不识别令牌
Not recognizing token
我最近将我的 SQL 解析器代码从 paraboiled 移到了 ANTLR,迁移非常顺利,但是当我的 SQL 包含 AND 或 OR 条件运算符时,我收到了这个错误消息。我正在分享示例语法,将不胜感激。
如果我尝试解析这个样本 sql "SELECT Name,Age,Salary FROM Employee WHERE Age=12 AND Dept=15"
我得到行 1:50 不匹配的输入 'AND' 期待 {, OPAND, OPOR}
但是,如果我用下面的规则替换它就可以了,我正在尝试实现不区分大小写的解析
binaryConditionalExp: binaryExp |
binaryConditionalExp CONDOPERATOR=('AND' | 'OR') binaryConditionalExp |
binaryparenExp;
/**
* Define a grammar called Hello
*/
grammar SQLParser;
@header
{
package somu.parsers;
}
prog : sqlsyntax; // match keyword hello followed by an identifier
sqlsyntax : (selectclause fromclause whereclause) | (selectclause fromclause ) ;
selectclause : 'SELECT' columnclause;
columnclause : columnName (',' columnName)*;
columnName : columnLiteral;
columnLiteral : ID | sqlsyntax;
fromclause : 'FROM' tableclause;
tableclause : (tableclausealiaswithas | tableclauseplainalias | tableclausenoalias);
tableclausenoalias : ID | ;
tableclausealiaswithas : ID 'as' ID;
tableclauseplainalias : ID ID;
whereclause : 'WHERE' binarystmt;
binarystmt : binaryConditionalExp;
binaryExp: columnName OPERATOR columnName;
binaryparenExp: '(' binaryConditionalExp ')';
binaryConditionalExp: binaryExp |
binaryConditionalExp CONDOPERATOR=(OPAND | OPOR) binaryConditionalExp |
binaryparenExp;
ID : [a-zA-Z0-9]+ ; // match identifiers
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
OPERATOR: [=><]+ ;
OPAND : A N D ;
OPOR : O R;
fragment DIGIT : [0-9];
fragment A : [aA];
fragment B : [bB];
fragment C : [cC];
fragment D : [dD];
fragment E : [eE];
fragment F : [fF];
fragment G : [gG];
fragment H : [hH];
fragment I : [iI];
fragment J : [jJ];
fragment K : [kK];
fragment L : [lL];
fragment M : [mM];
fragment N : [nN];
fragment O : [oO];
fragment P : [pP];
fragment Q : [qQ];
fragment R : [rR];
fragment S : [sS];
fragment T : [tT];
fragment U : [uU];
fragment V : [vV];
fragment W : [wW];
fragment X : [xX];
fragment Y : [yY];
fragment Z : [zZ];
由于规则的顺序,词法分析器将 AND 视为标识符,而不是关键字。如果将词法分析器规则部分更改为以下内容,字符串 "AND" 会正确标记为 OPAND.
// match RESERVED WORDS first
OPAND : A N D ;
OPOR : O R;
// match IDENTIFIERS etc.
ID : [a-zA-Z0-9]+ ;
WS : [ \t\r\n]+ -> skip ;
OPERATOR: [=><]+ ;
我最近将我的 SQL 解析器代码从 paraboiled 移到了 ANTLR,迁移非常顺利,但是当我的 SQL 包含 AND 或 OR 条件运算符时,我收到了这个错误消息。我正在分享示例语法,将不胜感激。
如果我尝试解析这个样本 sql "SELECT Name,Age,Salary FROM Employee WHERE Age=12 AND Dept=15"
我得到行 1:50 不匹配的输入 'AND' 期待 {, OPAND, OPOR}
但是,如果我用下面的规则替换它就可以了,我正在尝试实现不区分大小写的解析
binaryConditionalExp: binaryExp | binaryConditionalExp CONDOPERATOR=('AND' | 'OR') binaryConditionalExp | binaryparenExp;
/**
* Define a grammar called Hello
*/
grammar SQLParser;
@header
{
package somu.parsers;
}
prog : sqlsyntax; // match keyword hello followed by an identifier
sqlsyntax : (selectclause fromclause whereclause) | (selectclause fromclause ) ;
selectclause : 'SELECT' columnclause;
columnclause : columnName (',' columnName)*;
columnName : columnLiteral;
columnLiteral : ID | sqlsyntax;
fromclause : 'FROM' tableclause;
tableclause : (tableclausealiaswithas | tableclauseplainalias | tableclausenoalias);
tableclausenoalias : ID | ;
tableclausealiaswithas : ID 'as' ID;
tableclauseplainalias : ID ID;
whereclause : 'WHERE' binarystmt;
binarystmt : binaryConditionalExp;
binaryExp: columnName OPERATOR columnName;
binaryparenExp: '(' binaryConditionalExp ')';
binaryConditionalExp: binaryExp |
binaryConditionalExp CONDOPERATOR=(OPAND | OPOR) binaryConditionalExp |
binaryparenExp;
ID : [a-zA-Z0-9]+ ; // match identifiers
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
OPERATOR: [=><]+ ;
OPAND : A N D ;
OPOR : O R;
fragment DIGIT : [0-9];
fragment A : [aA];
fragment B : [bB];
fragment C : [cC];
fragment D : [dD];
fragment E : [eE];
fragment F : [fF];
fragment G : [gG];
fragment H : [hH];
fragment I : [iI];
fragment J : [jJ];
fragment K : [kK];
fragment L : [lL];
fragment M : [mM];
fragment N : [nN];
fragment O : [oO];
fragment P : [pP];
fragment Q : [qQ];
fragment R : [rR];
fragment S : [sS];
fragment T : [tT];
fragment U : [uU];
fragment V : [vV];
fragment W : [wW];
fragment X : [xX];
fragment Y : [yY];
fragment Z : [zZ];
由于规则的顺序,词法分析器将 AND 视为标识符,而不是关键字。如果将词法分析器规则部分更改为以下内容,字符串 "AND" 会正确标记为 OPAND.
// match RESERVED WORDS first
OPAND : A N D ;
OPOR : O R;
// match IDENTIFIERS etc.
ID : [a-zA-Z0-9]+ ;
WS : [ \t\r\n]+ -> skip ;
OPERATOR: [=><]+ ;