1

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

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

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

我们正在使用Gnoloo堆栈机器语言进行代码生成。

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

我必须存储变量的值吗?

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

如何存储堆栈机器的变量。

4

1 回答 1

0

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

C++:

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

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; 
}

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

于 2016-06-08T09:26:31.263 回答