有没有熟悉 antlr4 的懂哥
我正在实现一个查询语言的语义分析,其中我定义了数字的词法规则如下
然后我在解析分页命令时我使用如下的语法规则来进行匹配
page_stmt
: F_PAGE EQ number F_SIZE EQ number
;
number :(NUMBER)+ ;
NUMBER : DIGIT+ ;
fragment DIGIT : [0-9];
但是无论如何都报错,不能命中我定义的数字规则
name = 2023-01-01 and action in ('allow','src') or id = 12314 page = 1 size = 2
如下是生成的语法树
总是提示被DATE_TIME干扰了
最后附上完整g4文件
grammar Dsl;
@header {
package net.skycloud.dsl;
}
parse
: ( dsl_stmt_list )* EOF
;
dsl_stmt_list
: SCOL* dsl_stmt ( SCOL+ dsl_stmt )* SCOL*
;
dsl_stmt
: OPEN_PAR* expr ( ( K_AND | K_OR) OPEN_PAR* expr CLOSE_PAR* )* CLOSE_PAR* page_stmt? ordering_term?
;
expr
: K_NOT* ( field ) operator OPEN_PAR* ( literal_value | literal_list | FUNCTION | dates ) CLOSE_PAR*
;
page_stmt
: F_PAGE EQ number F_SIZE EQ number
;
ordering_term
: K_ORDER K_BY field ordering_op? (COMMA field ordering_op? )*
;
ordering_op
: ( K_ASC | K_DESC )
;
operator
: EQ
| NOT_EQ
| CONTAINS
| NOT_CONTAINS
| LT_EQ
| LT
| GT
| GT_EQ
| K_IN
| K_NOT K_IN
| K_IS
| K_WAS
| K_IS K_NOT
| K_WAS K_NOT
| K_CHANGED K_TO
;
literal_value
: STRING_LITERAL
| NUMBER*
| IDENTIFIER
| state_name
| field
| dates
;
FUNCTION
: [a-zA-Z]+ '(' (.*? | FUNCTION) ')'
;
literal_list
: '(' literal_value ( COMMA literal_value )* ')'
;
keyword
: K_AFTER
| K_AND
| K_ASC
| K_BEFORE
| K_BY
| K_CHANGED
| K_DESC
| K_IN
| K_IS
| K_NOT
| K_NULL
| K_ON
| K_OR
| K_ORDER
| K_TO
| K_WAS
;
state_name
: K_EMPTY
;
field
: F_ID
| F_NAME
| F_ENABLED
| F_DATASOURCE
| F_HITCOUNT
| F_UNIQUEKEY
| F_SOURCE_USER
| F_SOURCE_IP
| F_SOURCE_NAME
| F_DESTNATION_IP
| F_DESTNATION_NAME
| F_SERVICE_PROTOCOL
| F_SERVICE_PORT
| F_SRC_ZONE
| F_DST_ZONE
| F_ACTION
| F_DESCRIPTION
| F_TABLE
| F_SECTION
| F_SRC_NEGATED
| F_DST_NEGATED
| F_SVC_NEGATED
| F_SOURCE_IS_ANY
| F_DESTNATION_IS_ANY
| F_SERVICE_IS_ANY
| F_SCHEDULE_NAME
| F_LOG_OPTION
| F_DEVICE_ID
| F_DEVICE_NAME
;
number :(NUMBER)+ ;
dates : DATETIME ;
DATETIME
: ('-'|'+')? (NUMBER ('d'|'w'|'y'|'h'|'m')?)+
| ('"' DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT (DIGIT DIGIT ':' DIGIT DIGIT)? '"')
| ('\'' DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT (DIGIT DIGIT ':' DIGIT DIGIT)? '\'')
| ( DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT (DIGIT DIGIT ':' DIGIT DIGIT)? )
;
NUMBER : DIGIT+ ;
WHITESPACE : ' ' -> skip ;
SCOL : ';';
DOT : '.';
OPEN_PAR : '(';
CLOSE_PAR : ')';
COMMA : ',';
EQ : '=';
STAR : '*';
CONTAINS : '~';
NOT_CONTAINS : '!~';
LT : '<';
LT_EQ : '<=';
GT : '>';
GT_EQ : '>=';
NOT_EQ : '!=';
K_AFTER : A F T E R;
K_AND : A N D;
K_ASC : A S C;
K_BEFORE : B E F O R E;
K_BY : B Y;
K_CHANGED : C H A N G E D;
K_DESC : D E S C;
K_EMPTY : E M P T Y;
K_IN : I N;
K_IS : I S;
K_NOT : N O T;
K_NULL : N U L L;
K_ON : O N;
K_OR : O R;
K_ORDER : O R D E R;
K_TO : T O;
K_WAS : W A S;
F_ID : I D;
F_NAME : N A M E;
F_ACTION: A C T I O N;
F_DESTNATION_IP : (D E S T N A T I O N '.' I P | D S T '.' I P);
F_DESTNATION_NAME : (D E S T N A T I O N '.' N A M E | D E S T N A T I O N '.' N A M E);
F_DESTNATION_IS_ANY : (D E S T I N A T I O N '.' I S A N Y | D S T '.' I S A N Y);
F_SOURCE_IP : (S O U R C E '.' I P | S R C '.' I P);
F_SOURCE_NAME : (S O U R C E '.' N A M E | S R C '.' N A M E);
F_SOURCE_USER : (S O U R C E '.' U S E R | S R C '.' U S E R);
F_SOURCE_IS_ANY : (S O U R C E '.' I S A N Y | S R C '.' I S A N Y);
F_SERVICE_PORT : (S E R V I C E '.' P O R T | S V C '.' P O R T);
F_SERVICE_PROTOCOL : (S E R V I C E '.' P R O T O C O L | S V C '.' P R O T O C O L);
F_SERVICE_IS_ANY : (S E R V I C E '.' I S A N Y | S V C '.' I S A N Y);
F_DEVICE_NAME : D E V I C E '.' N A M E;
F_SECTION : S E C T I O N;
F_TABLE : T A B L E;
F_DEVICE_ID : D E V I C E '.' I D;
F_DESCRIPTION : D E S C R I P T I O N;
F_ENABLED : E N A B L E D;
F_DATASOURCE : D A T A S O U R C E;
F_HITCOUNT : H I T C O U N T;
F_UNIQUEKEY : U N I Q U E K E Y;
F_LOG_OPTION : L O G O P T I O N;
F_SRC_ZONE : (S R C Z O N E | S O U R C E Z O N E);
F_DST_ZONE : (D S T Z O N E | D E S T N A T I O N Z O N E);
F_SRC_NEGATED: (S R C '.' N E G A T E D| S O U R C E '.' N E G A T E D);
F_DST_NEGATED: (D S T '.' N E G A T E D| D E S T N A T I O N '.' N E G A T E D);
F_SVC_NEGATED: (S E R V I C E '.' N E G A T E D| S V C '.' N E G A T E D);
F_SCHEDULE_NAME: S C H E D U L E '.' N A M E;
F_PAGE: (P A G E | P);
F_SIZE: (S I Z E | S);
IDENTIFIER
: '"' (~'"' | '""')* '"'
| '`' (~'`' | '``')* '`'
| '[' ~']'* ']'
| [a-zA-Z_] [a-zA-Z_0-9.\-]* // TODO check: needs more chars in set
| '-'
| [A-Z]+ '-' [0-9]+ // ex) KEY-###
;
STRING_LITERAL
: '\'' ('\\'. | '\'\'' | ~('\'' | '\\'))* '\''
| '"' ( '\\'. | '""' | ~('"'| '\\') )* '"'
;
COMMENT
: '/*' .*? '*/' -> skip
;
LINE_COMMENT
: '//' ~[\r\n]* -> skip
;
SPACES
: [ \u000B\t\r\n] -> channel(HIDDEN)
;
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];
可能在你的词法分析器文件中,DATETIME规则在数字规则之前被定义了