ANTLR如何决定应用哪个词法分析规则?最长的匹配词法分析器规则获胜?
问题描述:
输入内容:ANTLR如何决定应用哪个词法分析规则?最长的匹配词法分析器规则获胜?
语法:
grammar test;
p : EOF;
Char : [a-z];
fragment Tab : '\t';
fragment Space : ' ';
T1 : (Tab|Space)+ ->skip;
T2 : '#' T1+ Char+;
匹配的结果是这样的:
[@0,0:6='# abc',<T2>,1:0] <<<<<<<< PLACE 1
[@1,7:6='<EOF>',<EOF>,1:7]
line 1:0 extraneous input '# abc' expecting <EOF>
请忽略最后一行的错误。我想知道为什么在PLACE 1匹配的标记为T2
。
在语法文件中,T2
词法分析规则变为后T1
词法分析规则。所以我预计T1
规则应该先申请。那么为什么# abc
中的空格没有被跳过?
ANTLR是否使用了一些贪婪策略来将当前字符流与最长的词法分析规则进行匹配?
答
三个规则,顺序如下:
- 最长的一场比赛的胜利第一。
- 规则匹配隐式标记(如文法中的
#
)接下来。 - 最后,在匹配的情况下(按匹配长度),匹配规则中最早列出的规则获胜。
在经过了大量的小时搜索之后,我再次从Sam Harwell的一篇冗长的引文中发现了大部分内容,他在其中还阐述了贪婪的操作员的影响。我记得第一次看到它,并在我的TDAR副本中勾勒出笔记,但没有提及。
ANTLR 4词法分析器通常以最长匹配获胜行为进行操作,而不考虑替代词在语法中出现的顺序。如果两个词法分析器规则匹配相同的最长输入序列,那么只有这些规则的相对顺序相比才能确定如何分配令牌类型。
只要词法分析器达到非贪婪可选或闭包,规则内的行为就会改变。从那时起,直到规则的结尾,该规则中的所有替代方案将按照有序方式处理,而替代方案的最低方式将胜出。这种看似奇怪的行为实际上是由于我们在潜在的ATN表示中订购替代品的方式而导致的非贪婪处理。当词法分析器处于此模式并到达块(ESC |。)时,排序约束要求在可能的情况下使用ESC。
“隐式令牌”规则是从here。
答
我认为这是因为ANTLR第一次在词法分析阶段看到#
字符,所以它会遵循T2
规则。幸运的是,T2
比赛。如果ANTLR先看到,则它将沿着
T1
规则行进。