对不起,也许这是一个抽象的问题。但这可以帮助我理解符号表的用法。假设我想实现简化的C#编译器,这是我要编译的代码:
// Let simplified version of c# language does not contain access modifiers
// (all by default public)
class Foo
{
int Sum(int a, int b) { return a + b; }
};
以下是简化的AST代码:
ClassNode (name:Foo)
└─╴FuncNode (name:Sum, type:(a:int,b:int)->int)
└─╴OperatorNode (name:+, type:(int,int)->int)
├─╴ArgNode (name:a, type:int)
└─╴ArgNode (name:b, type:int)
换句话说,我们有ClassNode
声明了类Foo。该ClassNode
有一个FuncNode
,它声明了函数Sum
。 FuncNode
包含主体,主体又是简单的算术表达式。
符号表的链看起来像:
(Global symbol table)
┌────────┬──────────┬───────────┐
│SymName │Type │Attr │
├────────┼──────────┼───────────┤
│Foo │class:Foo │ClassDecl │
└────────┴──────────┴───────────┘
\/
(Inner symbol table)
┌────────┬────────────────────┬──────────────────┐
│SymName │Type │Attr │
├────────┼────────────────────┼──────────────────┤
│Sum │func:(int,int)->int │InstanceFuncDecl │
└────────┴────────────────────┴──────────────────┘
\/
(Inner symbol table)
┌────────┬─────┬─────────┐
│SymName │Type │Attr │
├────────┼─────┼─────────┤
│a │Int │Argument │
│b │Int │Argument │
└────────┴─────┴─────────┘
符号表应该包含有关类/函数的声明的信息还是应该仅包含有关局部变量/字段等的信息?我想它应该同时包含两者,因为这样的信息可以用于生成调用递归函数(而不是从AST中提取函数的类型(它需要遍历AST),我们可以从符号表中快速提取出来吗?)
或者仅使用类型化的抽象语法树而不使用任何符号表也许就足够了?