使用标识符时出现 ANTLR4 错误,但在使用文本时出现错误



测试以下简单语法。

grammar SQL;
selectStatement: SELECT selectElements EOF;
selectElements: (star='*' | ID ) (',' ID)*;
ID: ID_LITERAL;
WS: [ trn]+ -> 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>

虽然在selectStatementSELECT标识符更改为内联文本会导致以下语法,这将分析相同的输入而不会出错。为什么?

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

模式[A-Z_$0-9]*? [A-Z_$]+? [A-Z_$0-9]*'SELECT'都匹配在输入SELECT *上,并且它们都产生相同长度的匹配(即它们都匹配SELECT然后*作为输入的其余部分(。在这种情况下,ANTLR(像大多数词法生成器一样(应用语法中首先出现的规则。在你的第一个语法中,这是ID.所以SELECT *被表述为ID, WS, '*',而不是SELECT, WS, '*'

如果将规则移动到ID定义之前SELECT: 'SELECT';,它将按预期工作。

最新更新