如何存储符号表编译器中的变量

时间:2016-06-07 20:31:51

标签: compiler-construction code-generation yacc symbol-table stack-machine

对于我的课程,我必须为Python的一小部分编写一个编译器:

  • 这种语言有一种方法
  • 没有功能,所以我只处理一个词法范围

此Python子集将转换为Java字节码。 我已经完成了词法分析和解析树(使用lex和yacc)。 我坚持代码生成。

我们正在使用Gnoloo代码生成,这是一种堆栈机器语言。

问题是我不知道如何存储变量。我知道我必须使用符号表,但我不知道如何填写它。

我是否必须存储变量的值?

如果代码有x = 2,symtable是否必须有一个字段?

如何存储堆栈计算机的变量。

1 个答案:

答案 0 :(得分:0)

您还没有说过您正在使用的语言,C ++或C.

C ++:

用C ++管理变量相当容易,你基本上会有一个映射std::map<string,int> symbol_table;(假设你的变量是整数)。第一次使用变量时,您会将其插入到地图中,每次声明时都会更新地图中的值。这在C ++中运行得非常快。当然,您可以在Yacc解析器中添加/更新这些值。

<强> C:

在C情况下有点棘手,没有地图!所以你需要做的是创建二进制搜索树。该树中的节点将包含char数组 - 表示变量名,并且还会有一些值。当您第一次获得某个变量时需要将其添加到BST中,当您更改值时,必须首先找到它然后更新该节点中的值。

注意:在C中存在内存分配问题,这个问题是名称内存分配,你通常在Lex中这样做(幸运的是有strdup功能)。 / p>

我认为C ++不需要代码示例,但我会在C中给你举例。

Yacc 开头:

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include "tree.h" /* All methods I mentioned above must be implemented */

    node *map = NULL; /* You would insert every variable here */

%}

<强>联:

%union {

    char *s; /* We will allocate memory in Lex */
    int value; /* We will update this value in Yacc */
};

<强>莱克斯:

[a-zA-Z_][a-zA-Z0-9_]* { 

    yylval.s = strdup(yytext);
    if(yylval.s == NULL){

        fprintf(stderr,"Unable to allocate memory for variable name.\n");
        exit(EXIT_FAILURE);
    }

    return id_token; 
}

基本上就是这样。要完成这项工作,还有很多工作要做。如果您还有其他问题,请随时提出。