如何设计抽象语法树的部分
本文关键字:语法树 抽象 | 更新日期: 2023-09-27 18:26:54
我正在从头开始为学习体验编写一个C#解释器,到目前为止一切都很顺利。我有一个功能齐全的C#lexer,它向解析器输出各种各样的令牌。我知道我将如何解析令牌,但我不确定我应该如何构建AST(抽象语法树)。
例如,如果我有一个简单的代码片段:
using System.Xml;
解析树时会是什么样子?
像这样?
UsingDirective
Identifier(System)
Identifier(Xml)
还是像这样?
UsingDirective
Identifier(System)
Identifier(Xml)
如果我能得到一些关于如何构建带点的标识符、If/else-If/else语句、组合在一个语句中的变量声明/赋值(int I=0;)、函数定义等内容的建议和/或示例,那将很有帮助。我只需要更好地了解如何构建这棵树,剩下的我自己就能搞定。谢谢
我过去写过几个解析器,通常我会选择这样的东西:
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编写的解析器看起来不一样——它们携带了所有这些额外的东西以及更多的信息,比如行号和列号。
您可以看看微软是如何利用Roslyn做到这一点的。你可以在那里看到他们是如何为C#(和VB.NET)声明语法树的,也许你甚至可以在编写它们之前使用它来代替解释器的一部分。
具体来说,using
指令的Roslyn语法树如下所示:
UsingDirective
UsingKeyword
QualifiedName
IdentifierName (System)
DotToken
IdentifierName (Xml)
SemicolonToken
所以,类似于您的第二个版本,但更详细。
我认为你的第一个版本没有多大意义。在句法层面上,Xml
不是System
的子级(尽管稍后在语义层面上可能会有"父命名空间"的概念)。