我正在嘗試從頭開始創建一種簡單的編程語言(解釋器),但我想知道為什么我應該使用詞法分析器。對我來說,創建一個直接決議代碼的決議器似乎會更容易。我在看什么?
uj5u.com熱心網友回復:
我想你會同意大多數語言(可能包括你正在實作的語言)都有概念標記:
- 運算子,例如 *(通常是乘法)、'('、')'、;
- 關鍵字,例如“IF”、“GOTO”
- 識別符號,例如 FOO、count、...
- 數字,例如 0、-527.23E-41
- 注釋,例如,/* 此文本在您的檔案中被忽略 */
- 空白,例如,被忽略的空白序列、制表符和換行符
實際上,需要一段特定的代碼來掃描/收集構成每個單獨令牌的字符。您的語言擁有的每種型別的標記都需要這樣的代碼塊。
如果您撰寫一個沒有詞法分析器的決議器,那么在您的決議器試圖決定接下來會發生什么的每一點上,您都必須擁有所有代碼來識別可能在決議中出現的標記。在下一個決議器點,您將需要所有代碼來識別那里可能存在的標記。這會給您帶來大量的代碼重復;您希望在決議器中出現多少次空白代碼?
如果您認為這不是一個好方法,那么明顯的解決方法是洗掉所有重復項:將每個標記的代碼放在該標記的子例程中,并在每個決議器位置呼叫標記的子例程。此時,從某種意義上說,您已經有了一個詞法分析器:用于識別標記的隔離代碼集合。 您可以通過這種方式撰寫完美的遞回下降決議器。
接下來您會發現,您在每個決議器點為許多標記呼叫標記子例程。即使這樣似乎也需要大量的作業和重復。因此,將所有呼叫替換為單個“GetNextToken”呼叫,該呼叫本身呼叫所有令牌的令牌識別代碼,并回傳一個標識遇到的特定令牌的列舉。現在您的決議器開始看起來合理:在每個決議器點,它對 GetNextToken 進行一次呼叫,然后在回傳的列舉上進行分支。這基本上是人們作為“詞法分析器”標準化的介面。
您會發現一件事是令牌詞法分析器有時會遇到重疊問題。關鍵字和識別符號通常有這個麻煩。實際上,將所有令牌識別器合并到一個有限狀態機中更容易,這樣可以更容易地區分令牌。在處理編程語言源文本時,這也證明是非常快的。您的玩具語言可能永遠不會決議超過 100 行代碼,但真正的編譯器每天要處理數百萬行代碼,并且大部分時間都花在了標記識別(“詞法分析”)上,尤其是。空白抑制。
您可以手動撰寫此狀態機。這并不難,但相當乏味。或者,您可以使用 FLEX 之類的工具為您完成此操作,這只是為了方便。隨著您的語言中不同種類的標記數量的增加,FLEX 解決方案變得越來越有吸引力。
TLDR:如果您使用詞法分析器,您的決議器更容易撰寫,體積也更小。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/407374.html
標籤:
上一篇:對于沒有陳述句終止符的語言,更喜歡在決議器中轉換而不是減少
下一篇:為什么說選擇排序有O(n)交換?
