【编译系统02】编译器 - 语义分析器(semantic)的简单设计思路(变量类与变量表)

当我们分析到 "int n;",说明其已经定义了一个变量,之后又遇到一个 "n=3",我们从哪里去找这个n并且赋值呢?

答案是:通过我们定义的 变量表(Table) 中查找。

其实,这变量声明定义与变量赋值一系列动作,都是由语义分析器负责的。

1. 当扫描到一个声明语句,比如 "string x;" 时:

  1)在语法分析中,当检测到 string <type>,其会将 (string,x)保存在(tVar.type,tVar.name)。

  2)调用 Table.addVar ,该函数会生成一个新的 变量对象(var_record),然后添加进 map<> 中。

  3)当之后遇到  x = ''hello world"时,其会调用 Table.getVar(x),然后将其赋值为 "hello world",这样就实现了赋值。

2. var_record类定义如下():

 1 class var_record {
 2 public:
 3     symbol type; // 类型
 4     string name; // 名称
 5      
 6     // 变量值
 7     int intVal; // 整数
 8     string strVal; // 字符串
 9     
10     
11     
12     int localAddr; // 局部变量相对于ebp指针的地址,或者临时string的索引地址
13     var_record(); // 默认构造函数
14     void init(symbol dec_type, string dec_name); // 声明初始化函数
15     var_record(const var_record& v);//拷贝构造函数
16     ~var_record();
17 };

  1)变量值一开始打算使用 union{int,string} 来实现,但在c++union作为类,存在权限访问冲突(暂时没解决),因此就分开来实现。

3. Table 变量表的定义如下:

 1 class Table {
 2     map<string, var_record*> var_map; // 变量声明列表
 3 public:
 4     Table(); // 构造函数
 5     void addVar(); // 添加变量声明记录,默认使用tvar
 6     
 7     //  该函数估计暂时用不到
 8     //void addVar(var_record*v); // 添加变量声明记录,重载(赋值已声明的变量后则要实现重载)
 9     var_record * getVar(string name); // 获取已经记录的变量名
10 };

  1)Table类核心就是围绕map<>结构来建立

  2)两个方法,一个是添加变量,另一个是找到变量。

4. 简单的测试代码(模拟"遇到字符串与数字的定义赋值与输出")

 1 #include "pch.h"
 2 #include "semantic.h"
 3 #include <iostream>
 4 #include <string>
 5 #include <map>
 6 using namespace std;
 7 
 8 map<string, int> a;
 9 
10 /*
11      模拟变量声明过程
12      int a;
13      a = 3;
14 */
15 
16 int main() {
17     // 建立一个全局变量表
18     
19     Table VarTable;
20         
21     // int a;
22     tVar.type = NUM; // 变量类型是 NUM(INT) 数字类型
23     tVar.name = "a";    // 添加变量名
24     VarTable.addVar(); // 其默认将tVar 添加进表中
25 
26     // a = 3;
27     var_record * a =  VarTable.getVar("a"); // 拿出变量a
28     a->intVal = 3; // 将a 赋值为 3
29     
30     // 输出结果
31     // cout << a << endl
32     cout << VarTable.getVar("a")->intVal << endl;
33     
34 
35     // string x;
36     tVar.type = STR; // 变量类型是 NUM(INT) 数字类型
37     tVar.name = "x";    // 添加变量名
38     VarTable.addVar(); // 其默认将tVar 添加进表中
39 
40     // x= "hello world";
41     var_record * x = VarTable.getVar("x"); // 拿出变量x
42     x->strVal = "hello world"; // 将a 赋值为 3
43     int tt =4;
44 
45     cout << VarTable.getVar("x")->strVal << endl;
46     return 0;
47 }
View Code

测试结果符合要求。

猜你喜欢

转载自www.cnblogs.com/onetrainee/p/11962123.html