我有一些关于我不理解的AST /符号表关系的事情。
我目前在C#中实现了一个AST,其中包含变量声明的节点(这些节点包含有关名称,类型,源位置,可能的常量值作为表达式节点的信息等)。
现在我想填充一个符号表(使用AST上的访问者模式),但我的问题是:是“符号”新类,例如VariableSymbol,还是符号表直接存储AST的VariableDeclarationNode?
如果符号是新类,那么谁将存储常量变量的评估表达式值,VariableDeclarationNode或VariableSymbol或其他地方?
(我已经看到了一些解释器示例,它们将所有变量值(包括常量)存储在一个额外的哈希表中,但我正在处理源到源编译器而不是解释器,所以我不知道你在哪里存储在这种情况下评估常数。抱歉,我知道这些有点多个问题)
答案 0 :(得分:2)
是例如VariableSymbol的“符号”新类,或者符号表是否直接存储来自AST的VariableDeclarationNode? p>
如果AST节点中的信息足以完成任务,那么您只需在范围树/表中存储引用即可。如果您从语法树解释而不是仅仅发出代码,那么您需要复杂的数据结构,其中存在对原始AST节点的引用是次要问题。我们已经看到并完成了这两项工作。在lexing&amp ;;之外的阶段不保留对“原始”AST节点的引用。解析是一种更清洁的方法。
[会不会]在符号类中存储已计算的常量值(对于特殊情况),还是应该为这些值创建一个附加表?
这实际上也取决于......如果您将常量值设想为声明的固有属性,请将其存储在符号描述符类中:
class Symbol : ISymbol {
ASTNode DeclaringNode;
SymbolType RuntimeType;
bool InitializeAsConstant;
RuntimeValue ConstantValue;
...
}
如果你保留包含rvalues,那么你可以在目标语言中逐字复制声明,然后将它们视为一个变量,直到过程结束:
/* fantasy source language */
Constant $$IAMCONSTANT :=> /03\ MUL /02\ KTHXBYE
/* target language */
const int IAMCONSTANT = 3 * 2;
/* as opposed to compilation stage 1 precomputed */
const int IAMCONSTANT = 6;
对于源到源的情况,第一个更容易,因为你可能会在编译器中没有计算表达式值的情况下离开。