antlr tokenizer以最后一个标记开头

时间:2014-08-03 21:59:16

标签: antlr4

我有以下语法:

grammar Aligner;

line
    :   emptyLine
    |   codeLine
    ;

emptyLine
    :   ( KW_EMPTY KW_LINE )?
        ( EOL | EOF )
    ;

codeLine
    :   KW_LINE COLON
        indent
        CODE
        ( EOL | EOF )
    ;

indent
    :   absolute_indent
    |   relative_indent
    ;

absolute_indent
    :   NUMBER
    ;

relative_indent
    :   sign NUMBER
    ;

sign
    :   PLUS
    |   MINUS
    ;

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

KW_EMPTY:               'empty';
KW_LINE:                'line';

NUMBER
    :   DIGIT+
    ;

EOL
    :   ('\n' | '\r\n')
    ;

SPACING
    :   LINE_WS -> skip
    ;

CODE
    :   (~('\n' | '\r'))+
    ;

fragment
DIGIT
    :   '0'..'9'
    ;

fragment   
LINE_WS
    :   ' '
    |   '\t'
    |   '\u000C'
    ;

当我尝试解析时 - empty line我收到错误:line 1:0 no viable alternative at input 'empty line'。当我调试正在进行的操作时,第一个令牌来自CODE类型并包含整行。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

ANTLR会尝试匹配最长的令牌。当两个词法分析器规则匹配给定长度的相同字符串时,语法中出现的第一个规则将获胜。

你的规则CODE基本上是一个包罗万象:它将匹配整行文本。所以这里ANTLR可以选择匹配empty line作为CODE类型的单个标记,并且由于没有其他规则可以生成长度为10的标记,CODE规则将消耗整行

您应该重写CODE规则,使其仅与代码的含义相匹配。现在它太宽泛了。