SLR,语法分析表的构建

太累了,感觉不会再爱了。执行了跟编译原理上的一模一样的例子,输出了正确结果

  1 #include <stdio.h>
  2 #include <malloc.h>
  3 #include <string.h>
  4 //这个头文件是为了将语法声明的产生式按照调用顺序来构建调用图,并顺便构建反向调用图。
  5 //从而来构建拓扑排序,并用到将来的分析之中。
  6 typedef struct _decl_hash_table
  7 {
  8     int is_used;//代表是否已经被使用
  9     char* decl_hash_name;//代表名字
 10     int node_index;//代表所代表的节点编号
 11 }decl_hash_table,*pdecl_hash_table;
 12 decl_hash_table decl_hash[100];//暂且定位100,其实我们在使用的过程中只会使用其中的97个,因为这个是一个质数
 13 typedef struct _decl_edge
 14 {
 15     int node_of_dest;
 16     struct _decl_edge* next;
 17 }decl_edge,*pdecl_edge;
 18 typedef struct _phrase
 19 {
 20     pdecl_edge begin_of_phrase;
 21     struct _phrase* next;
 22 }phrase;
 23 typedef struct _decl_node
 24 {
 25     phrase* phrase_link;//作为产生体链表的第一个节点的指针
 26     char* name_of_decl;//这个节点的名称,主要是为了输出使用的
 27 }decl_node,*pdecl_node;
 28 decl_node decl_node_table[100];//假设为100个节点,可以改
 29 int node_index=0;//全局的用来给节点赋予编号的变量,最后的值代表了有多少个文法符号,结束符不算在里面
 30 
 31 int insert_decl_hash(char* name,int input_node_index)
 32 //hash表插入函数,如果满了则返回-1
 33 //注意这里为了节省空间,hash表与节点表的名字域公用了一个字符串指针
 34 {
 35     int name_total;
 36     int counter;
 37     int result;
 38     int name_for_i;
 39     char* new_name;
 40     name_for_i=counter=name_total=result=0;
 41     while(name[name_for_i]!='\0')
 42     {
 43         name_total=name_total+name[name_for_i];
 44         name_for_i++;
 45     }
 46     new_name=malloc(sizeof(char)*(name_for_i+1));
 47     strcpy(new_name,name);
 48     result=name_total%97;
 49     while(counter<97)
 50     {
 51         if(decl_hash[result].is_used==0)
 52         {
 53             decl_hash[result].is_used=1;
 54             decl_hash[result].decl_hash_name=new_name;
 55             decl_hash[result].node_index=input_node_index;
 56             decl_node_table[input_node_index].name_of_decl=new_name;//公用名字指针
 57             return result;
 58         }
 59         else
 60         {
 61             result=(result+1)%97;
 62             counter++;
 63         }
 64     }
 65     return -1;
 66 }
 67 
 68 int search_decl_hash(char* input_name)
 69 {
 70     int name_total;
 71     int counter;
 72     int result;
 73     int name_for_i;
 74     name_for_i=counter=name_total=result=0;
 75     while(input_name[name_for_i]!='\0')
 76     {
 77         name_total=name_total+input_name[name_for_i];
 78         name_for_i++;
 79     }
 80     result=name_total%97;
 81     while(counter<97)
 82     {
 83         if(decl_hash[result].is_used==1)
 84         {
 85             if(!strcmp(decl_hash[result].decl_hash_name,input_name))
 86             {
 87                 return decl_hash[result].node_index;
 88             }
 89             else
 90             {
 91                 result=(result+1)%97;
 92                 counter++;
 93             }
 94         }
 95         else
 96         {
 97             return -1;
 98         }
 99     }
100     return -1;
101 }
102 
103 //以上是与hash表有关的函数
104 //下面则是与建立邻接表相关的数据结构与函数
105 void tackle_phrase(char* input_phrase)
106 //根据输入来建立所有的产生式,用数字来代替名字
107 //注意生成链表的时候,为了插入方便,我们是逆序的链表,全都建完之后再逆序一遍然后变成正序的
108 {
109     int for_i,for_j;
110     int current_tail_node,current_head_node;
111     char temp[20];//起临时的名字作用
112     phrase* temp_phrase;
113     decl_edge* temp_decl_edge;
114     for_i=0;
115     while(input_phrase[for_i]!=':'&&input_phrase[for_i]!=' ')
116     {
117         temp[for_i]=input_phrase[for_i];
118         for_i++;
119     }//找到头部的名字
120     temp[for_i]='\0';
121     current_head_node=search_decl_hash(temp);
122     if(current_head_node==-1)//如果这个名字是第一次碰到
123     {
124         node_index++;
125         insert_decl_hash(temp,node_index);
126         current_head_node=node_index;
127         decl_node_table[current_head_node].phrase_link=NULL;
128         printf("%d is the label of %s\n",node_index,temp);
129     }//建立名字
130     temp_phrase=malloc(sizeof(struct _phrase));//临时的产生体
131     temp_phrase->begin_of_phrase=NULL;
132     temp_phrase->next=decl_node_table[current_head_node].phrase_link;
133     decl_node_table[current_head_node].phrase_link=temp_phrase;
134     //把当前的产生式链接到产生式头的产生式链表中
135     while(input_phrase[for_i]==' '||input_phrase[for_i]==':')
136     {
137         for_i++;
138     }//找到第一个可以分析的点
139     while(input_phrase[for_i]!='\0')
140     {
141         while(input_phrase[for_i]==' ')
142         {
143             for_i++;
144         }//找到可以分析的点 
145         for_j=0;
146         while(input_phrase[for_i]!=' '&&input_phrase[for_i]!='\0')
147         {
148             temp[for_j]=input_phrase[for_i];
149             for_i++;
150             for_j++;
151         }//再次找到一个名字
152         temp[for_j]='\0';
153         current_tail_node=search_decl_hash(temp);
154         if(current_tail_node==-1)//如果是新的名字,则加入到hash中,并为他分配一个标号
155         {
156             node_index++;
157             current_tail_node=node_index;
158             insert_decl_hash(temp,node_index);
159             decl_node_table[current_tail_node].phrase_link=NULL;
160             printf("%d is the label of %s\n",node_index,temp);
161         }
162         //为当前的产生式链表增加一个元素
163         temp_decl_edge=malloc(sizeof(struct _decl_edge));
164         temp_decl_edge->node_of_dest=current_tail_node;
165         temp_decl_edge->next=temp_phrase->begin_of_phrase;
166         temp_phrase->begin_of_phrase=temp_decl_edge;
167     }
168 }
169 
170 
171 
172 void phrase_end(void)//这个函数是为了将终结符加入到符号表中
173 {
174     char* end="EOF";
175     decl_node_table[node_index+1].phrase_link=NULL;
176     insert_decl_hash(end,node_index+1);
177 }
178 
179 void reverse_phrase(void)
180 {
181     int for_i;
182     phrase* temp_phrase;
183     pdecl_edge temp_edge,swap_edge,next_edge;
184     for_i=1;
185     for(for_i=1;for_i<=node_index;for_i++)
186     {
187         temp_phrase=decl_node_table[for_i].phrase_link;
188         while(temp_phrase!=NULL)
189         {
190             temp_edge=temp_phrase->begin_of_phrase;
191             swap_edge=NULL;
192             while(temp_edge!=NULL)//由于前面是逆序的链表,现在我们把他转成顺序的链表
193             {
194                 next_edge=temp_edge->next;
195                 temp_edge->next=swap_edge;
196                 swap_edge=temp_edge;
197                 temp_edge=next_edge;
198             }
199             temp_phrase->begin_of_phrase=swap_edge;
200             //链表转换完成
201             temp_phrase=temp_phrase->next;
202         }//当前节点的所有产生式转换完成
203     }//所有节点的产生式逆转完成
204 }

