【问题标题】:How to store variables from Symbol Table Compilers如何存储符号表编译器中的变量
【发布时间】:2016-06-07 20:31:51
【问题描述】:

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

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

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

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

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

我必须存储变量的值吗?

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

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

【问题讨论】:

  • 不清楚你在问什么。从您接受的答案来看,您是在询问如何构建编译时符号表,在这种情况下,堆栈机器与问题完全无关,并且您不会停留在代码生成上,而是停留在符号表上建筑。您的问题的措辞方式似乎是关于如何通过代码生成器将变量存储到堆​​栈机器的目标代码中。

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


【解决方案1】:

你还没有说你使用的是什么语言,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; 
}

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

【讨论】:

  • 谢谢你!我正在使用java。我的问题是我必须为堆栈机器生成代码。假设源代码有这两个语句:x = 2 *3 和后来的 y = 2 + x。我不知道如何跟踪我加载 x 的位置。我该怎么做?。
  • 你可以使用哈希映射或字典。它与我为 C++ 描述的基本相同。在此处阅读有关 stackoverflow.com/questions/267312/… 哈希映射和字典的更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
  • 1970-01-01
  • 2016-10-09
  • 2021-07-18
  • 1970-01-01
  • 2011-06-11
相关资源
最近更新 更多