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

查看:29
本文介绍了在 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?

(对于悬空 else 问题的简单情况,请参阅:在 ANTLR4 中使用什么来解决歧义(而不是句法谓词)?)

(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:

For example, replace expr with e:

e   :   expr | pe
    ;

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

pe  :   '[' expr ']'
    ;

这似乎有效,尽管语法变得更加复杂.

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

我可能误解了一些东西,但是这两种解决方案似乎都没有语法谓词那么优雅和复杂.虽然,我喜欢 ?? 运算符的悬空 else 问题的解决方案.但我不确定在这种情况下如何使用.可能吗?

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天全站免登陆