表达式的ANTLR语法

时间:2009-09-21 03:10:34

标签: antlr expression grammar abstract-syntax-tree

我正在尝试实现一个表达式处理语法(处理嵌套的括号和东西)。到目前为止,我有以下内容,但他们无法处理某些情况(成功/失败案例出现在以下代码块之后)。有谁知道发生了什么事?

注意: varname + = varname = 这些东西只是XText中的一些额外的AST生成助手。暂时不要担心它们。

...

NilExpression returns Expression:
  'nil';

FalseExpression returns Expression:
  'false';

TrueExpression returns Expression:
  'true';

NumberExpression returns Expression:
  value=Number;

StringExpression returns Expression:
  value=STRING; //EllipsesExpression: '...';
//FunctionExpression: function=function; //don't allow random functions


UnaryExpression:
  op=unop ('(' expr=Expression ')')|expr=Expression;

BinaryExpression:
  'or'? AndOp; //or op

AndOp:
  'and'? ComparisonOp;

ComparisonOp:
  ('>'|'<'|'>='|'<='|'=='|'~=')? ConcatOp;

ConcatOp:
  '..'? AddSubOp;

AddSubOp:
  ('+' '-')? MultDivOp;

MultDivOp:
  ('*' '/')? ExpOp;

ExpOp:
  '^'? (('(' expr=Expression ')')|expr=Expression);

ExprSideOne : Variable|NilExpression|FalseExpression|TrueExpression|
  NumberExpression|StringExpression|UnaryExpression;

Expression:
  ( 
   '('
  expression1=ExprSideOne expression2+=BinaryExpression*
   ')' 
  )
  |
  ( expression1=ExprSideOne expression2+=BinaryExpression* )
;
...

这是解析/失败的列表:

c = ((b)); //fails
c = ((a not b)); //fails
c = b; //parses
d = (b); //parses

3 个答案:

答案 0 :(得分:4)

正在发生的事情是你的表达式/表达式支持单括号但不支持多个括号(如你所述)。我没有ANTLR特定的经验,但我和Javacc一起工作,它有许多相似的概念(我为Prolog写了一个语法......不要问)。

要处理嵌套括号,通常会有类似于:

的内容
ParenthesisExpression: '(' (ParenthesisExpression | Expression) ')';

这意味着表达式要么包含在括号中,要么只是一个原始表达式。至于AST如何处理这个问题,ParenthesisExpression'是一个'表达式,所以它可以表示为子类或实现(如果Expression是一个接口/抽象类的排序)。

答案 1 :(得分:1)

我将这个语法用于简单表达式: http://fisheye2.atlassian.com/browse/~raw,r=5175/antlr-examples/C/polydiff/Poly.g

我还在这个项目中使用了包含更复杂表达式的语法: http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx

答案 2 :(得分:1)

使用^ 之后的,令牌/规则名称对于定义表达式非常有用。

    expression :    e1 (OR^ e1)* ;
    e1  :   e2 (AND^ e2)*;
    e2  :   e3 (PIPE^ e3)*;
    e3  :   e4 (ANDSYMB^ e4)*;
    e4  :   e5 ((EQUAL^|NOTEQUAL^) e5)*;
    e5  :   e6 ((LESS^|GREATER^) e6)*;
    e6  :   e7 ((PLUS^|MINUS^) e7)* ;
    e7  :   e8 ((STAR^|SLASH^) e8)* ;
    e8  :   e9 (NEW^ ID LPAREN RPAREN)*;
    e9  :   (NOT^)? e10;
    e10 :   e11 | call_def;
    e11 :   constant 
        | '(' expression ')' -> expression;