C# ANTLR:使用自定义类型而不是CommonTree生成树图
我已经在ANTLR中为非常简单的表达式定义了语法,如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 = '/' ; } /*------------------------------------------------------------
(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;}
;