我写了以下语法,应该检查条件表达式。 下面的示例是我想使用此语法实现的目标:
无效test
无效test = 1
有效test = 1 and another_test>=0.2
有效test = 1 kasd y = 1
无效(两个条件必须用 AND/OR 分隔(a = 1 or (b=1 and c)
无效(不能有像"c"这样的孤独字符。它应该始终是三胞胎。即文字运算符文字(
grammar expression;
expr
: literal_value
| expr ( '='|'<>'| '<' | '<=' | '>' | '>=' ) expr
| expr K_AND expr
| expr K_OR expr
| function_name '(' ( expr ( ',' expr )* | '*' )? ')'
| '(' expr ')'
;
literal_value
: NUMERIC_LITERAL
| STRING_LITERAL
| IDENTIFIER
;
keyword
: K_AND
| K_OR
;
name
: any_name
;
function_name
: any_name
;
database_name
: any_name
;
table_name
: any_name
;
column_name
: any_name
;
any_name
: IDENTIFIER
| keyword
| STRING_LITERAL
| '(' any_name ')'
;
K_AND : A N D;
K_OR : O R;
IDENTIFIER
: '"' (~'"' | '""')* '"'
| '`' (~'`' | '``')* '`'
| '[' ~']'* ']'
| [a-zA-Z_] [a-zA-Z_0-9]*
;
NUMERIC_LITERAL
: DIGIT+ ( '.' DIGIT* )? ( E [-+]? DIGIT+ )?
| '.' DIGIT+ ( E [-+]? DIGIT+ )?
;
STRING_LITERAL
: ''' ( ~''' | '''' )* '''
;
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];
WS: [ ntr]+ -> skip;
所以我的问题是,我怎样才能让语法适用于上面提到的例子?我们可以在两个三元组之间将某些单词设置为强制性的(文字运算符文字(吗?从某种意义上说,我只是想让一个解析器来验证 where 子句条件,但只允许简单的条件和函数。我还想要一个访问者来检索 Java 中的函数、括号、任何文字等值,如何实现?
是和否。
您可以将语法更改为仅允许对同一表达式进行比较和逻辑运算:
expr
: term ( '='|'<>'| '<' | '<=' | '>' | '>=' ) term
| expr K_AND expr
| expr K_OR expr
| '(' expr ')'
;
term
: literal_value
| function_name '(' ( expr ( ',' expr )* | '*' )? ')'
;
如果你想允许布尔变量或函数,问题就来了——你需要在词法分析器中对函数/变量进行分类,并为每个函数/变量设置一个不同的终端,这很棘手且容易出错。
相反,通常最好不要在解析器中进行这种检查 - 让你的解析器宽容并接受任何类似表达式的东西,并为它生成一个表达式树。 然后对树进行单独的传递(称为类型检查器(,该树检查操作数的类型以及函数的参数。
后一种方法(使用单独的类型检查器(通常最终会更简单、更清晰、更灵活,并提供更好的错误消息(而不仅仅是"语法错误"(。