在LALR(1)語法分析器中,語法中的規則被轉換爲一個分析表,它有效地表示「如果你有這個輸入,並且前瞻記號是X,那麼轉移到狀態Y或者按規則減少R」。yacc/bison LALR(1)算法如何處理「空」規則?
我已經成功構建瞭解釋語言(ruby)中的LALR(1)解析器,不使用生成器,但在運行時計算解析表並使用該解析表評估輸入。這種方式出人意料地出色,表格生成相當簡單(這讓我感到很吃驚),支持自我引用規則和左/右關聯。
但是,我有一點難以理解的是yacc/bison在概念上如何處理空白規則定義。我的解析器無法處理它們,因爲在生成表格時,它會遞歸地查看每個規則中的每個符號,而「空白」不是來自詞法分析器的東西,也不會被規則所減少。那麼,LALR(1)解析器如何處理空的規則呢?他們是專門對待它,還是一個有效的算法應該適用的「自然」概念,甚至不需要特別意識到這樣的概念?
比方說,一個規則可以與任何中間匹配任意數量成對的括號:
expr: /* empty */
| '(' expr ')'
;
輸入類似下面將匹配這條規則:
((((()))))
這意味着在閱讀'('和'看')',在分析器選擇:解析器選擇:
- 移動')'(不可能)
- 根據一些規則(不可能)
- 別的東西減少輸入...
不太適合「移」或「減少」的核心算法。解析器實際上不需要將任何東西移到堆棧上,將「無」減少到expr
,然後移動下一個標記')'
,給出'(' expr ')'
,當然這減少到expr
,依此類推。
這是「沒有任何變化」,令我困惑。分析表如何傳達這樣的概念?還要考慮到應該可以調用一些語義操作,該操作返回值爲$$
以減少空值,因此,從分析表跳過該操作並且在堆棧中指示'('
和')'
處於前瞻狀態的相當簡單的視圖應該是隻是簡單地轉換爲轉換,不會真正產生序列'(' expr ')'
,但只會產生序列'(' ')'
。
我確信[龍書](http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools)中有關於處理這些規則的部分很長。我不認爲Stack Overflow是討論它的正確場所 - 也許是程序員? –
感謝您對本書的建議......現在查看該鏈接。 Stackoverflow似乎是對我來說合適的地方。這是關於算法的直接問題,而不是主觀討論。有人可以很好地尋找這個,如果有人知道答案,快速解決。 – d11wtq
我想我其實只是想到了這一點,當一個基本點出現在我身上時,它是如此明顯而直截了當。將回答問題,因爲谷歌搜索什麼都沒有,這是一個相當自然的問題;) – d11wtq