ANTLR如何决定应用哪个词法分析器规则?最长的匹配词法分析器规则获胜?

smw*_*dia 1 compiler-construction antlr lexer antlr4

输入内容:

在此输入图像描述

语法:

grammar test;

p : EOF;

Char : [a-z];

fragment Tab : '\t';
fragment Space : ' ';
T1 : (Tab|Space)+ ->skip;

T2 : '#' T1+ Char+;
Run Code Online (Sandbox Code Playgroud)

匹配结果如下:

[@0,0:6='#   abc',<T2>,1:0]    <<<<<<<< PLACE 1
[@1,7:6='<EOF>',<EOF>,1:7]
line 1:0 extraneous input '#   abc' expecting <EOF>
Run Code Online (Sandbox Code Playgroud)

请忽略最后一行中的错误.我想知道为什么在PLACE 1匹配的令牌是T2.

在语法文件中,T2词法规则去T1词法规则.所以我希望T1首先应用规则.那么为什么# abc不跳过空格呢?

ANTLR是否使用一些贪婪策略来匹配当前字符流和最长的词法分析器规则?

Tom*_*rvo 5

按以下顺序适用三条规则:

  1. 最长的比赛首先获胜.
  2. #接下来,规则匹配隐式标记(就像在你的语法中).
  3. 最后,在平局(通过匹配长度)的情况下,匹配规则中最早列出的规则获胜.

经过大量的凌晨搜索,我在Sam Harwell的一篇冗长的引文中再次找到了大部分这些材料,其中他还阐述了贪婪的操作员的影响.我记得第一次看到它并在我的TDAR副本中勾画笔记,但没有参考.

ANTLR 4词法分析器通常以最长匹配获胜行为运行,而不考虑备选在语法中出现的顺序.如果两个词法分析器规则匹配相同的最长输入序列,则只有这些规则的相对顺序进行比较才能确定如何分配令牌类型.

一旦词法分析器到达非贪婪的可选或闭包,规则内的行为就会发生变化.从该时刻到规则结束,该规则中的所有备选方案都将被视为有序,而具有最低备选方案的路径将获胜.这种看似奇怪的行为实际上是由于我们在底层ATN表示中订购替代方式而导致的非贪婪处理.当词法分析器处于此模式并到达块(ESC |.)时,排序约束要求它尽可能使用ESC.

"隐式令牌"规则来自此处.