antlr4-tsql解析器:忽略未知语句
我是新来的。我想编写一个t-sql(sybase)解析器,它只监听一些相关的sql语句 是否可以忽略不相关的语句,而不在语法文件中编写完整的t-sql语法。这样就不会出现类似“第8:2行不匹配的输入'INSERT'预期为{EXEC,BEGIN,END,IF}”这样的错误 我的输入是以下sql存储过程(仅示例;): 因此,在我的语法文件中没有任何内容描述insert语句。所以我想忽略这些未知的东西。可能吗 这是我的语法文件:antlr4-tsql解析器:忽略未知语句,tsql,antlr,antlr4,Tsql,Antlr,Antlr4,我是新来的。我想编写一个t-sql(sybase)解析器,它只监听一些相关的sql语句 是否可以忽略不相关的语句,而不在语法文件中编写完整的t-sql语法。这样就不会出现类似“第8:2行不匹配的输入'INSERT'预期为{EXEC,BEGIN,END,IF}”这样的错误 我的输入是以下sql存储过程(仅示例;): 因此,在我的语法文件中没有任何内容描述insert语句。所以我想忽略这些未知的东西。可能吗 这是我的语法文件: grammar Tsql; /************Parser R
grammar Tsql;
/************Parser Rules*******************/
file : createProcedure sqlBlock;
createProcedure: CREATE PROC ID paramList? AS;
//Params of create procedure
paramList: LPAREN (sqlParam)(COMMA sqlParam)* RPAREN;
sqlParam: AT_SIGN ID sqlType; //(EQ defaultValue)?;
sqlType: (VARCHARTYPE | NUMERICTYPE | INTTYPE | CHARTYPE) length?;
length: LPAREN INT RPAREN;
sqlBlock : BEGIN sql* END;
sql: sqlBlock
| sqlIf
| sqlExec
;
sqlExec: EXEC ID (LPAREN sqlExprList? RPAREN)* ; //SQLCall
//IF-rule
sqlIf: IF LPAREN sqlexpr RPAREN sqlIfBlock (sqlElseBlock)?;
sqlElseBlock: ELSE BEGIN sql* END;
sqlIfBlock: BEGIN sql* END;
/* T-SQL expressions */
sqlexpr
: ID LPAREN sqlExprList? RPAREN # K
| AT_SIGN ID # SQLVar
| LPAREN sqlexpr RPAREN # SQLParens
| sqlexpr EQ INT # SQLEqual
| sqlexpr NOT_EQ INT # SQLNotEqual
| sqlexpr LTH sqlexpr # SQLLessThan
| sqlexpr GTH sqlexpr # SQLGreaterThan
| sqlexpr LEQ sqlexpr # SQLLessEqual
| sqlexpr GEQ sqlexpr # SQLGreaterEqual
| sqlexpr (PLUS|MINUS) # SQLAddSub
| sqlexpr (MUTLIPLY|DIVIDE) # SQLMultDiv
| LPAREN sqlexpr RPAREN # SQLParens
| NOT sqlexpr # SQLNot
;
sqlExprList : sqlexpr (',' sqlexpr)* ; // arg list
/************Lexer Rules*******************/
//createProcedure
CREATE : 'CREATE' | 'create';
PROC : 'PROCEDURE' | 'procedure';
AS : 'AS'|'as';
EXEC : ('EXEC'|'exec');
//SqlTypes
INTTYPE: 'int'|'INT';
VARCHARTYPE : 'varchar'|'VARCHAR';
NUMERICTYPE : 'numeric'|'NUMERIC';
CHARTYPE : 'char'| 'CHAR';
//SqlBlock
BEGIN: 'BEGIN' | 'begin';
END: 'END' | 'end';
//If
IF: 'IF' | 'if';
ELSE : 'ELSE' | 'else';
RETURN : ('RETURN' | 'return');
DECLARE : ('DECLARE'|'declare');
AT_SIGN : '@';
ID : LETTER (LETTER | [0-9])* ;
APOSTROPH : [\'];
QUOTE : ["];
LPAREN : '(';
RPAREN : ')';
COMMA : ',';
SEMICOLON : ';';
DOT : '.';
EQ : '=';
NOT_EQ : ('!='|'<>');
LTH : ('<');
GTH : ('>');
LEQ : ('<=');
GEQ : ('=>');
RBRACK : ']';
LBRACK : '[';
PLUS : '+';
MINUS : '-';
MUTLIPLY : '*';
DIVIDE : '/';
COLON : ':';
NOT : ('NOT' | '!');
INT : [0-9]+ ;
ML_COMMENT
: '/*'.*? '*/' -> skip
;
SL_COMMENT
: '//' .*? '\n' -> skip
;
WS : [ \t\r\n]+ -> skip;
fragment
LETTER : [a-zA-Z] ;
语法Tsql;
/************解析器规则*******************/
文件:createProcedure-sqlBlock;
createProcedure:创建过程ID参数列表?AS;
//创建过程的参数
参数列表:LPAREN(sqlParam)(逗号sqlParam)*RPAREN;
sqlParam:AT_SIGN ID sqlType//(EQ默认值)?;
sqlType:(varchartType | NUMERICTYPE | INTTYPE | chartType)长度?;
长度:LPAREN INT RPAREN;
sqlBlock:开始sql*结束;
sql:sqlBlock
|sqlIf
|sqlExec
;
sqlExec:EXEC ID(LPAREN sqlExprList?RPAREN)*//SQLCall
//如果规则
sqlIf:IF LPAREN sqlexpr RPAREN sqlIfBlock(sqlElseBlock)?;
sqlElseBlock:ELSE BEGIN sql*END;
sqlIfBlock:开始sql*结束;
/*T-SQL表达式*/
sqlexpr
:ID LPAREN sqlExprList?RPAREN#K
|AT_符号ID#SQLVar
|LPAREN sqlexpr RPAREN#SQLParens
|sqlexpr EQ INT#SQLEqual
|sqlexpr NOT_EQ INT#SQLNotEqual
|sqlexpr LTH sqlexpr#SQLLessThan
|sqlexpr GTH sqlexpr#SQLGreaterThan
|sqlexpr LEQ sqlexpr#SQLLessEqual
|sqlexpr GEQ sqlexpr#SQLGRaterEqual
|sqlexpr(加|减)#SQLAddSub
|sqlexpr(相互分割)#SQLMultDiv
|LPAREN sqlexpr RPAREN#SQLParens
|非sqlexpr#SQLNot
;
sqlExprList:sqlexpr(','sqlexpr)*;//参数列表
/************Lexer规则*******************/
//创建过程
创建:“创建”|“创建”;
程序:“程序”|“程序”;
AS:‘AS’|‘AS’;
执行官:(‘执行官’|‘执行官’);
//SqlTypes
INTTYPE:'int'|'int';
VARCHARTYPE:'varchar'|'varchar';
NUMERICTYPE:'numeric'|'numeric';
图表类型:“char”|“char”;
//SqlBlock
开始:“开始”|“开始”;
结束:“结束”|“结束”;
//如果
IF:“IF”|“IF”;
ELSE:“ELSE”|“ELSE”;
RETURN:(‘RETURN’|‘RETURN’);
声明:('DECLARE'|'DECLARE');
在"符号"处,;
ID:字母(字母|[0-9])*;
撇号:[\'];
报价:[“];
LPAREN:'(';
RPAREN:')';
逗号:',';
分号:';';
点:';
等式:'=';
非均衡器:(“!=”);
LTH:('');
LEQ:('');
RBRACK:']';
LBRACK:'[';
加:“+”;
减:'-';
相互地:'*';
除法:“/”;
冒号:':';
不:(‘不’|’!’);
内部:[0-9]+;
米卢评论
:“/*”.*?“*/”->跳过
;
SL_评论
:“/”*?“\n'->跳过
;
WS:[\t\r\n]+->跳过;
片段
信:[a-zA-Z];
非常感谢
是否可以忽略不相关的语句,而不在语法文件中编写完整的t-sql语法
你可以这样做:
file
: unit* EOF
;
unit
: my_interesting_statement
| . // any token
;
my_interesting_statement
: createProcedure sqlBlock
| // other statements here?
;
// parser rules
// lexer rules
// Last lexer rule catches any character
ANY
: .
;
规则
文件
现在将匹配零个或多个单位
s。一个单位
将首先尝试匹配一个my\u interest\u语句
,当这不可能时,单位
规则中的最后一个备选方案
,将只匹配一个令牌(没错:解析器规则中的
匹配一个标记,而不是一个字符)。您好,Bart Kiers,非常感谢您的简单解释。很好用!!:)
file
: unit* EOF
;
unit
: my_interesting_statement
| . // any token
;
my_interesting_statement
: createProcedure sqlBlock
| // other statements here?
;
// parser rules
// lexer rules
// Last lexer rule catches any character
ANY
: .
;