对于我的课程,我必须为Python的一小部分编写一个编译器:
此Python子集将转换为Java字节码。 我已经完成了词法分析和解析树(使用lex和yacc)。 我坚持代码生成。
我们正在使用Gnoloo
代码生成,这是一种堆栈机器语言。
问题是我不知道如何存储变量。我知道我必须使用符号表,但我不知道如何填写它。
我是否必须存储变量的值?
如果代码有x = 2
,symtable是否必须有一个字段?
如何存储堆栈计算机的变量。
答案 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;
}
基本上就是这样。要完成这项工作,还有很多工作要做。如果您还有其他问题,请随时提出。