作为帮助我解释数字解释模糊性的Overlapping rules - mismatched input的后续工作,我现在遇到了下一个问题 - 数字也被允许作为标识符的一部分,不幸的是,即使在开始时标识符,所以......
这个语法说明了问题
grammar NOVIANum;
statement : (priorityT | integerT | levelT )* ;
priorityT : T_PRIO twoDigits ;
integerT : T_INTEGER integer ;
levelT : T_LEVEL levelNumber ;
levelNumber : ( ZERO (OneToFour | FiveToNine) | ( OneToFour (ZERO | (OneToFour | FiveToNine)) ) ) ;
integer: ZERO* ( (OneToFour | FiveToNine) ( (OneToFour | FiveToNine) | ZERO )* ) ;
twoDigits : (ZERO | (OneToFour | FiveToNine)) ( ZERO | (OneToFour | FiveToNine) ) ;
WS : [ \t\r\n]+ -> skip ;
T_INTEGER : 'INTEGER' ;
T_LEVEL : 'LEVEL' ;
T_PRIO : 'PRIO' ;
ZERO : '0' ;
OneToFour : [1-4] ;
FiveToNine : [5-9] ;
ID : Letter SeparatorAndLetter* ;
Letter : [a-zA-Z0-9];
SeparatorAndLetter : ([\-]* [_]* Letter+);
以下输入
INTEGER 350
PRIO 10
LEVEL 01
确实有足够的结果
line 1:8 mismatched input '350' expecting {'0', OneToFour, FiveToNine}
line 2:5 no viable alternative at input '10'
line 3:6 no viable alternative at input '01'
(statement (integerT INTEGER (integer 350)) (priorityT PRIO (twoDigits 10)) (levelT LEVEL (levelNumber 01)))
因为在解析" 350"。
时,ID将在整数之前启动有什么方法吗?
谢谢 - 亚历克斯
答案 0 :(得分:2)
使ID
成为解析器规则而不是词法分析器规则。如果一个ID可以只是数字,那么词法分析器就不可能将它分开,并且因为你的整数词法分析规则只匹配1位数,所以词法分析器总是支持ID
规则用于超过1位数的数字(词法分析器总是尝试匹配最长的输入序列。)
以下语法适用于您的示例输入:
grammar NOVIANum;
statement : (priorityT | integerT | levelT | idT)* ;
priorityT : T_PRIO twoDigits ;
integerT : T_INTEGER integer ;
levelT : T_LEVEL levelNumber ;
idT : T_ID id ;
levelNumber : LVLNUMBER ;
integer : LVLNUMBER | TWODIGITS | NONZERONR ;
twoDigits : LVLNUMBER | TWODIGITS ;
number : LVLNUMBER | TWODIGITS | NONZERONR | ANYNUMBER ;
id : number | STRING ;
WS : [ \t\r\n]+ -> skip ;
T_INTEGER : 'INTEGER' ;
T_LEVEL : 'LEVEL' ;
T_PRIO : 'PRIO' ;
T_ID : 'ID' ;
LVLNUMBER : ZERO (OneToFour | FiveToNine) | OneToFour (ZERO | OneToFour | FiveToNine) ;
TWODIGITS : ZERO ZERO | FiveToNine (ZERO | OneToFour | FiveToNine) ;
NONZERONR : ZERO* (OneToFour | FiveToNine) (ZERO | OneToFour | FiveToNine)* ;
ANYNUMBER : (ZERO | OneToFour | FiveToNine)+ ;
STRING : (LVLNUMBER | TWODIGITS | NONZERONR | ANYNUMBER | LETTER) (Minus* Underscore* (LVLNUMBER | TWODIGITS | NONZERONR | ANYNUMBER | LETTER)+)* ;
fragment LETTER : [a-zA-Z];
fragment Minus : '-' ;
fragment Underscore : '_' ;
fragment ZERO : '0' ;
fragment OneToFour : [1-4] ;
fragment FiveToNine : [5-9] ;
虽然这个语法正确地解析了您的示例输入,但如果您有许多不同的特殊数字,例如LVLNUMBER
或TWODIGITS
,则会非常笨拙。我希望在解析后用监听器验证这些值(例如,levelNumber <50)。