1 #include <stdio.h>
2 #include <string.h>
3 #include <malloc.h>
4 typedef struct _array_description
5 {
6 int array_size;//代表当前层的最高索引,即上界
7 struct _array_description* next;//代表下一级
8 }array_description,*parray_description;
9 //注意我们把最低层的放在最前面,这样有利于下标的处理
10
11 typedef struct _basic_type_pattern
12 {
13 char* faction_name;//代表类型名字
14 int pointer_layer;//代表指针的级数,我们限制为8级,即只占一个字节,其他三个字节以后再使用,先留着
15 parray_description array_layer;//这里是数组描述,以链表串起多级数组
16 char* pattern_name;//代表分量的类型
17 }basic_type_pattern,*pbasic_type_pattern;
18 typedef struct _composition_list//这个是复合结构的产生式,包括联合、结构、函数
19 {
20 pbasic_type_pattern current;//当前的分量
21 struct _composition_list* next;//下一个分量的指针
22 }composition_list,*pcomposition_list;
23 typedef struct _type_description
24 {
25 pcomposition_list current_gen_list;//代表当前的产生式的体,也是函数参数的列表
26 int type_type;//1为函数,2为结构,3为联合,4为基础类型
27 char* name;//当前类型的名字
28 void* function_zone;//这个代表了函数相关的域,其中有三个域,类型链表,变量链表,动作链表
29 //这三个域都是需要后面定义的类型,所以我们目前把他作为一个void类型的指针来处理
30 int return_pointer ;//代表返回值的指针层数
31 char* return_name;//代表返回值的类型
32 }type_description,*ptype_description;//类型声明的体
33 typedef struct _type_avl_tree
34 {
35 struct _type_description* current_type_body;//产生体链表的头节点
36 //因为有交叉引用。。。
37 int tree_depth;//当前树的高度,这个域是用来计算平衡因子的
38 struct _type_avl_tree* left;//左子树
39 struct _type_avl_tree* right;//右子树
40 }type_avl_tree,*ptype_avl_tree;//这里是整个的类型avl树
41
42 ptype_avl_tree type_tree_head=NULL;//先初始化为空
43 ptype_avl_tree tree_node_stack[100];//这个栈是为了插入和删除用的,以及用来平衡树高
44 //前面的结构都是对应于类型符号表的,采取的是avl
45 //下面开始介绍变量符号表,采取的是hash
46 //对于变量符号表,我们首先需要考虑一个变量所包括的域,其实这些域在定义类型符号表的时候都使用过了
47 //即basic_type_pattern这个结构体,已经有我们所需要的所有的东西,对于hash值一样的变量,我们通过一个链表串接起来
48 //而这个链表结构我们现在都有了
49 //现在我们唯一需要的就是hash表的空间以及hash的方法,这里我们分配400个表项,因为397刚好是质数
50 //hash函数我们直接采用累加法,最简单的
51 typedef struct _var_hash_node
52 {
53 char* var_name;
54 int pointer_layer;//代表指针的级数,我们限制为8级,即只占一个字节,其他三个字节以后再使用,先留着
55 parray_description array_layer;//这里是数组描述,以链表串起多级数组
56 struct _type_description* var_type;//代表变量的类型
57 }var_hash_node,*pvar_hash_node;
58 typedef struct _var_hash_chain
59 {
60 pvar_hash_node current_var;
61 struct _var_hash_node next_var;
62 }var_hash_chain,*pvar_hash_chain;
63 pvar_hash_chain var_hash_table[400];//注意我们要在后面把这个全都初始化为空
64 void generation_free(void* generation_body)//释放生成体链表所占的空间
65 {
66 pcomposition_list temp_com_list_before,temp_com_list_after;
67 pbasic_type_pattern temp_basic_pattern;
68 parray_description temp_array_layer_before,temp_array_layer_after;
69 temp_com_list_before=(pcomposition_list)generation_list;//转换一下指针
70 while(temp_com_list_before!=NULL)
71 {
72 temp_com_list_after=temp_com_list_before->next;
73 temp_basic_pattern=temp_com_list_before->current;
74 free(temp_basic_pattern->faction_name);
75 temp_array_layer_before=temp_basic_pattern->array_layer;
76 while(temp_array_layer_before!=NULL)
77 {
78 temp_array_layer_after=temp_array_layer_before->next;
79 free(temp_array_layer_before);
80 temp_array_layer_before=temp_array_layer_after;
81 }//释放所有的数组空间
82 free(temp_com_list_before);
83 temp_com_list_before=temp_com_list_after;
84 }//释放所有的分量
85 }//现在所有的都释放完成了
86
87
88
89 void insert_var_hash(pvar_hash_node new_var)//在hash表中插入一个表项
90 {
91 int string_hash;
92 int for_i;
93 char* current_name;
94 pvar_hash_chain temp_link;//用来串接链表
95 current_name=new_var->var_name;
96 for_i=0;
97 string_hash=0;
98 while(current_name[for_i]!='\0')
99 {
100 string_hash+=current_name[for_i];
101 }
102 string_hash=string_hash%397;//取模
103 temp_link=malloc(sizeof(struct _var_hash_chain));
104 temp_link->next_var=var_hash_table[string_hash];
105 temp_link->current_var=new_var;
106 var_hash_table[string_hash]=temp_link;
107 }
108 void delete_var_hash(char* current_name)//这里其实我们不管具体的name,因为,删除的时候我们是一起删除的
109 {
110 int string_hash;
111 int for_i;
112 pvar_hash_chain temp_link;//用来串接链表
113 for_i=0;
114 string_hash=0;
115 while(current_name[for_i]!='\0')
116 {
117 string_hash+=current_name[for_i];
118 }
119 string_hash=string_hash%397;//取模
120 temp_link=var_hash_table[string_hash]->next_var;
121 free(var_hash_table[string_hash]);
122 var_hash_table[string_hash]=temp_link;
123 }
124
125 pvar_hash_node search_var_hash(char* current_name)//通过名字来查找变量符号表
126 {
127 int string_hash;
128 int for_i;
129 pbasic_type_pattern result;
130 pvar_hash_node temp_link;//用来串接链表
131 for_i=0;
132 string_hash=0;
133 while(current_name[for_i]!='\0')
134 {
135 string_hash+=current_name[for_i];
136 }
137 string_hash=string_hash%397;//取模
138 temp_link=var_hash_table[string_hash];
139 while(temp_link!=NULL)
140 {
141 result=temp_link->current_var;
142 if(strcmp(result,current_name)==0)
143 {
144 return result;
145 }
146 else
147 {
148 temp_link=temp_link->next_var;
149 }
150 }
151 return NULL;
152 }
153
154 void modify_node_depth(ptype_avl_tree current)//修改节点的高度
155 //由于这个操作需要做很多判断,不修改成函数的话,其他函数将会很长,所以做成一个函数
156 {
157 if(current->left!=NULL)
158 {
159 if(current->right!=NULL)
160 {
161 current->tree_depth=1+(current->left->tree_depth+current->right->tree_depth+1)/2;
162 }
163 else
164 {
165 current->tree_depth=1+current->left->tree_depth;
166 }
167 }
168 else
169 {
170 if(current->right!=NULL)
171 {
172 current->tree_depth=1+current->right->tree_depth;
173 }
174 else
175 {
176 current->tree_depth=1;
177 }
178 }
179 }
180 void avl_rotate_left( ptype_avl_tree father, ptype_avl_tree current)//将avl树左旋
181 {
182 ptype_avl_tree temp_node_one,temp_node_two,temp_node_three;//这命名碉堡了有木有
183 if(father==NULL)//如果旋转的是头节点
184 {
185 temp_node_one=current->right;
186 type_tree_head=current->right;//修改头节点
187 temp_node_two=temp_node_one->left;
188 current->right=temp_node_two;
189 type_tree_head->left=current;
190 //至此节点之间的关系修改完毕
191 //现在开始修改两个节点的高度
192 modify_node_depth(current);//修改高度有先后顺序的,先修改下面的,后修改上面的
193 modify_node_depth(temp_node_one)
194 }
195 else
196 {
197 temp_node_one=current->right;
198 current->right=temp_node_one->left;
199 temp_node_one->left=current;
200 if(father->left==current)
201 {
202 father->left=temp_node_one;
203 }
204 else
205 {
206 father->right=temp_node_one;
207 }
208 modify_node_depth(current);
209 modify_node_depth(temp_node_one);
210 mpdify_node_depth(father);
211 //这里需要修改三个节点
212 }
213 }
214 void avl_rotate_right(ptype_avl_tree father, ptype_avl_tree current)//右旋节点
215 {
216 ptype_avl_tree temp_node_one,temp_node_two,temp_node_three;//这命名碉堡了有木有
217 if(father==NULL)//如果旋转的是头节点
218 {
219 temp_node_one=current->left;
220 type_tree_head=current->left;//修改头节点
221 temp_node_two=temp_node_one->right;
222 current->left=temp_node_two;
223 type_tree_head->right=current;
224 //至此节点之间的关系修改完毕
225 //现在开始修改两个节点的高度
226 modify_node_depth(current);//修改高度有先后顺序的,先修改下面的,后修改上面的
227 modify_node_depth(temp_node_one)
228 }
229 else
230 {
231 temp_node_one=current->left;
232 current->left=temp_node_one->right;
233 temp_node_one->right=current;
234 if(father->right==current)
235 {
236 father->right=temp_node_one;
237 }
238 else
239 {
240 father->left=temp_node_one;
241 }
242 modify_node_depth(current);
243 modify_node_depth(temp_node_one);
244 mpdify_node_depth(father);
245 //这里需要修改三个节点
246 }
247 }
248
249 void insert_avl_node(ptype_description new_type_node)//插入一个新的节点
250 {
251 ptype_avl_tree temp_node_one,temp_node_two,temp_node_three,new_node;
252 ptype_description temp_type_description;
253 int stack_pointer=0;
254 int compare_result=0;//这个变量会被复用,在插入时作为字符串比较的结果,在平衡时作为高度差。
255 int original_depth;//这个用来记录节点原来的高度
256 tree_node_stack[0]=NULL;//哨兵节点,在旋转的时候有用
257 new_node=malloc(sizeof(struct _type_avl_tree));
258 new_node->current_gen_list=new_type_node;
259 new_node->left=NULL;
260 new_node->right=NULL;
261 new_node->tree_depth=1;
262 if(type_tree_head==NULL)
263 {
264 type_tree_head=new_node;
265 return 0;
266 }
267 else
268 {
269 temp_node_one=type_tree_head;
270 while(temp_node_one!=NULL)
271 {
272 stack_pointer++;
273 tree_node_stack[stack_pointer]=temp_node_one;
274 temp_type_description=(ptype_description)temp_node_one->current_type_body;
275 compare_result=strcmp(new_type_node->name,temp_type_description->name);
276 if(compare_result<0)
277 {
278 temp_node_one=temp_node_one->left;
279 }
280 else
281 {
282 temp_node_one=temp_node_one->right;
283 }
284 }//这个栈记录了插入所经过的路径
285 temp_node_one=tree_node_stack[stack_pointer];
286 if(compare_result<0)
287 {
288 temp_node_one->left=new_node;
289 }
290 else
291 {
292 temp_node_one->right=new_node;
293 }
294 //现在节点关系已经建立了,开始平衡树高度了
295 while(stack_pointer>0)//遍历整个栈,来寻找需要平衡的节点
296 //注意,这里跳出循环的条件是,某个节点在修改后高度没有改变,这样就没有必要再去修改了
297 //或者启用了平衡操作,启用平衡操作之后可以确保高度没有改变,因此可以退出
298 {
299 temp_node_one=tree_node_stack[stack_pointer];
300 original_depth=temp_node_one->tree_depth;
301 modify_tree_depth(temp_node_one);
302 if(original_depth==temp_node_one->tree_depth)
303 {
304 return 0;
305 }
306 else
307 {
308 compare_result=temp_node_one->left->tree_depth-temp_node_one->right->tree_depth;
309 if(compare_result==2)//如果左边比右边高2
310 {
311 //这个时候需要考虑是要进行两次旋转还是一次旋转
312 if(tree_node_stack[stack_pointer+1]->right==tree_node_stack[stack_pointer+2])
313 //这种情况我们需要做两次旋转
314 {
315 avl_rotate_left(tree_node_stack[stack_pointer],tree_node_stack[stack_pointer+1]);
316 }
317 avl_rotate_right(tree_node_stack[stack_pointer-1],tree_node_stack[stack_pointer]);
318 //第二次旋转
319 return 0;
320 }
321 else
322 {
323 if(compare_result==-2)
324 {
325 if(tree_node_stack[stack_pointer+1]->left==tree_node_stack[stack_pointer+2])
326 {
327 avl_rotate_right(tree_node_stack[stack_pointer],tree_node_stack[stack_pointer+1]);
328 }
329 avl_rotate_left(tree_node_stack[stack_pointer-1],tree_node_stack[stack_pointer]);
330 return 0;
331 }
332 else
333 {
334 //这里继续向上传递
335 stack_pointer--;
336 }
337 }
338 }
339 }
340 //至此所有的插入及平衡都做完了
341 }
342 }
343
344 void delete_avl_node(char* avl_node_name)//这里我们要求已经做过参数检查了,挂了自己撞墙去
345 {
346 ptype_avl_tree temp_node_one,temp_node_two,temp_node_three;//神一样的命名方法
347 ptype_description temp_type_description;
348 int stack_pointer=0;
349 int compare_result=0;
350 int original_depth=0;
351 temp_node_one=type_tree_head;
352 tree_node_stack[0]=NULL;//哨兵
353 temp_type_description=(ptype_description)temp_node_one->current_type_body;
354 compare_result=strcmp(avl_node_name,temp_type_description->name);
355 while(compare_result!=0)
356 {
357 stack_pointer++;
358 tree_node_stack[stack_pointer]=temp_node_one;
359 if(compare_result>0)
360 {
361 temp_node_one=temp_node_one->right;
362 }
363 else
364 {
365 temp_node_one=temp_node_one->left;
366 }
367 temp_type_description=(ptype_description)temp_node_one->current_type_body;
368 compare_result=strcmp(avl_node_name,temp_type_description->name);
369 }//找到对应的节点
370 if(temp_node_one->left==NULL||temp_node_one->right==NULL)//如果有删除的节点只有一个或零个子节点
371 {
372 if(stack_pointer==0)//如果是头节点,且只有不多于1个的子节点
373 {
374 type_tree_head=temp_node_one->left|temp_node_one->right;//这里就不需要考虑空节点了,这里已经考虑过了
375 free(temp_node_one);
376 return 0;//直接返回
377 }//这里就不需要平衡了
378 else//如果不是头节点
379 {
380 temp_node_two=tree_node_stack[stack_pointer];
381 if(temp_node_two->left==temp_node_one)
382 {
383 temp_node_two->left=temp_node_one->left|temp_node_one->right;
384 }
385 else
386 {
387 temp_node_two->right=temp_node_one->left|temp_node_one->right;
388 }//修正好所有的节点关系
389 }
390 }
391 else//有两个子节点,选择后继来处理
392 {
393 temp_node_two=temp_node_one->right;
394 while(temp_node_two!=NULL)
395 {
396 stack_pointer++;
397 tree_node_stack[stack_pointer]=temp_node_two;
398 temp_node_two=temp_node_two->left;
399 }
400 temp_node_two=tree_node_stack[stack_pointer];
401 temp_node_one->current_generate_body=temp_node_two->current_generate_body;
402 //这样就把这个节点复制过去了
403 //现在我们要删除这个新的节点
404 stack_pointer--;//最后一个点抛弃,因为我们要删除这个点
405 //现在我们开始修改好节点关系,修改完之后再去平衡
406 if(temp_node_one->right==temp_node_two)//这个是特殊情况
407 {
408 temp_node_one->right=temp_node_two->right;
409 }
410 else
411 {
412 tree_node_stack[stack_pointer]->left=temp_node_two->right;
413 }//这里修正好所有的节点关系,然后再开始平衡
414
415
416
417
418
419
420 }
421 //现在开始进行平衡
422 while(stack_pointer>0)
423 {
424 //这里跳出循环的条件是某个节点的高度没有变化,调用平衡处理之后,还是有可能影响上面的节点
425 //所以还是需要处理其他的点,因此平衡处理不是跳出循环的条件
426 temp_node_three=tree_node_stack[stack_pointer];
427 original_depth=temp_node_three->tree_depth;
428 modify_node_depth(temp_node_three);
429 if(temp_node_three->tree_depth==original_depth)
430 {
431 //如果子树的高度不变,则不需要继续处理了
432 return 0;
433 }
434 else//这里平衡操作不需要做第二次旋转,一次旋转就足够了
435 {
436 compare_result=temp_node_three->left->tree_depth-temp_node_three->right->tree_depth;
437 if(compare_result==2)
438 {
439 rotate_avl_right(tree_node_stack[stack_pointer-1],tree_node_stack[stack_pointer]);
440 stack_pointer--;
441 }
442 else
443 {
444 if(compare_result==-2)
445 {
446 rotate_avl_left(tree_node_stack[stack_pointer-1],tree_node_stack[stack_pointer]);
447 stack_pointer--;
448 }
449 else
450 {
451 stack_pointer--;
452 }
453 }
454 }
455 }
456 return 0;
457 }
458 ptype_description search_avl_tree(char* target_name)//在当前avl树中寻找是否有相应的名字的节点
459 {
460 ptype_avl_tree result;//作为遍历树的指针
461 ptype_description return_result;//作为返回的节点
462 int compare_result;//比较的时候的返回结果
463 result=type_tree_head;
464 while(result!=NULL)
465 {
466 return_result=(ptype_description)result->current_type_body;
467 compare_result=strcmp(target_name,return_result->name);
468 if(compare_result==0)
469 {
470 break;//不需要继续找了
471 }
472 else
473 {
474 if(compare_result<0)
475 {
476 result=result->left;
477 }
478 else
479 {
480 result=result->right;
481 }
482 }
483 }
484 return return_result;
485 }
486
487
488
489