antlr4-tsql解析器:忽略未知语句

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

我是新来的。我想编写一个t-sql(sybase)解析器,它只监听一些相关的sql语句

是否可以忽略不相关的语句,而不在语法文件中编写完整的t-sql语法。这样就不会出现类似“第8:2行不匹配的输入'INSERT'预期为{EXEC,BEGIN,END,IF}”这样的错误

我的输入是以下sql存储过程(仅示例;):

因此,在我的语法文件中没有任何内容描述insert语句。所以我想忽略这些未知的东西。可能吗

这是我的语法文件:

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
 : .
 ;