【问题标题】:How to design parts of an Abstract Syntax Tree?如何设计抽象语法树的一部分?
【发布时间】:2012-03-07 01:28:55
【问题描述】:

为了学习经验,我正在从头开始编写一个 C# 解释器,到目前为止一切都很顺利。我有一个功能齐全的 C# 词法分析器,可以将各种标记输出到解析器。我知道我将如何解析标记,但我不确定我应该如何构建我的 AST(抽象语法树)。

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

using System.Xml;

解析后的树会是什么样子?

像这样?

UsingDirective
   Identifier(System)
      Identifier(Xml)

还是这样?

UsingDirective
   Identifier(System)
   Identifier(Xml)

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

【问题讨论】:

  • 如果你想实现所有的 C#,这将是一个漫长的学习经历:-)
  • 好吧,我忽略了类库的大部分内容。我基本上只是在实现基本类/函数定义、变量创建/使用和函数调用需要实现的内容。

标签: c# syntax tree abstract


【解决方案1】:

我过去写过几个解析器,我通常会选择这样的东西:

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 编写的解析器看起来不同 - 它们携带所有这些额外的东西以及更多信息,例如行号和列号。

【讨论】:

  • 你为什么让你的IdentifierList只有两个孩子?为什么没有一个IdentifierList 和尽可能多的孩子?
  • 是的,我认为单个 IdentifierList 包含无限的孩子​​会更好。无论如何,感谢您的回答 xbonez。
  • 我相信这也可以。我个人发现以这种方式(递归)遍历它比只是一个身份列表更容易。我会设置一个函数traverIdentList: if (identlist.leftnode is identlistnode) { traverseIdentList(leftnode); } else { traverseident(leftnode); } traverseident(rightnode);
  • 好点。稍后我将在数学运算符中使用这种递归方法。
  • 我无法决定接受哪个答案。他们都很有帮助 XD。
【解决方案2】:

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

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

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

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

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

【讨论】:

  • 但这不是抽象的语法树,而是具体的语法树,因为它包含部分源代码,例如点和分号。
  • 是的,你是对的。但我认为您可以以此为基础构建您的 AST。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多