语法中的二义性调用表达式

语法中的二义性调用表达式

本文介绍了ANTLR4 语法中的二义性调用表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的语法(用于演示)

I have a simple grammar (for demonstration)

grammar Test;


program
    :   expression* EOF
    ;


expression
    :   Identifier
    |   expression '(' expression? ')'
    |   '(' expression ')'
    ;


Identifier
    :   [a-zA-Z_] [a-zA-Z_0-9?]*
    ;

WS
    :   [ \r\t\n]+ -> channel(HIDDEN)
    ;

显然,expression 规则中的第二个和第三个选项是不明确的.我想通过仅当表达式紧跟后跟'('.

Obviously the second and third alternatives in the expression rule are ambiguous. I want to resolve this ambiguity by permitting the second alternative only if an expression is immediately followed by a '('.

所以下面

bar(foo)

应该匹配第二个选项而

bar
(foo)

应该匹配第 1 个和第 3 个选项(即使它们之间的令牌在 HIDDEN 通道中).

should match the 1st and 3rd alternatives (even if the token between them is in the HIDDEN channel).

我该怎么做?我已经看到调用表达式和括号表达式之间的这些歧义,存在于没有(或有可选)表达式终止符标记(或规则)的语言中 - 示例

How can I do that? I have seen these ambiguities, between call expressions and parenthesized expressions, present in languages that have no (or have optional) expression terminator tokens (or rules) - example

推荐答案

解决方案是在您的第二个选择中临时取消隐藏"空白.查看这个问题,了解如何做到这一点.

The solution to this is to temporary "unhide" whitespace in your second alternative. Have a look at this question for how this can be done.

使用该解决方案,您的代码可能看起来像这样

With that solution your code could look somthing like this

expression
    :   Identifier
    |   {enableWS();} expression '(' {disableWS();} expression? ')'
    |   '(' expression ')'
    ;

这样,第二个选项匹配输入的 WS-sensitive,因此只有在标识符直接跟在括号之后才会匹配.

That way the second alternative matches the input WS-sensitive and will therefore only be matched if the identifier is directly followed by the bracket.

请参阅此处 用于实现链接问题中提到的 MultiChannelTokenStream.

See here for the implementation of the MultiChannelTokenStream that is mentioned in the linked question.

这篇关于ANTLR4 语法中的二义性调用表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 12:50