我写了下面的语法,应该检查条件表达式。 下面的例子是我想用这个语法实现的目标:
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: [ \n\t\r]+ -> skip;
所以我的问题是,如何让语法适用于上面提到的例子?我们可以在两个三元组之间强制使用某些单词(文字运算符字面值)吗?从某种意义上说,我只是想让一个解析器来验证where子句条件,但只允许简单的条件和函数。我还想让一个访问者在Java中检索函数,括号,任何文字等值,如何实现呢?
答案 0 :(得分:1)
是和否。
您可以将语法更改为仅允许相同的表达式和逻辑运算:
expr
: term ( '='|'<>'| '<' | '<=' | '>' | '>=' ) term
| expr K_AND expr
| expr K_OR expr
| '(' expr ')'
;
term
: literal_value
| function_name '(' ( expr ( ',' expr )* | '*' )? ')'
;
如果你想允许布尔变量或函数,问题就出现了 - 你需要对词法分析器中的函数/变量进行分类,并为每个变量分配一个不同的终端,这很棘手且容易出错。
相反,通常最好不要在解析器中进行这种检查 - 让你的解析器允许并接受类似表达式的任何东西,并为它生成表达式树。然后在树上有一个单独的传递(称为类型检查器),它检查操作操作数的类型和函数的参数。
后一种方法(使用单独的类型检查器)通常最简单,更清晰,更灵活,并提供更好的错误消息(而不仅仅是语法错误&#39;)。