我该如何告诉ANTLR更喜欢另一种替代方案?
我有以下产品:我该如何告诉ANTLR更喜欢另一种替代方案?
expression
: primary # stubLabel
| expression '.' Identifier # stubLabel
| expression '.' 'this' # stubLabel
| expression '.' 'new' nonWildcardTypeArguments? innerCreator # stubLabel
| expression '.' 'super' superSuffix # stubLabel
| expression '.' explicitGenericInvocation # stubLabel
| expression '[' expression ']' # stubLabel
| Identifier arguments # namedMethodInvocation
| expression '.' Identifier arguments # namedMethodInvocation
| expression arguments # unnamedMethodInvocation
| // Lots of other patterns...
;
我愿解析器首先尝试unnamedMethodInvocation
之前尝试namedMethodInvocation
模式。这不会自动发生,因为ANTLR会尝试选择最长匹配的备选项,而不是使用第一个匹配策略。我如何强迫它做到这一点?
编辑:对不起,我忽略发布链接到上面的语法文件。 Here是。
尝试移动namedMethodInvocation
至primary
生产规则(之前Identifier
)这样。
primary
: '(' expression ')'
| 'this'
| 'super'
| literal
| Identifier arguments // namedMethodInvocation
| Identifier
| typeType '.' 'class'
| 'void' '.' 'class'
| nonWildcardTypeArguments (explicitGenericInvocationSuffix | 'this' arguments)
;
或者在expression
移动primary
到最后。或者插入新规则primaryOrNamedMethodInvocation
。
expression
: primaryOrNamedMethodInvocation
| expression '.' Identifier
.....
;
primaryOrNamedMethodInvocation
: Identifier arguments // namedMethodInvocation
| primary
;
saka1029,我不想这样做,因为'namedMethodInvocation'是没有意义的。 ''nameMethodInvocation'应该匹配一个像'foo.bar()'这样的表达式,这太复杂了,无法成为主要的。 –
增加了另一种解决方案。 – saka1029
saka1029,我不认为这会影响结果,因为ANTLR根据它的时间长度来选择替代方案,而不是它在生产中的顺序。 –
请发布'主要'生产规则。 – saka1029
@ saka1029我很抱歉,我忽略了链接到我的文章中的完整语法文件!语法文件可以在这里找到(https://github.com/antlr/grammars-v4/blob/master/java/Java.g4#L540)。 “主要”生产规则是[here](https://github.com/antlr/grammars-v4/blob/master/java/Java.g4#L540)。 –
在语法分析器规则中,从一个接一个,从上到下地排列(如语法中所写)并且第一个匹配的成功。订单本身就是一个问题,因为它决定了很多事情(例如优先级)。 –