Parsing 在ANTLR4中使用什么来解决更复杂情况下的歧义(而不是语法谓词)?
在ANTLRv3中,可以使用语法谓词来解决歧义,即显式地告诉ANTLR应该选择哪个替代方案。ANTLR4似乎只是接受具有类似歧义的语法,但在解析过程中它会报告这些歧义。它产生了一个解析树,尽管存在这些歧义(根据文档,通过选择第一个备选方案)。但如果我想让它选择其他的选择,我能做什么呢?换句话说,我如何明确地解决歧义 (有关悬挂else问题的简单情况,请参见:) 一个更复杂的例子: 如果我有这样的规则:Parsing 在ANTLR4中使用什么来解决更复杂情况下的歧义(而不是语法谓词)?,parsing,antlr,antlr4,Parsing,Antlr,Antlr4,在ANTLRv3中,可以使用语法谓词来解决歧义,即显式地告诉ANTLR应该选择哪个替代方案。ANTLR4似乎只是接受具有类似歧义的语法,但在解析过程中它会报告这些歧义。它产生了一个解析树,尽管存在这些歧义(根据文档,通过选择第一个备选方案)。但如果我想让它选择其他的选择,我能做什么呢?换句话说,我如何明确地解决歧义 (有关悬挂else问题的简单情况,请参见:) 一个更复杂的例子: 如果我有这样的规则: expr : expr '[' expr? ']' | ID expr
expr
: expr '[' expr? ']'
| ID expr
| '[' expr ']'
| ID
| INT
;
这将把foo[4]
解析为(expr foo(expr[(expr 4)])
。但我可能想将其解析为(expr(expr foo)[(expr 4)])
。(也就是说,如果可能的话,总是选择第一个备选方案。它是第一个备选方案,因此根据文档,它应该具有更高的优先级。那么它为什么要构建这棵树呢?)
如果我理解正确,我有两种解决方案:
expr
替换为e
:
e : expr | pe
;
expr
: expr '[' expr? ']'
| ID expr
| ID
| INT
;
pe : '[' expr ']'
;
尽管语法变得更加复杂,但这似乎奏效了
我可能误解了一些事情,但这两种解决方案似乎都不如语法谓词那么优雅和复杂。尽管如此,我还是喜欢使用
??操作符解决悬空else问题。但我不知道在这种情况下如何使用。有可能吗?您可以通过将ID
选项置于ID expr
上方来解决此问题。当消除左递归时,所有非左递归的备选方案都会在左递归的备选方案之前进行解析
对于您的示例,第一个非左递归替代项ID expr
与整个表达式匹配,因此之后没有任何内容可供解析。要获取此表达式(expr(expr foo)[(expr 4)],可以使用
顶部:expr-EOF
expr:expr'['expr?']| ID | INT
我更新了您的示例,使用运算符[
和]
而不是(
和)
,以使读者清楚地了解以LISP语法打印示例时的格式。我尝试将ID置于ID expr之上。不幸的是,这并不能解决问题,我仍然得到相同的树。