我为表达式定义了以下生成规则。语法不允许有回溯,并且k更好或等于3。目前的版本有一些歧义,但我不知道在哪里。我在这里删除了AST规则,但语法应该创建一个很好的AST,其中根据优先级显示操作,并显示操作的左关联性。
Antlr 3.2.1与Antlerworks 1.5.1
disjunctionExpresion
: (conjunctionExpresion Disjunction conjunctionExpresion disjunctionExpresionDash) | conjunctionExpresion;
disjunctionExpresionDash
: (Disjunction conjunctionExpresion disjunctionExpresionDash) |;
conjunctionExpresion
: (relationalExpresion Conjunction relationalExpresion conjunctionExpresionDash) | relationalExpresion;
conjunctionExpresionDash
: (Conjunction relationalExpresion conjunctionExpresionDash)|;
relationalExpresion
: (addExpresion RelationalOperator addExpresion relationalExpresionDash) | addExpresion;
relationalExpresionDash
: (RelationalOperator addExpresion relationalExpresionDash)|;
addExpresion
: (multiExpresion addOperator multiExpresion addExpresionDash)| multiExpresion;
addExpresionDash
: (addOperator multiExpresion addExpresionDash)|;
multiExpresion
: (unaryExpresion MultiOperator unaryExpresion multiExpresionDash) | unaryExpresion;
multiExpresionDash
: (MultiOperator unaryExpresion multiExpresionDash) | ;
unaryExpresion
: (unaryOperator basicExpr)->^(unaryOperator basicExpr) | basicExpr -> basicExpr;
basicExpr
: Number | var basicExprDash | ('(' expr ')')->expr;
basicExprDash
: 'touches' var | ;
有了@kaby76关于使用EBNF和查找示例语法的提示,我最终得到了类似于这个C++Antlr3示例的东西。Antrl3树构造文档也非常有帮助。
"^"快速操作员允许我创建所需的AST。
expr : disjunctionExpression;
disjunctionExpression
: conjunctionExpression (Disjunction^ conjunctionExpression)*;
/*equal to:
disjunctionExpression
: (a=conjunctionExpression->$a) (o=Disjunction b=conjunctionExpression -> ^($o $disjunctionExpression $b) )*;
*/
conjunctionExpression
: relationalExpression (Conjunction^ relationalExpression)*;
relationalExpression
: additiveExpression (relationalOperator^ additiveExpression)*;
additiveExpression
: multiExpression (addOperator^ multiExpression)*;
multiExpression
: unaryExpression (multiOperator^ unaryExpression)*;
unaryExpression
: (unaryOperator^)? basicExpr;
basicExpr
: Number | var ('touches'^ var)? | '(' expr ')' -> expr;
这实际上是我以前的精简版:
expr : disjunctionExpresion;
disjunctionExpresion
: conjunctionExpresion disjunctionExpresionDash;
disjunctionExpresionDash
: (Disjunction conjunctionExpresion disjunctionExpresionDash) |;