首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译器如何处理符号表中的默认值

问编译器如何处理符号表中的默认值
EN

Stack Overflow用户
提问于 2012-04-16 04:00:19
回答 2查看 816关注 0票数 2

某些编程语言允许参数在函数调用中具有默认值,而在struct中的属性具有默认值。与python或javascript一样,当我们忽略函数调用中的一些参数时,函数中的默认值将被替换(同样,struct在属性中也可以具有默认值)。那么编译器实际上是如何处理这个问题的呢?特别是在符号表中?我认为为指向默认值的指针添加一个额外的属性,我也想在运行时推到堆栈上的默认值?如果我是对的,请告诉我。谢谢。

更新:在这里我指的是默认值,下面的程序参数b有默认值0。

代码语言:javascript
复制
def foo(a, b=0):
    return a+b
print foo(1)
print foo(1, 1)

我们将得到结果0和1。那么,编译器是如何在运行时或编译时处理这个问题的呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-16 18:44:23

当计算函数调用的参数列表时,代码生成器可以通过将该列表与存储在符号表中的函数签名进行比较来判断缺少哪些参数。一旦识别了需要替换哪个参数,就只需将默认值放入参数寄存器(或堆栈框架)。如果您处理的是OO语言,而形式参数是一个对象,则可以将0 (NULL)推入堆栈的下一个单词。如果参数是内置原语,您将推送语言指定的默认值。

当然,编译器可能会有所不同,但在简单的编译器中,并不一定需要将默认值关联到符号表中。首先,让我们清楚地看到符号表记录了所有变量声明。您必须存储有关这些声明的信息(例如,类、方法、类型、行、char等),但是当只有几种类型时,当然不需要记录每个变量的默认值,因此只有少数可能的默认值。

有些语言(Java/C++)指定具有未初始化对象属性的类的默认值为NULL。在实现类似的东西时,当代码生成器创建类构造函数时,它将确保生成将映射到该属性的对象内存中的0的代码(假设所有内容都是基于指针的)。当您去生成构造函数,并在类属性列表( AST节点)上迭代时,如果该属性没有初始化表达式,则调用一个方法来执行默认操作。

代码语言:javascript
复制
private void genConstructor(int classId) {

     //allocate new object

     codeGen.write("li $a0, "+classId); 
     codeGen.write("jal Runtime.newObject");

     //call parent constructor

     codeGen.write("move $a0, $v0"); 
     codeGen.write("jal ParentInit");

     //initialize the attributes this class has declared

     for(Attributes a: getAttributes(classId)) {

        //provide default value
        if(a.getInitExpr() == null)
            doDefault(a.getType(), a.getNum());
        else
            doInit(a.getInitExpr(), a.getNum());
     }
}

// An 'Int' default value is 1, everything else is 0 (Objects included)
// $t0 has the object address
// attributes start at the 5th word of each object 
private void doDefault(String type, int attrNum) {
     switch(type) {
          case "Int": {
                codeGen.write("sw $one, "+(5+attrNum)+"($t0)");
          }
          default: {
                codeGen.write("sw $zero, "+(5+attrNum)+"($t0)");
          }
     }
}

更新:

我想知道编译器如何处理程序员设置的默认值,而不是"class“或"type”的“默认”值。

我假设您说的是类似于C++构造函数中的默认args的内容。在这种情况下,正如Ira所提到的,在符号表记录中创建一个字段听起来是最简单的方法。在为缺少的参数生成代码时,请在表中查找默认值。

票数 1
EN

Stack Overflow用户

发布于 2012-04-16 05:44:37

无论您如何做,都必须将默认值与特定的标识符关联起来。

参数列表和结构成员形成小名称空间,编译器通常通过为这些名称空间构建符号表和更大的符号表来跟踪名称空间的关系。

由于编译器通常已经在这些小名称空间中有符号表条目,将其他信息与符号相关联(例如,任何类型信息),所以这是记录它的一个非常自然的地方。

有一个问题,究竟要记录什么为初始值。一个简单的方法就是记录一个指向AST的指针,该指针表示初始/默认值。此外,还必须记录评估该表达式的上下文(例如“环境”)。这个上下文通常是隐式的,因为它通常与定义了结构/参数的上下文相同,并且信息存储在更大的符号表中,该符号表将所有内容粘合在一起。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10168567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档