为什么这些模式在这个ANTLR生产中不匹配?
我正在使用ANTLR v4 Java语法(可用here)解析Java代码。其中生产的是这样的:为什么这些模式在这个ANTLR生产中不匹配?
expression
: primary
| expression '.' Identifier
| expression '.' 'this'
| expression '.' 'new' nonWildcardTypeArguments? innerCreator
| expression '.' 'super' superSuffix
| expression '.' explicitGenericInvocation
| expression '[' expression ']'
| expression arguments
| // Lots of other patterns...
;
expression '.' Identifier
一个简单的成员访问匹配,并且expression arguments
方法调用相匹配。您可以查看该制作的全部来源here。
出于语法高亮的目的,我想引入额外的冗余模式来检测我称之为的命名方法调用。 bar()
或foo.bar()
将作为命名方法调用计数,其中bar
是该方法的名称。对于这样的表达式,我想bar
被标记为绿色,即使标识符通常是白色的。但是,在foo.bar
或foo.bar[0]()
中,没有东西应该涂成绿色。前者bar
不调用方法,而后者bar[0]
不是有效的标识符。
我以前expression arguments
添加了这两个额外的模式(注:arguments
的代名词,在原始的源代码'(' expressionList? ')'
):
expression
: // ...
| expression '[' expression ']'
| Identifier arguments namedMethodInvocationStub // Detect bar()
| expression '.' Identifier arguments namedMethodInvocationStub // Detect (some().complicated().expression()).bar()
| expression arguments
| // ...
;
namedMethodInvocationStub
:
;
(在这里,namedMethodInvocationStub
是一个额外的虚拟生产我添加的想法是我可以覆盖VisitExpression
并检查最后一个孩子是否是namedMethodInvocationStub
如果是,那么我们已经匹配了一个命名的方法调用,所以请通过类型为Identifier
的所有直接子代并将它们着色为绿色。无论如何,这只是为了揭开什么秘密也就是说,它与下面的问题没有直接关系。)
我预计这个规则变化使foo.bar()
,它以前被解析为(expression '.' Identifier) arguments
,现在解析为expression '.' Identifier arguments namedMethodInvocationStub
。但是,它仍然像以前一样解析,无论我是否删除namedMethodInvocationStub
。为什么是这样?
我相信你无法比拟的空规则/令牌(namedMethodInvocationStub)在ANTLR(或任何其他词法分析器)
ANTLR: empty condition not working
What is the equivalent for epsilon in ANTLR BNF grammar notation?
你看到任何错误ANTLR代码中/警告生成阶段?
不过,它似乎在发生或者没有'namedMethodInvocationStub'。 –
我没有在您提供的位置找到模式“表达参数”https://github.com/antlr/grammars-v4/blob/master/java/Java.g4#L497-L538 –
对不起,我调整了代码有点让它更整洁。 'arguments'是另一个非终结符([here](https://github.com/antlr/grammars-v4/blob/master/java/Java.g4#L604-L606))与''('expressionList?'同义) “'。 –