我有一個簡單的語法。實際上,我使用的語法更復雜,但這是解釋我的問題的最小子集。從遞歸下降的語法生成表達式
Expr ::= Value Suffix
| "(" Expr ")" Suffix
Suffix ::= "->" Expr
| "<-" Expr
| Expr
| epsilon
Value
匹配標識符,字符串,數字等等。 Suffix
規則可以消除左遞歸。這個匹配表達式,如:
a -> b (c -> (d) (e))
也就是說,在a
進入既b
和(c -> (d) (e))
結果的曲線圖,和c
進入d
和e
。我試圖爲這些表達式產生一個抽象語法樹,但是我遇到了困難,因爲所有的操作符都可以接受任何數量的操作數。我寧願將生成AST的邏輯保留在遞歸下降解析方法中,因爲它避免了必須複製提取表達式的邏輯。我目前的策略如下:
如果出現
Value
,請將其推送到輸出。如果
From
或To
出現:輸出的分離器。
獲取下一個
Expr
。創建一個
Link
節點。將第一組操作數從輸出中彈出到
Link
,直到出現分隔符。擦除發現的分隔符。
將第二組操作數彈入
Link
直到出現分隔符。將
Link
推送到輸出。
如果我通過運行這個不服從步驟2.3 – 2.7,我得到的價值和分離器的列表。對於上面,a -> b (c -> (d) (e))
引述表達,輸出應該是:
A sep_1 B sep_2 C sep_3 D E
運用To
規則將隨後產量:
A sep_1 B sep_2 (link from C to {D, E})
而且隨後:
(link from A to {B, (link from C to {D, E})})
重要的是要注意是否sep_2
(對界定第二個->
的左側操作數至關重要)不會出現,所以解析器認爲表達實際寫入:
a -> (b c -> (d) (e))
爲了我目前的策略來解決這個問題,我需要一種方法來產生相鄰表達式之間的分隔符,但前提是當前表達式是封閉在一個From
或To
表達括號。如果可能的話,我只是沒有看到它,答案應該很簡單。但是,如果有更好的方法去解決這個問題,那麼請讓我知道!
啊哈!你是對的。我會嘗試添加另一個生產規則。通常我不使用遞歸下降,因爲我不喜歡重構複雜的語法,所以這對我來說是一種學習體驗。 – 2010-09-24 15:24:49
全套!謝謝你的幫助。 – 2010-09-24 16:43:21