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