2010-08-24 157 views
3

下面的ANTLR語法中的'expr'規則顯然是相互左遞歸的。作爲一名ANTLR新手,我很難解決這個問題。我讀過ANTLR參考書中的「解決非LL(*)衝突」,但我仍然沒有看到解決方案。任何指針?解決ANTLR相互左遞歸規則

 
LPAREN : ('(') ; 
RPAREN : (')'); 
AND : ('AND' | '&' | 'EN') ; 
OR : ('OR' | '|' | 'OF'); 
NOT : ('-' | 'NOT' | 'NIET'); 
WS : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;} ; 
WORD : (~(' ' | '\t' | '\r' | '\n' | '(' | ')' | '"'))*; 

input : expr EOF; 
expr : (andexpr | orexpr | notexpr | atom); 
andexpr : expr AND expr; 
orexpr : expr OR expr; 
notexpr : NOT expr; 
phrase : '"' WORD* '"'; 
atom : (phrase | WORD); 

回答

5

我建議看看antlr網站上的示例語法。 Java語法做你想要的。

Basicly你可以做這樣的事情:

expr : andexpr; 
andexpr : orexpr (AND andexpr)*; 
orexpr : notexpr (OR orexpr)*; 
notexpr : atom | NOT expr; 

最關鍵的是,每一個表情可以結束是一個原子。

+0

感謝您的回答。我對這個解決方案的問題是,解析樹看起來很奇怪:每個原子都有一個notexpr作爲父項,即使這不是真正的notexpr。也許LL(*)解析器不是這種解析的最佳解決方案? – 2010-08-24 12:22:04

+0

Theres沒有錯這種語法的LL解析器(使用這種表達式很常見)。如果你生成一個AST,你可以使用重寫規則來創建一個不包含「superflues」父母的AST。 – Arne 2010-08-24 13:55:40

+0

@Arne我在尋找解決原始海報同樣問題的解決方案時偶然發現了答案。我在代碼中發現了一個輕微的錯字:第一行應該讀取「expr:andexpr」而不是「expr:andexp」。我自己無法編輯它,因爲出於某些原因,出於某種原因要求我改變超過6個字符以便編輯被接受。你可以自己改變它,這樣像我這樣的不知道的複製粘貼將會遇到相同的編譯錯誤嗎? – phuibers 2012-08-14 07:19:11