Antlr - 不匹配的输入'1'期望数字

Antlr - mismatched input '1' expecting number

我是 Antlr 的新手,我有以下简化语言:

grammar Hello;

sentence : targetAttributeName EQUALS expression+ (IF relationedExpression (logicalRelation relationedExpression)*)?;         

expression : 
    '(' expression ')' |
    expression ('*'|'/') expression |
    expression ('+'|'-') expression |   
    function |
    targetAttributeName |
    NUMBER;

filterExpression :
    '(' filterExpression ')' |
    filterExpression ('*'|'/') filterExpression |
    filterExpression ('+'|'-') filterExpression |   
    function |
    filterAttributeName |
    NUMBER |
    DATE;

relationedExpression :
    filterExpression ('<'|'<='|'>'|'>='|'=') filterExpression |
    filterAttributeName '=' STRING |
    STRING '=' filterAttributeName
    ;

logicalRelation :
    'AND' |
    'OR'
    ;

targetAttributeName :
    'x'|
    'y'
;

filterAttributeName :
    'a' |
    'a' '1' |
    targetAttributeName;

function:
    simpleFunction |
    complexFunction ;

simpleFunction : 
    'simpleFunction' '(' expression ')' |
    'simpleFunction2' '(' expression ')'
    ;

complexFunction : 
    'complexFunction' '(' expression ')' |
    'complexFunction2' '(' expression ')'
;

EQUALS : '=';
IF : 'IF';

STRING : '"' [a-zA-z0-9]* '"';
NUMBER : [-]?[0-9]+('.'[0-9]+)?;
DATE: NUMBER NUMBER NUMBER NUMBER '.' NUMBER NUMBER? '.' NUMBER NUMBER? '.';
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines

它适用于 x = y * 2,但不适用于 x =y * 1

错误信息如下:

Hello::sentence:1:7: mismatched input '1' expecting {'simpleFunction', 'complexFunction', 'x', 'y', 'complexFunction2', '(', 'simpleFunction2', NUMBER}

这对我来说很奇怪,因为1是一个NUMBER...

如果我将 filterAttribute'a' '1' 更改为 'a1',那么它可以与 x=y*1 一起使用,但我不明白这两种情况之间的区别。有人可以为我解释一下吗?

谢谢。

通过这样做:

filterAttributeName :
    'a' |
    'a' '1' |
    targetAttributeName;

ANTLR 从这些内联标记创建词法分析器规则。所以你真的有一个看起来像这样的词法分析器语法:

T_1 : '1': // the rule name will probably be different though
T_a : 'a';
...
NUMBER : [-]?[0-9]+('.'[0-9]+)?;

换句话说,输入 1 将被标记为 T_1,而不是 NUMBER

编辑

每当某个输入可以匹配两个或多个词法分析器规则时,ANTLR 会选择第一个定义的规则。词法分析器不会 "listen" 到解析器以查看它在特定时间需要什么。词法分析和解析是两个不同的阶段。这就是 ANTLR 以及许多其他解析器生成器的工作原理。如果这对您来说不能接受,您应该 google for "scanner-less parsing",或 "packrat parsers".