我有一个简单的语法(用于演示)
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
规则中的第二和第三个备选方案含糊不清。我想通过允许第二种替代方法来解决这种歧义,只有当'('
>紧跟>>时才允许第二种方式。
以下
bar(foo)
时,应匹配第二种选择
bar
(foo)
应与第1和第3个备选项匹配(即使它们之间的令牌位于HIDDEN通道中)。
我该怎么做?我已经看到调用表达式和带括号的表达式之间的这些含糊不清,存在于没有(或具有可选)表达式终止符(或规则)的语言中 - example
答案 0 :(得分:1)
解决这个问题的方法是临时"取消隐藏"你的第二种选择中的空白。看看this question如何做到这一点。
使用该解决方案,您的代码可能看起来像这样
expression
: Identifier
| {enableWS();} expression '(' {disableWS();} expression? ')'
| '(' expression ')'
;
这样第二种方法匹配输入WS敏感,因此只有在标识符后面跟着括号时才匹配。
有关链接问题中提到的MultiChannelTokenStream
的实施,请参阅here。