補上了之前沒實作的 `syntax :: [Token] -> CoreProgram` ：

```
syntax :: [Token] -> CoreProgram
syntax = take_first_program . pProgram
         where
           take_first_program ((prog, []) : others) = prog
           take_first_program (parse      : others) = take_first_program others
           take_first_program others                = error $ "Syntax error: " ++ (show others)
```

翻成白話是：

  * 如果現在看到的是一個 parse 完成的 program ，那就是它了！
  * 如果現在看的沒 parse 完，那就看下一個，
  * 如果看到最後都沒找到 parse 完的，就報錯。

`pProgram` 只要用已經建立好的 parsers ，就能按書上第 18 頁的 BNF syntax 做出來。但要注意，該濾掉的關鍵字得濾乾淨，不然連簡單的 `f = x` 都 parse 不出來。

昨天自己亂做，馬上撞到 left recursion ，也就是：

```
pExpr = pThan EAp pExpr pAexpr
```

造成 `pExpr` 自己呼叫自己，停不下來的慘劇。

建議的解法是改成：

```
(pOneOrMore pAexpr) `pApply` mk_ap_chain
```

雖然 `pOneOrMore` 保證回來的陣列至少會有一個元素，但得在 `mk_ap_chain` 裡寫下 `error "Syntax error"` 還是覺得不舒服 XD

```
mk_ap_chain :: [CoreExpr] -> CoreExpr
mk_ap_chain [] = error "Syntax error: EAp"
mk_ap_chain (x:[]) = x
mk_ap_chain (x:y:xs) = mk_ap_chain (EAp x y : xs)
```

明天要處理 infix operators 。然後第二章講的是 template interpreter ，第三章才是我一直想了解的 G-machine 。

長路漫漫～
