-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsemantic.h
298 lines (231 loc) · 7.27 KB
/
semantic.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
#ifndef SEMANTIC_H
#define SEMANTIC_H
#include "tree.h"
//哈希表大小
#define TABLE_SIZE 100
#define INT_FLOAT_SIZE 4
extern int numHashSearch;
extern int nrTmpVar;
extern int nrLabel;
//类型定义:基本类型、数组类型、结构体
struct Type
{
enum {
BASIC,
ARRAY,
STRUCTURE
}kind;//类别
union
{
int basicType;//int or float,在tree.h 的 treeVal中定义
struct Array* array;//数组
struct Structure* structure;//结构体
}info;//具体类型信息和kind一一对应
};
//类型列表:用于描述结构体成员、函数形参列表
struct FieldList
{
char* name;//结构体成员名字,如果是函数形参就无所谓
int line;//第一次出现的行
struct Type* type;//类型
struct FieldList* next;//链表指针
};
//函数类型
struct Func
{
char* name;//函数名
struct Type* retType;//返回值类型
struct FieldList* params;//形参列表,参数的name并不重要
struct Func* next;//在表项中的下一个
int varSpace;//变量、临时变量空间
int nrParams;//参数个数
};
//数组类型
struct Array
{
//元素类型
struct Type* elem;
//元素数量
int numElem;
//单个元素所占空间
int elemWidth;
};
//变量表项
struct Variable
{
char* name;//变量名
int isParam;//是否为形式参数
struct Type* varType;
int firstAppearanceLine;//第一次出现的行号
struct Variable* next;
int offsetToEbp;
};
//结构体表项:仅包含有名结构体
struct Structure
{
char* name;
struct FieldList* structureInfo;//和变量valType相同类型是为了便于之后类型的比较
struct Structure* next;//这个next指针只在结构体表项中有用
};
//用于判断FL*中是否有重复名字的hashset表项
struct NameNode
{
char* name;
struct NameNode*next;
};
struct Operand
{
//操作数类型
enum{
OPERAND_LABEL,//跳转标号
OPERAND_FUNC,//函数名
OPEARND_VAR,//普通局部变量名
OPEARND_TMP_VAR,//中间代码临时变量 tmpNo
OPEARND_CONSTANT,//常数INT
OPEARND_ADDR//地址,其实还是用一个临时变量存储地址 tmpNo
}kind;
union{
int laeblNo;
char* funcName;
char* varName;
int tmpVarNo;//临时变量ID
int constantVal;
}info;
};
//中间代码
struct InterCode
{
enum{
IC_LABEL_DEF,
IC_FUNC_DEF,
IC_ASSIGN,
IC_PLUS,
IC_SUB,
IC_MUL,
IC_DIV,
IC_GET_ADDR,
IC_GET_VALUE,
IC_WRITE_TO_ADDR,
IC_GOTO,
IC_RELOP_GOTO,
IC_RETURN,
IC_DEC,
IC_ARG,
IC_CALL,
IC_PARAM,
IC_READ,
IC_WRITE
}kind;
struct Operand* operands[3];//最多3个操作数
// int Relop;//具体表明relop类型
enum{
LT,//<
GT,//>
LEQ,//<=
GEQ,//>=
NEQ,//!=
EQ//==
}relop;
int allocSize;//用于DEC
int numOperands;//操作数数量
struct InterCode* next;
struct InterCode* prev;
};
//函数实参链表节点
struct ArgNode
{
struct Operand* op;
struct ArgNode* next;
struct ArgNode* prev;
};
//记录临时变量以及偏移的数据结构
struct Pair
{
int tmpNo;
int offset;
struct Pair* next;
};
struct NameNode** getNameHashSet(int sz);
int nameSetContains(struct NameNode** set,int sz,char* name);
void insertIntoSet(struct NameNode** set,int sz,char*name);
void freeSet(struct NameNode** set,int sz);
//根据name查表
struct Func* searchFuncTable(char*name);
struct Structure* searchStructureTable(char*name);
struct Variable* searchVariableTable(char*name);
struct Pair* searchPairTable(int tmpNo);
//插入表项,名字在结构体中已经有了
void insertFuncTable(struct Func* func);
void insertStructureTable(struct Structure*structure);
void insertVariableTable(struct Variable*variable);
void insertPairTable(struct Pair* pairPtr);
//根据一个只有一个节点的创建出一个变量符号,用于插入变量表
struct Variable* getVarPtr(struct FieldList*FL,int line);
//打印类型信息,便于调试
void printType(struct Type*,int nrSpace);
//打印一系列域
void printFieldList(struct FieldList* ptr,int nrSpace);
//打印函数头
void printFuncDec(struct Func* funcPtr,int nrSpace);
//计算类型所占的空间
int calculateWidth(struct Type* typePtr);
//根据name取得哈希值,得到table表项地址
unsigned hash(char*name,int sz);
void printError(int type,int line,char* msg);
//检查是否有相同的名字
void checkNoDuplicateName(struct FieldList*FL);
//判断两个类型是不是一致
int checkTypeSame(struct Type *typePtr1,struct Type *typePtr2);
//判断参数列表是否符合
int checkFieldListSame(struct FieldList*FL1,struct FieldList*FL2);
//反转数组,并且填写width
void reverseArray(struct Type * arrayType);
void handleProgram(struct TreeNode* r);
void handleExtDef(struct TreeNode* r);
void handleExtDefList(struct TreeNode* r);
struct Type* handleSpecifier(struct TreeNode* r);
struct FieldList* handleExtDecList(struct TreeNode* r,struct Type* typrPtr);
struct Type* handleStructSpecifier(struct TreeNode* r);
char* handleTag(struct TreeNode* r);
char* handleOptTag(struct TreeNode* r);
struct FieldList* handleDefList(struct TreeNode* r,int isInStruc);
struct FieldList* handleDef(struct TreeNode* r,int isInStruc);
struct FieldList* handleDecList(struct TreeNode* r,struct Type * typtPtr,int isInStruc);
struct FieldList* handleDec(struct TreeNode* r,struct Type * typtPtr,int isInStruc);
struct Type* handleVarDec(struct TreeNode* r,struct Type * typtPtr,char**namePtr);
struct FieldList* handleVarDec2(struct TreeNode* r,struct Type * typePtr);
struct Func* handleFuncDec(struct TreeNode* r,struct Type * typePtr);
struct FieldList* handleVarList(struct TreeNode* r);
struct FieldList* handleParamDec(struct TreeNode* r);
void handleCompst(struct TreeNode* r,struct Type * typePtr);
void handleStmtList(struct TreeNode* r,struct Type * typePtr);
void handleStmt(struct TreeNode* r,struct Type * typePtr);
struct Type * handleExp(struct TreeNode* r, struct Operand* place, int needGetVal);
struct FieldList* handleArgs(struct TreeNode* r, struct ArgNode** argList);
struct Type * translateCond(struct TreeNode* r, struct Operand* labelTrue, struct Operand* labelFalse);
void appendInterCodeToList(struct InterCode* ICNodePtr);
//创建一个ICNode并且分配
struct InterCode* newICNode(int numOperands);
//创建一个Oprand
struct Operand* newOperand();
//获取新的跳转标号
struct Operand* getNewLabel();
//获取新的临时变量
// struct Operand* getNewTmpVar();
//获取下一个临时变量标号
int getNextTmpNo();
//打印中间代码
void printInterCodeList(FILE* fd);
//根据操作数类型打印,不输出多余空白
void printOperand(FILE* fd, struct Operand* op);
void printICPtr(FILE* fd, struct InterCode * curPtr);
//向函数表插入read和write初始化
void initReadAndWrite();
int min(int a,int b);
//将中间代码翻译为机器码
void translateToMachineCode(FILE *fd);
void printDataReadWrite(FILE *fd);
void translateInterCodeToMachine(FILE *fd, struct InterCode* ICptr);
void subSp(FILE *fd, int sz);
void addSp(FILE *fd, int sz);
#endif