2010-08-24 143 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