使用标识符时出现 ANTLR4 错误,但使用文字时不会出现 ANTLR4 错误
ANTLR4 error when using identifier but not when using literal
正在测试以下简单语法。
grammar SQL;
selectStatement: SELECT selectElements EOF;
selectElements: (star='*' | ID ) (',' ID)*;
ID: ID_LITERAL;
WS: [ \t\r\n]+ -> channel(HIDDEN);
fragment ID_LITERAL: [A-Z_[=10=]-9]*? [A-Z_$]+? [A-Z_[=10=]-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_[=12=]-9]*? [A-Z_$]+? [A-Z_[=12=]-9]*;
模式 [A-Z_[=10=]-9]*? [A-Z_$]+? [A-Z_[=10=]-9]*
和 'SELECT'
都匹配输入 SELECT *
并且它们都产生相同长度的匹配(即它们都匹配 SELECT
然后留下 *
作为输入的其余部分)。在这种情况下,ANTLR(像大多数词法分析器生成器一样)应用语法中最先出现的规则。在你的第一个语法中是 ID
。所以 SELECT *
被词法化为 ID, WS, '*'
,而不是 SELECT, WS, '*'
.
如果您将规则 SELECT: 'SELECT';
移到 ID
的定义之前,它将按您希望的方式工作。
正在测试以下简单语法。
grammar SQL;
selectStatement: SELECT selectElements EOF;
selectElements: (star='*' | ID ) (',' ID)*;
ID: ID_LITERAL;
WS: [ \t\r\n]+ -> channel(HIDDEN);
fragment ID_LITERAL: [A-Z_[=10=]-9]*? [A-Z_$]+? [A-Z_[=10=]-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_[=12=]-9]*? [A-Z_$]+? [A-Z_[=12=]-9]*;
模式 [A-Z_[=10=]-9]*? [A-Z_$]+? [A-Z_[=10=]-9]*
和 'SELECT'
都匹配输入 SELECT *
并且它们都产生相同长度的匹配(即它们都匹配 SELECT
然后留下 *
作为输入的其余部分)。在这种情况下,ANTLR(像大多数词法分析器生成器一样)应用语法中最先出现的规则。在你的第一个语法中是 ID
。所以 SELECT *
被词法化为 ID, WS, '*'
,而不是 SELECT, WS, '*'
.
如果您将规则 SELECT: 'SELECT';
移到 ID
的定义之前,它将按您希望的方式工作。