使用ANTLR4解析SQL CREATE语句:在输入'冲突'时没有可行的替代方法

时间:2013-07-22 06:05:10

标签: antlr4

我是新手ANTLR用户,并尝试解析以下sql create语句。 (我放弃了SQL和语法中不重要的部分)

CREATE TABLE Account (_id integer primary key, conflict integer default 1);

,语法是这样的:(你可以用copy& paste编译这个语法)

grammar CreateTable;

tableList : (createTableStmt)* ;

createTableStmt : CREATE TABLE tableName LP columnDefs (COMMA tableConstraints)? RP SEMICOLON ;

columnDefs      : columnDef (COMMA columnDef)* ;
columnDef       : columnName typeName? columnConstraint* ;
typeName        : sqliteType (LP SIGNED_NUMBER (COMMA SIGNED_NUMBER)? RP)?  ;
sqliteType      : intType | textType | ID ;
intType         : 'INTEGER'|'LONG';
textType        : TEXT ; 

columnConstraint
    : (CONSTRAINT name)? PRIMARY KEY conflictClause?
    | (CONSTRAINT name)? UNIQUE conflictClause?
    | (CONSTRAINT name)? DEFAULT SIGNED_NUMBER
    ;

tableConstraints
    : tableConstraint (COMMA tableConstraint)* ;

tableConstraint
    : (CONSTRAINT name)? (PRIMARY KEY|UNIQUE) LP indexedColumns RP conflictClause? ;

conflictClause  : ON CONFLICT REPLACE ;
indexedColumns  : indexedColumn (COMMA indexedColumn)* ;
indexedColumn   : columnName;
columnName      : name ;
tableName       : name ;
name            : ID | '\"' ID '\"' | STRING_LITERAL ;

SIGNED_NUMBER   : (PLUS|MINUS)? NUMERIC_LITERAL ;
NUMERIC_LITERAL : DIGIT+ ;
STRING_LITERAL  : '\'' (~'\'')* '\'' ;

LP              : '(' ;
RP              : ')' ;
COMMA           : ',' ;
SEMICOLON       : ';' ;
PLUS            : '+' ;
MINUS           : '-' ;

CONFLICT        : C O N F L I C T ; 
CONSTRAINT      : C O N S T R A I N T ; 
CREATE          : C R E A T E ; 
DEFAULT         : D E F A U L T;
KEY             : K E Y ; 
ON              : O N;
PRIMARY         : P R I M A R Y ; 
REPLACE         : R E P L A C E;
TABLE           : T A B L E ; 
TEXT            : T E X T;
UNIQUE          : U N I Q U E ; 

WS              : [ \t\r\n\f]+ -> channel(HIDDEN);
ID              : LETTER (LETTER|DIGIT)*;
fragment LETTER : [a-zA-Z_];
fragment DIGIT  : [0-9] ;
NL              : '\r'? '\n' ;

fragment A:('a'|'A'); fragment B:('b'|'B'); fragment C:('c'|'C'); 
fragment D:('d'|'D'); fragment E:('e'|'E'); fragment F:('f'|'F'); 
fragment G:('g'|'G'); fragment I:('i'|'I'); fragment K:('k'|'K'); 
fragment L:('l'|'L'); fragment M:('m'|'M'); fragment N:('n'|'N'); 
fragment O:('o'|'O'); fragment P:('p'|'P'); fragment Q:('q'|'Q'); 
fragment R:('r'|'R'); fragment S:('s'|'S'); fragment T:('t'|'T'); 
fragment U:('u'|'U'); fragment X:('x'|'X');

顺便说一句,我应解析的上述SQL语句使用保留字'conflict'作为列名。如果我将列名'冲突'改为其他名称,例如'conflict1',一切都可以。

我应该在哪里更改为解析SQL语句?

解析树看起来像这样。

wrong case correct case

由于

1 个答案:

答案 0 :(得分:1)

您将输入“冲突”定义为单独的标记CONFLICT。因此,如果它也是一个有效的表名和列名,那么这应该有效:

name            : ID | '\"' ID '\"' | STRING_LITERAL | CONFLICT