使用标识符但不使用文字时出现ANTLR4错误

时间:2018-09-28 16:54:43

标签: antlr antlr4

测试以下简单语法。

grammar SQL;
selectStatement: SELECT selectElements EOF;
selectElements: (star='*' | ID ) (',' ID)*;
ID: ID_LITERAL;
WS: [ \t\r\n]+ -> channel(HIDDEN);
fragment ID_LITERAL: [A-Z_$0-9]*? [A-Z_$]+? [A-Z_$0-9]*;
SELECT: 'SELECT';

给出输入SELECT *会产生以下错误:

line 1:0 missing 'SELECT' at 'SELECT'
line 1:7 extraneous input '*' expecting <EOF>

SELECT中将selectStatement标识符更改为内联文字时,将产生以下语法,该语法将解析相同的输入而不会出错。为什么?

grammar SQL;
selectStatement: 'SELECT' selectElements EOF;
selectElements: (star='*' | ID ) (',' ID)*;
ID: ID_LITERAL;
WS: [ \t\r\n]+ -> channel(HIDDEN);
fragment ID_LITERAL: [A-Z_$0-9]*? [A-Z_$]+? [A-Z_$0-9]*;

1 个答案:

答案 0 :(得分:0)

模式[A-Z_$0-9]*? [A-Z_$]+? [A-Z_$0-9]*'SELECT'在输入SELECT *上都匹配,并且它们都产生相同长度的匹配(即,它们都匹配SELECT,然后离开{ {1}}作为其余输入)。在这种情况下,ANTLR(像大多数词法生成器一样)将应用语法中的第一条规则。在您的第一个语法中,*。因此ID的词法是SELECT *,而不是ID, WS, '*'

如果将规则SELECT, WS, '*'移到SELECT: 'SELECT';的定义之前,它将按您的意愿运行。