寫 compiler 學 Forth 之 lexeme 篇

最近很熱忱寫 Forth 的 compiler ,用到 Erlang 語言。而目前寫的進度是在寫詞彙分析。大致底定的成品如此頁所示: https://github.com/YauHsien/erl4th/blob/master/src/forth_lexical.erl

寫程式的進度很慢,每天都想一點、想一點。最後才知道自己能分清楚什麼叫做詞彙,而其他什麼不是詞彙而是語法,而又哪些不是詞彙而是語意。最後仔細釐清的,是 integer 與 float 格式的差異。

Forth 程式語言,詞彙分為 integer, float, word, delimiter ,而彼此之間的結構差異,包括:

  1. float 格式包含了二段 integer 格式。
  2. word 可能參雜 integer, float 或 delimiter 的格式。
  3. delimiter 也可以是 word ,但這比較接近語法分析才處理的事情。

所以剛開始,詞彙分析的任務,就是將詞彙正確地切取出來,並且加上一個大概正確的詞性。

至於程式的方法,以前學過的 parsers & parser combinators 文章所舉的例子,較是以 BNF 定義出來的句子與詞彙為主體,不過,我的辦法是把主體帶到比較細緻的解析度,即以每一個字母或字元為主體,例如在輸入資料中,目前遇到字元是一個「點」,就考慮這個點在哪些情況,應該如何導向詞彙的蒐集與詞性的累積。因此,發現了有一些情況需要考慮二個字元,例如字串的開始符號「 ." 」,也發現了除了用空格分隔二個詞彙之外,還需要另一種分隔的考量,能夠分隔一些子結構,例如 float 中是以「 E 」分隔底數與指數。

完成詞彙分段之後,我做一點點計算,將 integer 與 float 的值求出來。在這方面,我了解到程式語言的語法,並不一定表達我們認知的語意。我參考了 GForth 文件所提的 Number Conversion – https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Number-Conversion.html ,並且用 Win32Forth 執行幾個 integer 與 float 數字,於是找出幾個事實:

  1. integer 可以沒有負號或有負號, float 可以有正號或有負號、或者沒有。
  2. integer 可以有一個「點」,點除了不能開頭之外,放在什麼位置都可以。
  3. float 底數部分與指數部分,用 E 或 e 分隔。
  4. float 底數部分格式跟 integer 一模一樣。
  5. flot 指數部分跟 integer 不一樣,不能有「點」在其中。
  6. 帶有「點」的 integer ,「點」沒有意義;移除「點」之後的數字就是那個 integer 的整數值。
  7. float 的底數部分,「點」的意義是分位點,所以帶有「點」的底數,基本已經是個浮點數,之後再由指數部分決定如何移動分位點。
廣告

About 黃耀賢 (Yau-Hsien Huang)

熱愛 Erlang ,並且有相關工作經驗。喜歡程式語言。喜歡邏輯。目前用 Python 工作。
本篇發表於 Programming 並標籤為 , 。將永久鏈結加入書籤。