2012-12-11 38 views
1

我已经在ANTLR语法定义非常简单的表情像(a + b) * cANTLR:使用自定义类型,而不是生成树图CommonTree

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) { ... } 
} 

我知道我们可以编写一些代码来转换CommonTreeExpr树,但我想直接改写到自定义类型,如:

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

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

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

但是,我应该怎么做exprmultExpr创建BinaryExpr与适当的BinaryExprType

回答

1

尝试这样的事情(未经测试!):

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;} 
; 

诀窍是递归使用规则本身的二进制表示:在new BinaryExpr(...)$expr.e$multExpr.e

相关问题