符号表是存储AST(声明)节点还是“符号”不同的对象/类?

时间:2018-06-03 14:22:02

标签: c# compilation abstract-syntax-tree symbol-table compiler-construction

我有一些关于我不理解的AST /符号表关系的事情。

我目前在C#中实现了一个AST,其中包含变量声明的节点(这些节点包含有关名称,类型,源位置,可能的常量值作为表达式节点的信息等)。

现在我想填充一个符号表(使用AST上的访问者模式),但我的问题是:是“符号”新类,例如VariableSymbol,还是符号表直接存储AST的VariableDeclarationNode?

如果符号是新类,那么谁将存储常量变量的评估表达式值,VariableDeclarationNode或VariableSymbol或其他地方?

(我已经看到了一些解释器示例,它们将所有变量值(包括常量)存储在一个额外的哈希表中,但我正在处理源到源编译器而不是解释器,所以我不知道你在哪里存储在这种情况下评估常数。抱歉,我知道这些有点多个问题)

1 个答案:

答案 0 :(得分:2)

  

是例如VariableSymbol的“符号”新类,或者符号表是否直接存储来自AST的VariableDeclarationNode?

如果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;

对于源到源的情况,第一个更容易,因为你可能会在编译器中没有计算表达式值的情况下离开。