C# ANTLR:使用自定义类型而不是CommonTree生成树图

C# ANTLR:使用自定义类型而不是CommonTree生成树图,c#,antlr,antlr3,C#,Antlr,Antlr3,我已经在ANTLR中为非常简单的表达式定义了语法,如(a+b)*c: grammar SimpleCalc; options { language=CSharp2; output=AST; } tokens { PLUS = '+' ; MINUS = '-' ; MULT = '*' ; DIV = '/' ; } /*------------------------------------------------------------

我已经在ANTLR中为非常简单的表达式定义了语法,如
(a+b)*c

grammar SimpleCalc;

options {
    language=CSharp2;
    output=AST;
}

tokens {
    PLUS  = '+' ;
    MINUS = '-' ;
    MULT = '*' ;
    DIV = '/' ;
}

/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/

ID  : ('a'..'z' | 'A' .. 'Z' | '0' .. '9')+ ;

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { Skip(); } ;

/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

expr : multExpr ((PLUS | MINUS)^ multExpr)*;

multExpr : atom ((MULT | DIV)^ atom )*;

atom : ID
     | '(' expr ')' -> expr;
现在我有了一些用于创建树结构的预定义类型:

public class Expr { }

public class SimpleExpr : Expr
{
    public SimpleExpr(string name) { ... }
}

public enum BinaryExprType
{
    Plus,
    Minus,
    Multiply,
    Divide
}

public class BinaryExpr : Expr
{
    public BinaryExpr(Expr left, BinaryExprType op, Expr right) { ... }
}
我知道我们可以编写一些代码将
CommonTree
转换为
Expr
树,但我想直接重写为自定义类型,如:

atom returns [Expr e]
    : ID { $e = new SimpleExpr($ID.text); }
    | '(' expr ')' { $e = $expr.e; };

expr returns [Expr e]
    : /* ??? */;

multExpr returns [Expr e]
    : /* ??? */;
但是我应该如何为
expr
multExpr
创建
BinaryExpr
,并使用适当的
BinaryExprType

尝试类似的方法(未经测试!):

诀窍是在二进制表达式中递归使用规则本身:
newbinaryexpr(…)
中的
$expr.e
$multExpr.e
尝试类似的方法(未经测试!):

诀窍是在二进制表达式中递归使用规则本身:
newbinaryexpr(…)
中的
$expr.e
$multExpr.e

expr returns [Expr e]
 : m1=multExpr         {$e = $m1.e;} 
   ( PLUS m2=multExpr  {$e = new BinaryExpr($expr.e, BinaryExprType.Plus, $m2.e);}
   | MINUS m2=multExpr {$e = new BinaryExpr($expr.e, BinaryExprType.Minus, $m2.e);}
   )*
 ;

multExpr returns [Expr e]
 : a1=atom        {$e = $a1.e;}
   ( MULT a2=atom {$e = new BinaryExpr($multExpr.e, BinaryExprType.Multiply, $a2.e);}
   | DIV a2=atom  {$e = new BinaryExpr($multExpr.e, BinaryExprType.Divide, $a2.e);}
   )*
 ;

atom returns [Expr e]
 : ID           {$e = new SimpleExpr($ID.text);}
 | '(' expr ')' {$e = $expr.e;}
 ;