Antlr - 表达式解析器和赋值器

时间:2016-09-23 18:44:19

标签: java parsing antlr antlr4

我需要编写一个布尔表达式解析器/求值器。 表达式将是形式,并将括在括号中:

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给出了评估表达式的一些想法,但我无法在我的情况下应用

2 个答案:

答案 0 :(得分: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相同。

答案 1 :(得分: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),
    • 或左括号LEFTPARNbinary_exp,二元运算符BINARYOPbinary_exp和右括号RIGHTPARN的序列。
  • 比较表达式是左括号LEFTPARN,变量VARIABLE,比较运算符COMPOPVARIABLE和右括号{{的序列1}}。

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