问题描述
我有一个简单的语法(用于演示)
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 语法中的二义性调用表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!