在更复杂的情况下(而不是句法谓词),可以在ANTLR4中使用什么来解决歧义? [英] What to use in ANTLR4 to resolve ambiguities in more complex cases (instead of syntactic predicates)?

查看:96
本文介绍了在更复杂的情况下(而不是句法谓词),可以在ANTLR4中使用什么来解决歧义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在ANTLR v3中,可以使用句法谓词来解决歧义,即明确告诉ANTLR应该选择哪种选择. ANTLR4似乎只是接受具有相似歧义的语法,但在解析过程中会报告这些歧义.尽管存在这些歧义,它仍会生成一个解析树(根据文档,选择第一个替代树).但是,如果我希望它选择其他替代方法,该怎么办?换句话说,我该如何明确解决歧义?

In ANTLR v3, syntactic predicates could be used to solve ambiguitites, i.e., to explicitly tell ANTLR which alternative should be chosen. ANTLR4 seems to simply accept grammars with similar ambiguities, but during parsing it reports these ambiguities. It produces a parse tree, despite these ambiguities (by chosing the first alternative, according to the documentation). But what can I do, if I want it to chose some other alternative? In other words, how can I explicitly resolve ambiguities?

(有关悬而未决的其他问题的简单案例,请参见:

(For the simple case of the dangling else problem see: 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) ]). (即,如果可能,请始终采用第一种选择.这是第一种选择,因此根据文档,它应具有更高的优先级.那么为什么要构建此树?)

This will parse foo[4] as (expr foo (expr [ (expr 4) ])). But I may want to parse it as (expr (expr foo) [ (expr 4) ]). (I. e., always take the first alternative if possible. It is the first alternative, so according to the documentation, it should have higher precedence. So why it builds this tree?)

如果我理解正确,我有两种解决方法:

If I understand correctly, I have 2 solutions:

  1. 基本上使用语义谓词来实现语法谓词(但是,在这种情况下,我不确定如何实现).

  1. Basically implement the syntactic predicate with a semantic predicate (however, I'm not sure how, in this case).

重构语法.

例如,将expr替换为e:

e   :   expr | pe
    ;

expr
    :   expr '[' expr? ']'
    |   ID expr
    |   ID
    |   INT
    ;

pe  :   '[' expr ']'
    ;

这似乎行得通,尽管语法变得更加复杂.

This seems to work, although the grammar became more complex.

我可能会误解一些事情,但是与语法谓词相比,这两种解决方案似乎都不太优雅,也更复杂.虽然,我喜欢使用??运算符解决悬而未决的问题的解决方案.但是我不确定在这种情况下如何使用.有可能吗?

I may misunderstood some things, but both of these solutions seem less elegant and more complicated than syntactic predicates. Although, I like the solution for the dangling else problem with the ?? operator. But I'm not sure how to use in this case. Is it possible?

推荐答案

您可以通过将ID替代项放在ID expr上方来解决此问题.当消除了左递归后,所有未左递归的替代方案都将在您左递归的替代方案之前进行解析.

You may be able to resolve this by placing the ID alternative above ID expr. When left-recursion is eliminated, all of your alternatives which are not left recursive are parsed before your alternatives which are left recursive.

对于您的示例,第一个非左递归替代项ID expr与整个表达式匹配,因此此后无需解析.

For your example, the first non-left-recursive alternative ID expr matches the entire expression, so there is nothing left to parse afterwards.

这篇关于在更复杂的情况下(而不是句法谓词),可以在ANTLR4中使用什么来解决歧义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