yee*_*een 9 c# compiler-construction antlr visitor abstract-syntax-tree
// Create a scanner that reads from the input stream passed to us
CSLexer lexer = new CSLexer(new ANTLRFileStream(f));
tokens.TokenSource = lexer;
// Create a parser that reads from the scanner
CSParser parser = new CSParser(tokens);
// start parsing at the compilationUnit rule
CSParser.compilation_unit_return x = parser.compilation_unit();
object ast = x.Tree;
Run Code Online (Sandbox Code Playgroud)
我怎么能用compilation_unit_return类型的x来提取它的根,它的类,它的方法等?我必须提取其适配器吗?我怎么做?请注意,compilation_unit_return在我的CSParser中定义(由ANTLR自动生成):
public class compilation_unit_return : ParserRuleReturnScope
{
private object tree;
override public object Tree
{
get { return tree; }
set { tree = (object) value; }
}
};
Run Code Online (Sandbox Code Playgroud)
然而,我得到的树是类型对象.我使用调试器运行,似乎看到它是BaseTree类型.但是BaseTree是一个界面!我不知道它与BaseTree的关系,也不知道如何从这棵树中提取细节.
我需要编写一个访问其类,方法,变量等的访问者.ParserRuleReturn类从RuleReturnScope扩展并具有一个start和stop对象,我不知道它是什么.
此外,ANTLR提供的这个TreeVisitor类看起来令人困惑.它需要一个Adapter作为参数传递给它的构造函数(如果不是它将使用默认的CommonTreeAdaptor),这就是我询问如何获取Adapter eariler的原因.还有其他问题.对于API,您可以参考http://www.antlr.org/api/CSharp/annotated.html
您可以在文件顶部的语法选项中设置AST树类型,如下所示:
tree grammar CSharpTree;
options {
ASTLabelType = CommonTree
}
Run Code Online (Sandbox Code Playgroud)
我将构建第3个语法或将其用于现有的解析器语法,将树转换为您创建的类.例如,假设您有一个与plus运算符匹配的规则,它是2个参数.您可以定义匹配该树的规则,该树创建您已编写的类,我们将其称为PlusExpression,如下所示:
plusExpr returns [PlusExpression value]
: ^(PLUS left=expr right=expr) { $value = new PlusExpression($left.value, $right.value); }
Run Code Online (Sandbox Code Playgroud)
expr将是语法匹配表达式中的另一个规则.left和right只是给树值的别名.除了替换变量引用之外,{}之间的部分几乎逐字转换为C#代码.$ left和$ right的.value属性来自它们创建的规则指定的返回值.