符号表如何与静态链和范围界定相关?

时间:2010-08-02 17:25:07

标签: scope symbol-tables

我现在正在学习编程语言课程的原则,但我不能为我的生活弄清楚这一点。这不仅仅是一个普通的概念问题。

在我们班上,我们讨论过静态链和显示。我想我理解为什么我们需要这些。否则,当我们有嵌套方法时,我们无法弄清楚当我们有嵌套方法时我们正在谈论的变量。

我的教授也谈到了一个符号表。我的问题是用于的符号表是什么?它与静态链有什么关系?

我会给出一些背景(如果我错了,请纠正我)。


(我将定义一些内容,以便更容易解释)

假设我们有这段代码:

main(){
    int i;
    int j;
    int k;
    a(){
        int i;
        int j;
        innerA(){
            int i = 5;
            print(i);
            print(j);
            print(k);
        }
    }

    b(){
        ...
    }
    ...
}

这个堆栈:

| innerA  |
| a       |
| b       |
| main    |
-----------              

静态链的快速描述作为复习。

静态链用于查找在内部函数内重新定义变量时应使用的变量。在上面显示的堆栈中,每个帧都有一个指向包含它的方法的指针。所以:

| innerA  | \\ pointer to a
| a       | \\ pointer to main
| b       | \\ pointer to main
| main    | \\ pointer to global variables
-----------        

(假设静态作用域,对于动态作用域,我认为每个堆栈帧都只指向它下面的那个)

我认为当我们在print(<something>)方法中执行innerA时,会发生这种情况:

currentStackframe = innerAStackFrame;
while(true){ 
    if(<something> is declared in currentStackFrame)
        print(<something>);
        break;
    else{
        currentStackFrame = currentStackFrame.containedIn();
    }
}

快速复习符号表

我不确定符号表的用途。但这就是它的样子:

Index is has value, 
Value is reference.
 __
|  |
|--|                        --------------------------------------------------
|  | --------------------> | link to next | name | type | scope level | other |
|--|                        --------------------------------------------------
|  |                              |
|--|                ---------------
|  |                |    
|--|                |             --------------------------------------------------
|  |                 ------->    | link to next | name | type | scope level | other |
|--|                              --------------------------------------------------
|  |
|--|
  • 链接到下一个 - 如果多个东西具有相同的哈希值,则这是一个链接
  • name - 元素的名称(示例:i,j,a,int)
  • 类型 - 事物是什么(例如:变量,函数,参数)
  • 范围级别 - 不是100%确定如何定义。我觉得:
    • 0将内置
    • 1将是全局
    • 2将是主要方法
    • 3将是a和b
    • 4将是innerA

重述我的问题:

  • 用于的符号表是什么?
  • 它与静态链有什么关系?
  • 为什么我们需要静态链,因为范围信息在符号表中。

2 个答案:

答案 0 :(得分:5)

请注意,“符号表”可能意味着两个不同的东西:它可能意味着编译器用来确定变量的哪个别名具有范围的内部结构,或者它可能意味着库导出到其的符号列表用户在加载时。在这里,您使用的是前一个定义。

符号表用于确定用户使用某个名称时用户所指的内存地址。当你说“x”时,你想要“x”的别名吗?

您需要同时保留静态链和符号表的原因是:当编译器需要确定哪些变量在某个范围内可见时,它需要“取消屏蔽”先前在内部范围中别名的变量。例如,当从innerA移回a时,变量i会更改其内存地址。从amain再次发生同样的事情。如果编译器没有保留静态链,则必须遍历整个符号表。如果你有很多名字,那就太贵了。对于静态链,编译器只查看当前级别,删除其中包含的每个变量的最后一个定义,然后跟随一个范围的链接。另一方面,如果您没有符号表,那么不在本地范围内的每个变量访问都会使编译器必须遍历静态链。

总结一下,您可以从静态链重构符号表,反之亦然。但是你真的希望两者都能快速完成常见的操作。如果缺少符号表,则编译将花费更长时间,因为每个非本地范围的变量访问都需要爬上静态链。如果缺少静态链,则编译将花费更长时间,因为保留范围将需要遍历符号表以删除现在已解散的条目。

顺便说一下,如果你还没有使用Michael Scott的编程语言语用学,你应该看看它。到目前为止,这是我见过的关于这个主题的最好的教科书。

答案 1 :(得分:1)

这显然是指某些特定的类实现,为了理解它,我强烈建议与与该类相关的人交谈。

符号表将源代码标识符转换为编译器可以使用的内容。它保留了必要的描述。它往往在整个编译过程中使用。你提到的“类型”看起来像是用于解析,并且无疑会有更多的条目(在“其他”中)用于后期阶段。

很难知道它与静态链的关系,或者为什么需要它们,因为你甚至不知道“范围级别”是什么。但请注意,a()b()可能都有变量i,您似乎认为它们具有相同的范围级别,因此您需要一些区分它们。

此外,静态链通常是优化,因此编译器知道要接受哪些符号表条目。如果没有静态链,编译器必须进行一些查找以拒绝binnerA中遇到的内容中的条目。

为了获得更多有用的东西,你将不得不更多地解释正在发生的事情(我强烈建议与教练或助教或其他人交谈)并且可能有更具体的问题。