上面的代码只是为所有的文法符号生成一个标号,并将生成式转化了这些标号。

下面的代码才是核心的生成语法分析表的步骤,感觉总是有点疑问,特别是有些前提没有证明。

  1 #include "declar_topological.h"
  2 typedef struct _lr_group_node
  3 {
  4     int node_pointer;//代表产生式头
  5     phrase* current_phrase;//代表当前的产生式体
  6     pdecl_edge current_edge;//代表当前期待的语法单元 
  7 }lr_group_node,*plr_group_node;//这里是闭包中的一个项的描述
  8 typedef struct _lr_closure
  9 {
 10     plr_group_node current_group_node;//这个代表一个项 
 11     struct _lr_closure* next;//这个next域将所有的单个项串联起来
 12 }lr_closure,*plr_closure;//这里是一个闭包的结构
 13 plr_closure current_closure[100];//暂且定为100,可以改
 14 int group_index=0;//这里是为了标记群号
 15 typedef struct _transition_node
 16 {
 17     enum
 18     {
 19         shift,//移进
 20         reduce,//规约
 21         error,//报错
 22         accept//接受
 23     }action_type;
 24     union
 25     {
 26         struct 
 27         {
 28             int shift_node;//移进的项集
 29         };
 30         struct
 31         {
 32             int reduce_node;//规约的时候的产生式头
 33             int reduce_length;//规约的时候的产生式体的长度
 34         };
 35     };
 36 }transition_node,*p_transition_node;
 37 typedef struct _token_list
 38 {
 39     struct _token_list* next;
 40     int node_number;
 41 }token_list,*ptoken_list;
 42 ptoken_list list_head=NULL;//节点头
 43 
 44 transition_node* transition_table[400];//这里代表了整个转换表
 45 void extend_group(int in_group_index)//扩展项集的函数
 46 {
 47     plr_closure temp_group,temp_group_end,temp_group_add;
 48     //temp_group是用来遍历所有的项,temp_group_end是用来在遍历过程中表示最后一个项,
 49     //temp_group_add跟前面一个合用,来在项集的末尾增加项
 50     plr_group_node temp_group_node,temp_group_node_add;
 51     //temp_group_node是用来遍历项,temp_group_node_add用来在增加项的过程中使用
 52     phrase* temp_phrase;
 53     //这两个都是用来增加项用的
 54     int graph_node_index;
 55     temp_group=current_closure[in_group_index];//得到当前项集的索引
 56     temp_group_end=temp_group;//这里用来得到当前项集的最后一个项
 57     while(temp_group_end->next!=NULL)
 58     {
 59         temp_group_end=temp_group_end->next;
 60     }//寻找到末尾那个节点
 61     while(temp_group!=NULL)//遍历整个项集,必要的时候扩充项集,即闭包
 62     {
 63         temp_group_node=temp_group->current_group_node;//获得当前项
 64         if(temp_group_node->current_edge!=NULL)//如果右端还有文法符号,则试图去扩展
 65         {
 66             graph_node_index=temp_group_node->current_edge->node_of_dest;//获得当前项所期待的文法符号的索引
 67             if(temp_group_node->node_pointer!=graph_node_index)//如果这个文法符号与当前产生式的文法符号不相同
 68             //相同的时候会造成无限循环,即不停的把这个项添加进当前闭包中,并且无法终止 
 69             //由于我们在扩展闭包的过程中是按照拓扑顺序来添加的,所以可以保证在不重复添加同一节点的情况下
 70             //群的大小是有界的
 71             //在不等的情况下,我们可以扩展群
 72             {
 73                 temp_phrase=decl_node_table[graph_node_index].phrase_link;//获得当前文法符号的第一个产生式 
 74                 while(temp_phrase!=NULL)//遍历产生式
 75                 {
 76                     temp_group_node_add=malloc(sizeof(struct _lr_group_node));
 77                     temp_group_node_add->current_edge=temp_phrase->begin_of_phrase;//设置为开始的那一条边
 78                     temp_group_node_add->current_phrase=temp_phrase;//设置为当前产生式的链表头
 79                     temp_group_node_add->node_pointer=graph_node_index;//设置为产生式的头
 80                     //至此构建了一个项的描述
 81                     //开始添加进项集中,准确的来说是末尾
 82                     temp_group_add=malloc(sizeof(struct _lr_closure));
 83                     temp_group_add->current_group_node=temp_group_node_add;
 84                     temp_group_add->next=NULL;
 85                     temp_group_end->next=temp_group_add;
 86                     temp_group_end=temp_group_add;
 87                     temp_phrase=temp_phrase->next;
 88                 }//把当前项的扩展项都添加进去了
 89             }//同上
 90         }
 91         temp_group=temp_group->next;//处理下一项
 92     }//所有的扩展项都处理完成了 
 93 }//扩展完成
 94 
 95 plr_closure closure_transition(int closure_index,int node_index)
 96 {
 97     plr_closure result_closure,now_closure,temp_closure_add,temp_closure_end,temp_closure;
 98     plr_group_node temp_group_node,temp_group_node_add;
 99     pdecl_edge temp_edge;//尼玛 ,为什么这么多temp啊,老子要转函数式编程
100     now_closure=current_closure[closure_index];
101     result_closure=malloc(sizeof(struct _lr_closure));
102     result_closure->current_group_node=NULL;
103     result_closure->next=NULL;
104     temp_closure_end=NULL;
105     //把这个新的群初始化为空
106     temp_closure=now_closure;
107     while(temp_closure!=NULL)
108     {
109         temp_group_node=temp_closure->current_group_node;
110         temp_edge=temp_group_node->current_edge;//注意这里current_edge可能为空,要去判断
111         if(temp_edge!=NULL)//如果不为空,再去判断是否是希望的节点
112         {
113             if(temp_edge->node_of_dest==node_index)
114             {
115                 temp_group_node_add=malloc(sizeof(struct _lr_group_node));
116                 temp_group_node_add->current_edge=temp_edge->next;
117                 temp_group_node_add->current_phrase=temp_group_node->current_phrase;
118                 temp_group_node_add->node_pointer=temp_group_node->node_pointer;
119                 //现在建立好了一个项,准备插入到这个项集里面去
120                 temp_closure_add=malloc(sizeof(struct _lr_closure));
121                 temp_closure_add->current_group_node=temp_group_node_add;
122                 temp_closure_add->next=NULL;//因为是从尾部开始加入的所以就初始化为空
123                 if(temp_closure_end!=NULL)//这里需要判断当前加入的是不是第一个项,因为要特殊处理
124                 {
125                     temp_closure_end->next=temp_closure_add;
126                     temp_closure_end=temp_closure_add;
127                 }
128                 else
129                 {
130                     result_closure->current_group_node=temp_group_node_add;
131                     temp_closure_end=result_closure;
132                     free(temp_closure_add);
133                 }
134             }
135         }
136         temp_closure=temp_closure->next;
137     }//一直遍历整个项链表,有转换的时候就添加
138     if(result_closure->current_group_node==NULL)
139     {
140         free(result_closure);
141         return NULL;
142         //额,这里忘了释放内存了,调试完再去释放
143     }
144     else
145     {
146         return result_closure;
147     }
148 }
149 
150 
151 int already_in(plr_closure input_closure)
152 //遍历整个项集来比较,这个方法比较笨,其实可以插入的时候打表
153 //也可以利用hash或者其他的数据结构来查询
154 //这个函数是目前问题最大的函数
155 {
156     int for_i;
157     plr_closure temp_closure,begin_closure;
158     plr_group_node temp_group_node,org_group_node;
159     for(for_i=1;for_i<=group_index;for_i++)//遍历整个项集族
160     {
161         temp_closure=current_closure[for_i];
162         begin_closure=input_closure;
163         //都获得第一个项集的指针,这样我们就可以遍历了
164         while(begin_closure!=NULL)//遍历整个项集,由于当前尚未扩展,所以用这个短的
165             //当前比较的都是核心项,这里需要担心的是某个项集的核心项包括了当前项集的核心项
166             //如果出现这种情况,这里的代码就会出现错误
167             //当前我们先不考虑这种情况,之后再去修改
168         {
169             temp_group_node=temp_closure->current_group_node;
170             org_group_node=begin_closure->current_group_node;
171             //由于我们保证了添加项集的时候是按照文法符号的引用序来添加的
172             //所以直接按照链表,一个一个来比较就行了,如果有一个没有匹配上就不需要再去比较剩下的项了
173             //只需要匹配下一个项集族
174             //现在判断是否完全匹配
175             if(temp_group_node->node_pointer==org_group_node->node_pointer)//如果产生式头相同
176             {
177                 if(temp_group_node->current_phrase==org_group_node->current_phrase)//如果产生式的体相同
178                 {
179                     if(temp_group_node->current_edge==org_group_node->current_edge)//如果下一个期待的符号相同
180                     {
181                         temp_closure=temp_closure->next;
182                         begin_closure=begin_closure->next;
183                         continue;//进入下次循环
184                     }
185                 }
186             }
187             break;//如果这三个不能完全匹配,则跳出当前项集循环判断,进入下一个项集的循环判断
188         }//当前项集遍历结束
189         if(begin_closure==NULL)
190             //如果遍历到了末尾,则说明完全匹配了
191             //这里我们保证了开始时的temp_closure不是空的,因为我们不会插入一个空群
192         {
193             return for_i;//返回群号,说明这个项集已经存在了
194         }
195     }
196     //如果所有的项集都无法匹配
197     return 0;//返回0,说明这个项集还不存在
198 }
199 void output_transition(void)
200 {
201 
202     int for_i,for_j;
203     transition_node* temp_tran_row;
204     printf("     ");
205     for(for_i=1;for_i<=node_index+1;for_i++)
206     {
207         printf("%-4s ",decl_node_table[for_i].name_of_decl);
208     }
209     printf("\n");
210     for(for_i=1;for_i<=group_index;for_i++)
211     {
212         temp_tran_row=transition_table[for_i];
213         printf("%3d  ",for_i);
214         for(for_j=1;for_j<=node_index+1;for_j++)
215         {
216             if(temp_tran_row[for_j].action_type==reduce)
217             {
218                 printf("r%2d  ",(temp_tran_row+for_j)->reduce_node);
219             }
220             else
221             {
222                 if(temp_tran_row[for_j].action_type==shift)
223                 {
224                     printf("s%2d  ",(temp_tran_row+for_j)->shift_node);
225                 }
226                 else
227                 {
228                     if(temp_tran_row[for_j].action_type==accept)
229                     {
230                         printf("ac   ");
231                     }
232                     else
233                     {
234                         printf("err  ");
235                     }
236                 }
237             }
238         }
239         printf("\n");
240     }
241 }
242 
243 void output_closure(void)
244 {
245     int for_i;
246     int begin;
247     plr_closure temp_closure;
248     plr_group_node temp_group_node;
249     pdecl_edge temp_edge;
250     phrase* temp_phrase;
251     for(for_i=1;for_i<=group_index;for_i++)
252     {
253         temp_closure=current_closure[for_i];
254         while(temp_closure!=NULL)
255         {
256             temp_group_node=temp_closure->current_group_node;
257             begin=temp_group_node->node_pointer;
258             temp_phrase=temp_group_node->current_phrase;
259             temp_edge=temp_phrase->begin_of_phrase;
260             printf("%s->",decl_node_table[begin].name_of_decl);
261             while(temp_edge!=NULL)
262             {
263                 if(temp_edge==temp_group_node->current_edge)
264                 {
265                     printf(".");
266                 }
267                 printf("%s",decl_node_table[temp_edge->node_of_dest].name_of_decl);
268                 temp_edge=temp_edge->next;
269             }
270             if(temp_group_node->current_edge==NULL)
271             {
272                 printf(".");
273             }
274             printf("\n");//当前项输出完成
275             temp_closure=temp_closure->next;
276         }//当前项集输出完成
277         printf("closure %d is completed\n",for_i);
278     }//所有项集输出完成
279 }
280 
281 
282 
283 
284 
285 void graph_to_closure(char* begin_name)
286 {
287     int begin_node_index;//这个作为原来的开始文法符号的索引
288     int current_group_index;//这个代表当前正在处理的项集
289     int for_i,is_in;
290     pdecl_edge temp_edge;
291     phrase* temp_phrase;
292     plr_closure temp_group;
293     plr_group_node temp_group_node;
294     transition_node* temp_tran_row;//代表临时的转换行
295     int recept_group;//当作接收节点
296     begin_node_index=search_decl_hash(begin_name);//找到开始节点的索引
297     //开始添加伪节点
298     temp_edge=malloc(sizeof(struct _decl_edge));
299     temp_edge->next=NULL;
300     temp_edge->node_of_dest=begin_node_index;
301     temp_phrase=malloc(sizeof(struct _phrase));
302     temp_phrase->begin_of_phrase=temp_edge;
303     temp_phrase->next=NULL;
304     decl_node_table[0].phrase_link=temp_phrase;
305     insert_decl_hash("dumb",0);//插入哑元
306     //这里添加了伪开始节点
307     //下面开始建群
308     temp_group_node=malloc(sizeof(struct _lr_group_node));
309     temp_group_node->current_edge=temp_edge;
310     temp_group_node->current_phrase=temp_phrase;
311     temp_group_node->node_pointer=0;
312     temp_group=malloc(sizeof(struct _lr_closure));
313     temp_group->next=NULL;
314     temp_group->current_group_node=temp_group_node;
315     group_index++;
316     current_closure[group_index]=temp_group;//从1开始标号,注意
317     //现在开始扩展项集
318     extend_group(group_index);
319     current_group_index=group_index;
320     while(current_group_index<=group_index)//一个项集一个项集的处理
321     {
322         //现在对每一个文法单元进行尝试,看是否有转移
323         //如果有转移,看是否生成的项集已经被包括了
324         temp_tran_row=malloc(sizeof(struct _transition_node)*(node_index+2));
325         //这里需要考虑最后的终结符号,所以加1,又由于为了表述方便,我们把开始偏移定为1,所以最后是加2
326         transition_table[current_group_index]=temp_tran_row;
327         for(for_i=1;for_i<=node_index+1;for_i++)//这里加1是为了考虑终结符号
328         {
329             temp_group=NULL;
330             temp_group=closure_transition(current_group_index,for_i);//调用子函数来进行项集的生成
331             if(temp_group!=NULL)//如果不是空群,进行移进
332             {
333                 is_in=already_in(temp_group);
334                 if(!is_in)//如果这个项集还没有添加
335                 {
336                     group_index++;
337                     current_closure[group_index]=temp_group;
338                     temp_tran_row[for_i].action_type=shift;
339                     temp_tran_row[for_i].shift_node=group_index;
340                     extend_group(group_index);
341                 }
342                 else//如果项集已经添加
343                 {
344                     temp_tran_row[for_i].action_type=shift;
345                     temp_tran_row[for_i].shift_node=is_in;
346                 }
347             }
348             else//如果没有转换,则考虑规约
349             {
350                 temp_tran_row[for_i].action_type=error;//首先写为这个,后面再去修改
351                 //现在开始遍历当前项集,如果当前项集里面存在点在最末尾的项,则按照这个项来规约
352                 //我们默认当前不会产生归约冲突,即当前的是无二义的lr(0)文法
353                 temp_group=current_closure[current_group_index];
354                 while(temp_group!=NULL)//遍历当前项集中所有的项,看是否有可归约项
355                 {
356                     temp_group_node=temp_group->current_group_node;
357                     if(temp_group_node->current_edge==NULL)//如果这个项可以作为一个归约式
358                     {
359                         int length_of_phrase;//这个代表产生式体有多少个符号
360                         temp_phrase=temp_group_node->current_phrase;
361                         temp_edge=temp_phrase->begin_of_phrase;
362                         length_of_phrase=0;
363                         while(temp_edge!=NULL)//获得产生式长度
364                         {
365                             length_of_phrase++;
366                             temp_edge=temp_edge->next;
367                         }
368                         temp_tran_row[for_i].reduce_node=temp_group_node->node_pointer;
369                         temp_tran_row[for_i].reduce_length=length_of_phrase;
370                         temp_tran_row[for_i].action_type=reduce;
371                         break;
372                     }
373                     temp_group=temp_group->next;
374                 }
375                 //如果到最后都没有找到可以规约的项,则保持这个为error
376             }
377         }//所有文法符号处理完毕
378         current_group_index++;//当前项集处理完成,开始处理下一个项集
379 
380     }//所有的项集处理完成
381     //这里再去添加一个接受状态
382     temp_tran_row=transition_table[(transition_table[1]+begin_node_index)->shift_node];
383     (temp_tran_row+node_index+1)->action_type=accept;
384     
385     //现在把这个调整成为了接受状态,可以输出整个转换表了
386     //现在开始输出
387     output_closure();//输出所有的项集
388     output_transition();//输出转换
389     
390 }//所有的完成
391 void str_to_list(char* input_str)//将输入字符转变为文法单元,然后以链表串接起来
392 {
393     char temp[10];
394     int str_index;
395     int str_len; 
396     int node_pointer;
397     ptoken_list temp_list;
398     ptoken_list current_list;
399     str_index=0;
400     while(input_str[str_index]!='\0')
401     {
402         while(input_str[str_index]==' ')
403         {
404             str_index++;
405         }
406         str_len=0;
407         while(input_str[str_index]!=' '&&input_str[str_index]!='\0')
408         {
409             temp[str_len]=input_str[str_index];
410             str_index++;
411             str_len++;
412         }
413         temp[str_len]='\0';
414         node_pointer=search_decl_hash(temp);
415         temp_list=malloc(sizeof(struct _token_list));
416         temp_list->node_number=node_pointer;
417         temp_list->next=NULL;
418         if(list_head==NULL)
419         {
420             list_head=temp_list;
421             current_list=temp_list;
422         }
423         else
424         {
425             current_list->next=temp_list;
426             current_list=temp_list;
427         }
428     }
429     temp_list=malloc(sizeof(struct _token_list));
430     temp_list->node_number=node_index+1;
431     current_list->next=temp_list;
432     temp_list->next=NULL;
433 }
434 
435 
436 
437 int get_token(void)//从链表中获得一个文法单元
438 {
439     ptoken_list temp_list;
440     int result_node;
441     result_node=list_head->node_number;
442     temp_list=list_head;
443     list_head=list_head->next;
444     free(temp_list);
445     return result_node;
446 }
447 void putback(int withdraw)
448 {
449     ptoken_list temp_list;
450     temp_list=malloc(sizeof(struct _token_list));
451     temp_list->node_number=withdraw;
452     temp_list->next=list_head;
453     list_head=temp_list;
454 }
455 //现在建立了转换表
456 void input_recognise(void )
457 {
458     int syntax_stack[100];//暂且开这么大
459     int stack_pointer;
460     int input_token;
461     int temp_token;
462     int reduce_token;//注意这里规约的时候,可能会产生为0的点
463     int reduce_length;
464     int for_i;
465     int end=0;
466     transition_node* current_tran_node;
467     stack_pointer=1;
468     syntax_stack[1]=1;//把最开始的群号放进去
469     temp_token=-1;//防止出现为0的情况
470     input_token=-1;
471     while(1)//一直循环
472     {
473         if(input_token==-1)
474         {
475             input_token=get_token();
476         }
477         current_tran_node=transition_table[syntax_stack[stack_pointer]]+input_token;//获得栈顶节点的转换表
478         switch((current_tran_node->action_type))//判断转换类型
479         {
480         case accept://接受
481             printf("acc\n");
482             input_token=-1;
483             end=1;//设置结束位
484             break;
485         case shift://移入
486             stack_pointer++;
487             syntax_stack[stack_pointer]=current_tran_node->shift_node;
488             printf("shift %d\n",current_tran_node->shift_node);
489             input_token=-1;//设置提醒位,提示下次需要读取输入
490             break;
491         case error://报错
492             printf("error\n");
493             end=1;//设置结束位
494             break;
495         case reduce://如果是规约,那么获得规约长度,然后缩短栈指针,
496             putback(input_token);//返回这个输入
497             reduce_length=current_tran_node->reduce_length;
498             reduce_token=current_tran_node->reduce_node;
499             stack_pointer=stack_pointer-reduce_length;
500             printf("reduce ");
501             for(for_i=1;for_i<=reduce_length;for_i++)
502             {
503                 printf("%d ",syntax_stack[stack_pointer+for_i]);
504             }
505             printf(" to %d \n",reduce_token);
506             input_token=reduce_token;
507             break;
508         default:
509             printf("we are in trouble\n");
510             break;
511         }
512         if(end!=0)
513         {
514             break;//报错或接受,因此结束
515         }
516     }//一直循环
517 }
518 
519 
520 
521 
522         

 

posted @ 2013-07-04 19:44  huangnima  阅读(2830)  评论(0编辑  收藏  举报