如何存储来自 Symbol Table 编译器的变量

How to store variables from Symbol Table Compilers

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

这个 Python 子集将被翻译成 Java 字节码。 我已经完成了词法分析和解析树(使用 lex 和 yacc)。 我坚持代码生成。

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

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

我必须存储变量的值吗?

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

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

你还没有说你使用的是什么语言,C++ 还是 C。

C++:

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

C:

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

注意: 在 C 中存在内存分配问题,该问题是名称内存分配,您通常在 Lex 中这样做(幸运的是有 strdup 函数用于那个)。`

我不认为代码示例对于 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; 
}

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