Antlr3 非递归/左分解语法,用于具有良好 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 的内容。 Antrl3 DocumentationsTree 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) |;