grammar Hello;
prog: stat+ EOF;
stat: expr NEWLINE # printExpr
| ID '=' expr NEWLINE # assign
| NEWLINE # blank
| STRING NEWLINE # string
;
expr: expr (MUL|DIV) expr # opExpr
| expr (ADD|SUB) expr # opExpr
| expr AND expr # andExpr
| INT # int
| ID # id
| '(' expr ')' # parens
;
MUL: '*';
DIV: '/';
ADD: '+';
SUB: '-';
ID: [a-zA-Z]+[0-9a-zA-Z]*;
NEWLINE : [\r\n] ;
INT : [0-9]+ ;
AND : '&';
WS : [ \t\r\n]+ -> skip;
CM : '//' ~[\r\n]* -> skip;`
有人可以向我解释我的代码有什么问题吗?这是我的错误:
我们将非常感谢您的帮助!
答案 0 :(得分:2)
问题在于这些词法规则:
NEWLINE : [\r\n] ;
WS : [ \t\r\n]+ -> skip;
当词法分析器在输入字符串中找到\r\n
时,它会尝试匹配规则,并且两者都匹配。但是,WS
将匹配整个\r\n
,生成一个WS
令牌,而NEWLINE
将匹配\r
然后\n
,产生两个NEWLINE
1}}令牌。
在这种情况下,Antlr总是选择最长的匹配,在您的情况下,它将生成WS
。如果查看a = 3\r\nx = 4\r\n
的词法分析器输出,生成的标记将为:
ID WS '=' WS INT WS ID WS '=' WS INT WS
a = 3 \r\n x = 4 \r\n
但你要找的是:
ID WS '=' WS INT NEWLINE ID WS '=' WS INT NEWLINE
a = 3 \r\n x = 4 \r\n
您的语法似乎写得完全期望所有换行符生成NEWLINE
令牌,因此我建议将WS
规则更改为:
WS: [ \t]+ -> skip;