Antlr3 具有良好 AST 的表达式的非递归/左分解语法

Antlr3 Non-recursive / leftfactorized grammar for expressions with a nice AST

我已经为表达式定义了以下生产规则。语法不允许有回溯和 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 example. The Antrl3 Documentations for Tree construction 也很有帮助。

“^”快速运算符允许我创建所需的 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) |;