如何在Antlr中强制执行某些规则
问题描述:
我编写了下面的应检查条件表达式的语法。下面 例子是我想用这个语法要达到什么:如何在Antlr中强制执行某些规则
test
无效test = 1
有效test = 1 and another_test>=0.2
有效test = 1 kasd y = 1
无效(两个条件都必须通过分离和/或)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中的函数,括号,任何文字等值,如何实现这一点?
答
是和否。
您可以将语法更改为仅允许在同一比较和逻辑运算表达式:
expr
: term ('='|'<>'| '<' | '<=' | '>' | '>=') term
| expr K_AND expr
| expr K_OR expr
| '(' expr ')'
;
term
: literal_value
| function_name '(' (expr (',' expr)* | '*')? ')'
;
问题来,如果你想允许布尔变量或函数 - 你需要的功能分类/ vars在你的词法分析器中,并且每个都有一个不同的终端,这是棘手和容易出错的。
相反,它是一般最好不要做这种在解析器检查 - 有了解析器是宽容和接受任何表情状,并为它生成一个表达式树。然后有一个单独的遍历树(称为类型检查器)来检查操作的操作数的类型和函数的参数。
后一种方法(与单独的类型检查器)通常最终被简单得多,更清晰,更灵活,并给出了更好的错误信息(而不是仅仅“语法错误”)。
谢谢。接受一切,然后抛出错误似乎是一个更好的方法。但是,我不能得到它的树:http://imgur.com/a/68RWI – NEO
在这个例子中,你有一个语法错误的'lals',因为没有办法做出来的表情它,不论什么类型 –