2016-09-23 65 views
1

我需要编写布尔表达式解析器/评估器。 表达会的形式,并会在括号括起来:Antlr - 表达式解析器和评估器

exp1 : (A = B) 
exp2 : ((A = B) AND (C = D)) 
exp3 : ((A = B) AND ((C = D) OR (E = F))) 
exp4: (((A = B) AND (C = D)) OR (E = F)) 

,并继续下去。该规则可能包含“n”个表达式,每个组中都有适当的分组2。我的语法文件如下所示:

/* 
Expression grammar 
*/ 

grammar Exparser; 

options 

{ 
    language = Java; 
} 
cond : 
tc EOF; 

tc: 
     exp 
    | binary_exp 
| leftparen* exp (binaryop leftparen* exp rightparen+)* 
| leftparen* exp (binaryop leftparen* exp rightparen*)* 

; 

binary_exp: 
'(' exp BINARYOP exp ')' 
; 

binaryop: 
      BINARYOP 
     ; 
leftparen: 
      LEFTPARN 
     ; 

rightparen: 
       RIGHTPARN 
      ; 

exp: 
LEFTPARN VARIABLE COMPOP VARIABLE RIGHTPARN 

; 

variable: 
      VARIABLE; 


BINARYOP: AND | OR; 
COMPOP: EQUAL | LT | GT | LTE | GTE | NE; 
VARIABLE: (CHAR)+; 
LEFTPARN: '('; 
RIGHTPARN: ')'; 
EQUAL: '=' | 'EQ'; 
LT: '<' | 'LT'; 

GT:'>' | 'GT'; 
LTE: '<='; 
GTE: '>='; 
NE : '!=' | 'NE'; 
AND: 'AND' | '&' | 'and'; 

OR: 'OR' | 'or'; 

CHAR : 'a'..'z'|'A'..'Z'|'_' |'0'..'9'|'-' | '.' 
    ; 

该语法运行正常,但我无法在AST中实现深度。例如exp3被解析为三个exp而不是一个exp和一个binary_exp。 另外如何使用我的解析器评估布尔表达式? 我的语法如何强制平衡括号? 虽然Nested Boolean Expression Parser using ANTLR给出了一些评估表达的想法,但我无法适用于我的案例

回答

1

从以下语法生成的解析器解析所有例如输入:

grammar Exparser; 

parse 
: expr EOF 
; 

expr 
: expr binop expr 
| VARIABLE 
| '(' expr ')' 
; 

binop 
: AND | OR | EQUAL | LT | GT | LTE | GTE | NE 
; 

EQUAL  : '=' | 'EQ'; 
LT  : '<' | 'LT'; 
GT  : '>' | 'GT'; 
LTE  : '<='; 
GTE  : '>='; 
NE  : '!=' | 'NE'; 
AND  : 'AND' | '&' | 'and'; 
OR  : 'OR' | 'or'; 
VARIABLE : [a-zA-Z0-9_.-]+; 
SPACE  : [ \t\r\n] -> skip; 

评估这些表达式应该是一样the Q&A you linked to in your question

+0

谢谢巴特。当我在antlrworks 2上运行它时,我可以获得我的树结构。我尚未开发评估部分。 – ssdimmanuel

+0

语法像魅力一样工作。我做了简单的修改以适应我的需求。对我来说,我的应用程序中的表达式一旦定义就相当静态。我正在考虑将分析树写入磁盘,但发现它不可能,因为这些类不是可序列化的。有没有其他经过验证的方法可以做到这一点? – ssdimmanuel

+0

我还没有看到序列化/持续的ANTLR 4类。 –

0

注意:我不知道antlr。不过,我认为你需要让你的语法更加明确。你超负荷exp太多。尝试这样的伪代码:

tc <- binary_exp ; 
binary_exp <- comparison_exp 
      | LEFTPARN binary_exp RIGHTPARN 
      | LEFTPARN binary_exp BINARYOP binary_exp RIGHTPARN ; 
comparison_exp <- LEFTPARN VARIABLE COMPOP VARIABLE RIGHTPARN ; 
  • tc是一个二进制表达式binary_exp
  • 二进制表达为下列之一:
    • 的比较表达式comparison_exp
    • 一个二进制表达式用括号(LEFTPARNRIGHTPARN)包围,
    • 或左括号LEFTPARN的序列,一个binary_exp,二元运算符BINARYOPbinary_exp和右括号RIGHTPARN
  • 的比较表达式是左括号LEFTPARN的序列,可变VARIABLE,比较运算符COMPOP,一个VARIABLE,和右括号RIGHTPARN

该语法将允许二进制表达式嵌套在额外的括号内或嵌套在另一个括号内,但比较表达式不能在其中嵌套其他表达式。