在ANTLR v3中,句法谓词可用于解决ambiguitites,即明确告诉ANTLR应选择哪种替代方案。 ANTLR4似乎只接受具有类似歧义的语法,但在解析过程中它会报告这些歧义。它产生了一个解析树,尽管有这些含糊之处(根据文档,通过选择第一个替代方案)。但是,如果我想让它选择其他替代方案,我该怎么办?换句话说,我该如何明确地解决歧义?
(对于悬挂其他问题的简单案例,请参阅:What to use in ANTLR4 to resolve ambiguities (instead of syntactic predicates)?)
一个更复杂的例子:
如果我有这样的规则:
expr
: expr '[' expr? ']'
| ID expr
| '[' expr ']'
| ID
| INT
;
这会将foo[4]
解析为(expr foo (expr [ (expr 4) ]))
。但我可能想将其解析为(expr (expr foo) [ (expr 4) ])
。 (例如,如果可能的话,总是采取第一种选择。这是第一种选择,因此根据文档,它应该具有更高的优先级。那么为什么要构建这个树?)
如果我理解正确,我有2个解决方案:
基本上用语义谓词实现语法谓词(但是,在这种情况下,我不确定如何)。
重组语法。
例如,将expr
替换为e
:
e : expr | pe
;
expr
: expr '[' expr? ']'
| ID expr
| ID
| INT
;
pe : '[' expr ']'
;
这似乎有效,尽管语法变得更加复杂。
我可能误解了一些事情,但这两种解决方案似乎都不如句法谓词更优雅,更复杂。虽然,我喜欢??
运算符悬挂其他问题的解决方案。但我不确定如何在这种情况下使用。有可能吗?
答案 0 :(得分:0)
您可以通过将ID
替代方案置于ID expr
之上来解决此问题。当删除左递归时,所有未递归的替代方法都会在您的替代方案之前进行解析。
对于您的示例,第一个非左递归替代ID expr
匹配整个表达式,因此之后没有任何内容可以解析。
答案 1 :(得分:0)
要获取此表达式(expr(expr foo)[(expr 4)]),可以使用
top:expr EOF;
expr:expr'['expr? ']'| ID | INT;