// 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;我能用compilation_unit_return类型的x做什么来提取它的根,它的类,它的方法等等?我必须拔出它的适配器吗?我该怎么做?请注意,在我的CSParser (由ANTLR自动生成)中,compilation_unit_return是这样定义的:
public class compilation_unit_return : ParserRuleReturnScope
{
private object tree;
override public object Tree
{
get { return tree; }
set { tree = (object) value; }
}
};然而,我得到的树是object类型的。我使用调试器运行,似乎看到它的类型是BaseTree。但是BaseTree是一个接口!我不知道它与BaseTree有什么关系,也不知道如何从这棵树中提取细节。
我需要写一个访问者,它可以访问它的类,方法,变量等。ParserRuleReturn类从RuleReturnScope扩展,并有一个开始和停止对象,我不知道它是什么。
此外,还有一个由ANTLR提供的TreeVisitor类,它看起来令人困惑。它需要一个适配器作为参数传递给它的构造函数(如果不是,它将使用默认的CommonTreeAdaptor),这就是为什么我在上询问如何获得适配器的原因。以及其他问题。具体接口可以参考http://www.antlr.org/api/CSharp/annotated.html
发布于 2009-08-18 00:32:45
我从未在C#中使用过ANTLR,但是根据你的API链接,BaseTree显然不是一个接口--它是一个class,它具有公共属性:Type获取节点的类型,Text获取(我假设)与之对应的源文本,Children获取子节点。你还需要什么东西才能走到那里呢?
发布于 2009-08-30 02:35:21
您可以在文件顶部的语法选项中设置AST树类型,如下所示:
tree grammar CSharpTree;
options {
ASTLabelType = CommonTree
}我将构建第三个语法,或者将其添加到您现有的解析器语法中,将树转换为您创建的类。例如,假设您有一个匹配加号运算符的规则,它有两个参数。您可以定义一个与该树匹配的规则来创建您编写的类,让我们将其命名为PlusExpression:
plusExpr returns [PlusExpression value]
: ^(PLUS left=expr right=expr) { $value = new PlusExpression($left.value, $right.value); }expr是语法中另一个匹配表达式的规则。left和right只是为树值指定的别名。除了替换变量引用之外,{}之间的部分几乎完全变成了C#代码。$left和$right的.value属性来自于从创建它们的规则中指定的返回。
https://stackoverflow.com/questions/1291153
复制相似问题