zoukankan      html  css  js  c++  java
  • minic 符号表

      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]!='')
     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]!='')
    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]!='')
    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         
  • 相关阅读:
    05,WP8的文件和存储
    04,WP8的async和await
    01,Windows Phone 8 介绍
    开源工作流引擎
     RMS集成的时候会出这样那样的问题
    ASP.NET第一次访问慢的完美解决方案(MVC,Web Api)
    SharePoint2010关闭我的网站(个人网站)
    SMSServer的网关配置
    文件间调用变量(extern,include)[转]
    [转]安装SMSServer作为Windows系统服务
  • 原文地址:https://www.cnblogs.com/huangfeidian/p/3211163.html
Copyright © 2011-2022 走看看