如何设计抽象语法树的部分?

时间:2012-03-07 01:28:55

标签: c# syntax tree abstract

我正在从头开始编写C#口译员以获得学习体验,到目前为止,一切都进展顺利。我有一个功能齐全的C#lexer,可以将各种标记输出到解析器。我知道我将如何解析令牌,但我不确定如何构建我的AST(抽象语法树)。

例如,如果我有一个简单的代码片段:

using System.Xml;

解析时树会是什么样子?

喜欢这个吗?

UsingDirective
   Identifier(System)
      Identifier(Xml)

还是喜欢这个?

UsingDirective
   Identifier(System)
   Identifier(Xml)

如果我能得到一些建议和/或示例,我可以如何构造带有点的标识符之类的东西,if / else if / else语句,变量声明/赋值组合在一个语句中(int i = 0;) ,功能定义等会有所帮助。我只需要更好地了解如何构建树,我可以自己弄清楚其余部分。感谢。

2 个答案:

答案 0 :(得分:2)

你可以看看微软是如何与Roslyn一起做的。您可以看到他们是如何为C#(和VB.NET)声明语法树的,甚至可以在编写它们之前使用它而不是解释器的一部分。

具体来说,using指令的Roslyn语法树如下所示:

UsingDirective
    UsingKeyword
    QualifiedName
        IdentifierName (System)
        DotToken
        IdentifierName (Xml)
    SemicolonToken

所以,类似于你的第二个版本,但更详细。

我认为你的第一个版本没有多大意义。 Xml在句法层面上不是System的孩子(即使您稍后在语义层面上可能有“父命名空间”的概念)。

答案 1 :(得分:2)

我过去曾写过几个解析器,我通常会这样做:

UsingDirective
   IdentifierList
     Identifier (LeftNode) (System)
     Identifier (RightNode) (Xml)

如果是using System.Collections.Generic

UsingDirective
   IdentifierList
       IdentifierList (LeftNode)
           Identifier (LeftNode) (System)
           Identifier (RightNode) (Collections)
       Identifier (RightNode) (Generic)

与Roslyn不同,我更喜欢通过不包括诸如分号,using关键字等标记来保持我的AST,因为编译器不需要它们。

解析器我专门为IDE编写的看起来与众不同 - 它们带有所有这些额外的东西以及更多的信息,如行号和列号。