ANTLR重写规则中的替代方案

时间:2012-08-27 10:58:12

标签: parsing antlr

我正在编写一个支持任意布尔表达式的语法。语法用于表示程序,该程序稍后通过静态分析工具传递。静态分析工具有一定的局限性,因此我想应用以下重写规则:

严格的不等式用epsilon近似:

expression_a > expression_b -> expression_a >= expression_b + EPSILON

使用“或”语句近似不等式:

expression_a != expression_b -> expression_a > expression_b || expression_a < expression_b

使用ANTLR有没有简单的方法?目前我的语法是这样的:

comparison          : expression ('=='^|'<='^|'>='^|'!='^|'>'^|'<'^) expression;

我不确定如何应用不同的重写规则,具体取决于运算符。我希望树保持不变,如果运算符是(“==”,“&lt; =”或“&gt; =”)并按照上面定义的规则以递归方式转换它。

1 个答案:

答案 0 :(得分:3)

  

[...]并以递归方式转换它,[...]

你可以部分地做到这一点。

您无法告诉ANTLR将a > b重写为^('>=' a ^('+' b epsilon)),然后将a != b定义为^('||' ^('>' a b) ^('<' a b)),然后让ANTLR自动重写^('>' a b)^('<' a b)分别为^('>=' a ^('+' b epsilon))^('<=' a ^('-' b epsilon))

这里需要一些手工工作。诀窍在于,如果实际未解析此令牌,则不能仅使用>=之类的令牌。解决此问题的方法是使用imaginary tokens

快速演示:

grammar T;

options {
  output=AST;
}

tokens {
  AND;
  OR;
  GTEQ;
  LTEQ;
  SUB;
  ADD;
  EPSILON;
}

parse
 : expr
 ;

expr
 : logical_expr
 ;

logical_expr
 : comp_expr ((And | Or)^ comp_expr)*
 ;

comp_expr
 : (e1=mult_expr -> $e1) ( Eq   e2=mult_expr -> ^(AND ^(GTEQ $e1 $e2) ^(LTEQ $e1 $e2))
                         | LtEq e2=mult_expr -> ^(LTEQ $e1 $e2)
                         | GtEq e2=mult_expr -> ^(GTEQ $e1 $e2)
                         | NEq  e2=mult_expr -> ^(OR ^(GTEQ $e1 ^(ADD $e2 EPSILON)) ^(LTEQ $e1 ^(SUB $e2 EPSILON)))
                         | Gt   e2=mult_expr -> ^(GTEQ $e1 ^(ADD $e2 EPSILON))
                         | Lt   e2=mult_expr -> ^(LTEQ $e1 ^(SUB $e2 EPSILON))
                         )?
 ;

add_expr
 : mult_expr ((Add | Sub)^ mult_expr)*
 ;

mult_expr
 : atom ((Mult | Div)^ atom)*
 ;

atom
 : Num
 | Id
 | '(' expr ')'
 ;

Eq    : '==';
LtEq  : '<=';
GtEq  : '>=';
NEq   : '!=';
Gt    : '>';
Lt    : '<';
Or    : '||';
And   : '&&';
Mult  : '*';
Div   : '/';
Add   : '+';
Sub   : '-';
Num   : '0'..'9'+ ('.' '0'..'9'+)?;
Id    : ('a'..'z' | 'A'..'Z')+;
Space : ' ' {skip();};

从上面的语法生成的解析器将产生以下内容:


a == b

enter image description here


a != b

enter image description here


a > b

enter image description here


a < b

enter image description here