ANTLR Lexer规则似乎只能作为解析器规则的一部分,而不是另一个lexer规则的一部分

时间:2020-05-27 17:50:42

标签: antlr antlr4

如果我具有以下语法来分析由空格分隔的整数列表:

grammar TEST;

test
    : expression* EOF
    ;

expression
    : integerLiteral
    ;

integerLiteral
    : INTLITERAL
    ;

PLUS: '+';
MINUS: '-';

DIGIT: '0'..'9';
DIGITS: DIGIT+;
INTLITERAL: (PLUS|MINUS)? DIGITS;

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

它不起作用!如果我通过“ 100”,我将得到:

line 1:0 extraneous input '100' expecting {<EOF>, INTLITERAL}

但是,如果删除词法分析器INTLITERAL规则,并将其放在解析器规则integerLiteral之下,就像这样

integerLiteral
    : (PLUS|MINUS)? DIGITS
    ;

现在看来一切正常!

我认为,如果我能够理解为什么会这样,那么我将开始理解我所遇到的一些特质。

1 个答案:

答案 0 :(得分:3)

词法分析器以以下方式创建令牌:

  1. 尝试为单个令牌匹配尽可能多的字符
  2. 如果两个标记匹配相同的字符,则让第一个定义为“获胜”

鉴于上述2条规则的信息,您将看到自己的规则:

DIGITS: DIGIT+;
INTLITERAL: (PLUS|MINUS)? DIGITS;

是问题所在。对于输入100,将创建一个DIGITS令牌:规则2在这里适用:两个规则都与100匹配,但是由于DIGITS是在INTLITERAL之前定义的,因此{ {1}}令牌已创建。

解决方案1 ​​

DIGITS移到INTLITERAL上方:

DIGITS

但是现在请注意,INTLITERAL: (PLUS|MINUS)? DIGITS; DIGIT: '0'..'9'; DIGITS: DIGIT+; DIGIT永远不会单独成为令牌,因为DIGITS将始终首先匹配。在这种情况下,您可以同时创建这两个规则INTLITERAL,然后再放置它们也没关系,因为fragment规则仅在其他词法分析器规则中使用(在解析器规则中不使用)< / p>

解决方案2

制作fragmentDIGIT片段

DIGITS

解决方案3

或者更好的是,不要将运算符粘贴在fragment DIGIT: '0'..'9'; fragment DIGITS: DIGIT+; INTLITERAL: (PLUS|MINUS)? DIGITS; 上,而是将其与一元表达式匹配:

INTLITERAL
相关问题