【发布时间】:2018-06-03 14:22:02
【问题描述】:
关于 AST / 符号表关系,我有一些我不明白的地方。
我目前有一个用 C# 实现的 AST,它具有用于变量声明的节点(这些包含有关名称、类型、源位置、可能的常量值作为表达式节点等的信息)。
现在我想填写一个符号表(在我的 AST 上使用访问者模式),但我的问题是:“符号”是新类,例如 VariableSymbol,还是符号表直接存储来自 AST 的 VariableDeclarationNode?
如果符号是新类,那么谁来存储常量变量、VariableDeclarationNode 或 VariableSymbol 或其他地方的计算表达式值?
(我看过一些解释器示例,它们将所有变量值(包括常量)存储在一个附加的哈希表中,但我正在使用源到源编译器而不是解释器,所以我不确定你将在这种情况下评估常量。抱歉,我知道这些问题有点多)
【问题讨论】:
-
如果您正在使用源到源编译器,为什么还要存储常量表达式的计算表达式值?它是关于翻译成目标语言的语法,而不是解释或维护任何运行时状态。一旦您拥有变量的声明/初始化节点,您能否举例说明您的代码应该做什么/应该做什么?存储对在您用作目标代码发射基础的对象中声明符号的节点的引用本身并没有对错,这取决于您所考虑的架构。
-
我当前的架构是生成 AST 的扫描仪和解析器,我的目标是将 AST 转换为 C 代码,但前提是代码是“有效的”,例如不是多个具有相同名称的变量.我看到了一些博客/教程,他们描述了我可以从 AST 中构建一个范围/符号表来进行语义检查。我发现的示例都有访问者模式来访问所有变量声明并将它们添加到范围/符号表中,但一些示例存储 AST 节点(本示例中为 VariableDeclarationNode),其他示例创建一个新类,例如 VariableSymbol跨度>
-
这就是为什么我不确定哪个解决方案更好,如果我应该直接将 AST 节点添加到范围/表中,或者我是否应该为符号创建新类。您对常量表达式是正确的,遗憾的是我需要出于某种“愚蠢”/遗留原因评估它们,不允许有多个具有相同名称的变量,但有一个特殊规则,如果两个变量都是常量并且具有相同的值,那么应该没有错误消息(但只使用一个变量),这就是为什么我必须为这种特殊的遗留案例评估和存储常量变量的值
-
我想补充一点,这目前是用于源到源编译器,但 AST 将来可能会用于其他用途,因为我们可能稍后会添加解释器,这就是我想要制作的原因确保我使用了一个好的架构,因为这是我第一次用 AST / 编译器做任何事情
-
我明白了。仍然可能a)意见问题或b)由您的帖子中不够清楚的设计考虑驱动:如果AST节点中的信息对任务足够,那么您只需存储参考就可以了在范围树/表中。如果你从语法树解释而不是仅仅发出代码,那么你需要复杂的数据结构,其中对原始 AST 节点的引用是次要问题(c'ued)
标签: c# compilation abstract-syntax-tree symbol-table compiler-construction