优先规则

几个词法分析器规则可以匹配相同的输入文本。在这种情况下,将选择令牌类型如下:

  • 首先,选择匹配最长输入的词法分析器规则
  • 如果文本与隐式定义的标记(如'{')匹配,请使用隐式规则
  • 如果多个词法分析器规则匹配相同的输入长度,请根据定义顺序选择一个

以下结合语法:

grammar LexerPriorityRulesExample;

// Parser rules

randomParserRule: 'foo'; // Implicitly declared token type
    
// Lexer rules
    
BAR: 'bar';
IDENTIFIER: [A-Za-z]+;
BAZ: 'baz';

WS: [ \t\r\n]+ -> skip;

鉴于以下输入:

aaa foo bar baz barz

将从词法分析器生成以下标记序列:

IDENTIFIER 'foo' BAR IDENTIFIER IDENTIFIER
  • aaa 的类型为 IDENTIFIER

    只有 IDENTIFIER 规则可以匹配此令牌,没有歧义。

  • foo 属于'foo'

    解析器规则 randomParserRule 引入了隐含的'foo'令牌类型,它在 IDENTIFIER 规则上是优先的。

  • barBAR 的类型

    此文本与 BAR 规则匹配,该规则在 IDENTIFIER 规则之前定义,因此具有优先权。

  • baz 的类型为 IDENTIFIER

    此文本符合 BAZ 规则,但它也符合 IDENTIFIER 规则。选择后者,因为它是 BAR 之前定义的。

    鉴于语法,BAZ 永远无法匹配,因为 IDENTIFIER 规则已经涵盖了 BAZ 可以匹配的所有内容。

  • barz 的类型为 IDENTIFIER

    BAR 规则可以匹配此字符串的前 3 个字符(bar),但 IDENTIFIER 规则将匹配 4 个字符。由于 IDENTIFIER 匹配较长的子字符串,因此选择 BAR

根据经验,应更通用的规则之前定义特定规则。如果规则只能匹配先前定义的规则已涵盖的输入,则永远不会使用它。

隐含定义的规则(如'foo')就好像它们是所有其他词法规则之前定义的一样