建筑用ANTLR自己的C#编译器:编译单元(Building own C# compiler usi

2019-08-01 12:56发布

// 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? 我一定要提取其适配器呢? 我怎么做? 注意,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; }
        }
    };

不过我正在树是对象的类型。 我运行使用调试器,似乎看到它的类型是BaseTree的。 但是BaseTree是一个接口! 我不知道它如何与BaseTree,不知道如何从这种树中提取出来的细节。

我需要写一个具有访问其类,方法,变量等。ParserRuleReturn类从RuleReturnScope延伸,并且具有启动访客和停止对象,我不知道它是什么。

此外,存在通过ANTLR提供了这个TreeVisitor类看起来混乱。 它需要一个适配器将作为参数传递给它的构造(如果不是会使用默认的CommonTreeAdaptor),TT就是为什么我问了一下如何获取适配器早期的教上。 和其他问题了。 对于API,你可以参考http://www.antlr.org/api/CSharp/annotated.html

Answer 1:

我还没有过ANTLR的工作从C#,但下面的链接API, BaseTree显然不是一个接口-这是一个类 ,它具有公共属性: Type ,以获得节点的类型, Text得到(我认为)与之相对应的源文本,以及Children得到子节点。 还有什么你需要走呢?



Answer 2:

你可以在像这样的文件的顶部设置你的语法选项AST树类型:

tree grammar CSharpTree;
options { 
    ASTLabelType = CommonTree
}

我将建立一个第三语法或它的工作到您现有的解析器语法,轮流树为您创建的类。 例如,假设你已经有了加操作相匹配的规则,它的2个参数。 您可以定义规则匹配树创建你写一个类,姑且称之为PlusExpression是这样的:

plusExpr returns [PlusExpression value]
   : ^(PLUS left=expr right=expr) { $value = new PlusExpression($left.value, $right.value); }

EXPR将是你的语法表达式匹配其他规则。 左,右只是别名给树值。 在之间的{}的是相当多用替换变量引用的例外变成C#代码逐字的部分。 该.value的财产关闭的$左,右$来自关的,他们从创建的规则中指定的回报。



Answer 3:

如果我要做出今天的C#编译器,这是我愿意 尝试的第一次尝试:

  1. 与ANTLR C#3的目标开始(当然我有偏见这里 - 认真,你可以使用的CSHARP2或CSharp3目标)。
  2. 获取的Visual Studio 2010与.NET Framework 4,这里的关键是.NET 4,它是甜的新表达式树。
  3. 建立一个基本的结合解析器。 把尽可能少的逻辑在解析器绝对有可能的。 它应该有几个(如果有的话)的行动,并且输出应该是未修饰的AST可与LL(1)步行者在上面行走。
  4. 建立了一棵树的语法遍历树并确定所有声明类型。 还应保持member_declaration子树以备后用。
  5. 建立树遍历器,可以引导一个member_declaration和成员增加了TypeBuilder 。 跟踪的方法体,但并不深,走他们没有。
  6. 建立树遍历器,可以引导一个方法的主体。 产生Expression<TDelegate>匹配的方法中,与使用 CompileToMethod方法 我自己的API(见帕维尔和我的意见)来生成IL代码。

如果你在这个顺序做的事情,那么当你终于解析表达式(方法体,字段初始化),您可以使用string参数化方法, 像这样一个在Expression类保存工作解决成员。



文章来源: Building own C# compiler using ANTLR: Compilation Unit