对于我的课程,我必须为一小部分 Python 编写编译器:
- 这种语言有一种方法
- 没有函数,所以我只处理一个词法范围
这个 Python 子集将被翻译成 Java 字节码。我已经完成了词法分析和解析树(使用 lex 和 yacc)。我被困在代码生成上。
我们正在使用Gnoloo
堆栈机器语言进行代码生成。
问题是我不知道如何存储变量。我知道我必须使用符号表,但我不知道如何填充它。
我必须存储变量的值吗?
如果代码有x = 2
,符号表是否必须有一个字段?
如何存储堆栈机器的变量。
对于我的课程,我必须为一小部分 Python 编写编译器:
这个 Python 子集将被翻译成 Java 字节码。我已经完成了词法分析和解析树(使用 lex 和 yacc)。我被困在代码生成上。
我们正在使用Gnoloo
堆栈机器语言进行代码生成。
问题是我不知道如何存储变量。我知道我必须使用符号表,但我不知道如何填充它。
我必须存储变量的值吗?
如果代码有x = 2
,符号表是否必须有一个字段?
如何存储堆栈机器的变量。
你还没有说你使用的是什么语言,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;
}
基本上就是这样。为了完成这项工作,还有很多工作要做。如果您还有其他问题,请随时提问。