如何存储来自 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;
}
基本上就是这样。要完成这项工作,还有很多工作要做。如果您有任何其他问题,请随时提问。
对于我的 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;
}
基本上就是这样。要完成这项工作,还有很多工作要做。如果您有任何其他问题,请随时提问。