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".
我是 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".