minic 词法单元建立

  1 #include <stdio.h>
  2 #include "symbol_table_def.h"
  3 //前面的那个词法和文法说明只是大概的说明,现在又有了改动,把指针运算符改为了@,把取地址运算符改为了$
  4 //但是类型声明的时候的指针类型仍然是*
  5 //现在所有的符号都用了,除了让人恶心的逗号和问号
  6 //现在开始定义词法单元的枚举类型
  7 enum lex_type
  8 {
  9     name,//代表字符串,包括所有的关键字和变量声明
 10     delimit,//代表分号,以及大括号
 11     char_type,//代表字符
 12     an_operator,//代表操作符
 13     constant,//代表常量
 14     string_phrase,//代表字符串
 15     new_line//代表换行,因为在处理的时候换行是一个很重要的符号
 16 };
 17 enum basic_operator_type
 18 {
 19     array_op=9,//代表数组分量运算
 20     parenthesis,//代表括号
 21     p_str_sub,//代表结构体指针分量运算
 22     str_sub,//代表结构体分量运算
 23     not,//代表!
 24     bit_rev,//代表~
 25     get_adr,//代表$
 26     get_mem,//代表@
 27     type_cast,//代表强制类型转换
 28     negative,//代表负号运算
 29     get_size,//代表sizeof
 30     multi,//代表乘法 
 31     div,//代表除法
 32     module,//代表模
 33     add,//代表加法
 34     minus,//代表减法
 35     left_shift,//左移
 36     right_shift,//右移
 37     larger,//大于
 38     smaller,//小于
 39     lar_eqa,//大于等于
 40     sma_eqa,//小于等于
 41     equal,//等于
 42     nequal,//不等于
 43     bit_and,//&
 44     bit_xor,//^
 45     bit_or,//|
 46     and,//&&
 47     or// ||
 48 };
 49 
 50 struct first_lex_token
 51 {
 52     enum lex_type current_lex_type;//在第一遍处理的时候我们把所有的词素分为前面所说的六种
 53     char* token_name;
 54 };
 55 struct first_token_chain//这个链表将所有的词法单元串联起来
 56 {
 57     struct first_lex_token* current_first_token;
 58     struct first_token_chain* next;
 59 };
 60 struct first_token_chain* first_chain_head=NULL;//这里是所有节点的头节点
 61 struct first_token_chain* first_chain_tail=NULL;//这里是所有节点的末尾节点,为了插入用.
 62 //在第一趟处理的时候我们开两个2000个字节的缓冲区,用来读文件,并不断的切换
 63 //为了表明文件的结束,我们找来了我们的老朋友 '17' ,我们用这个字符来表示缓冲区的文件末尾
 64 char end_of_file=17;
 65 char* buff_zone[2];//这个代表两个缓冲区
 66 int buffer_pointer;//这个代表在缓冲区内的偏移
 67 int file_read_byte;//这个代表在读取文件到缓冲区的时候,读取了多少个字符
 68 int buff_zone_index;//代表使用的是那一个缓冲区
 69 char* current_buff;//这个代表当前的缓冲区
 70 int seek_begin(void )
 71 {
 72     //吃掉所有的空格和制表符
 73     while(buffer_pointer<2000)
 74     {
 75         switch(*(buffer_zone[buffer_zone_index]+buffer_pointer))
 76         {
 77         case 17:
 78             return -1;//直接返回,文件已经处理完毕了
 79             break;
 80         case ' ':
 81             buffer_pointer++;
 82             break;
 83         case '\t':
 84             buffer_pointer++;
 85             break;
 86         default:
 87             break;
 88         }
 89     }
 90     if(buffer_pointer==2000)//越过缓冲区了
 91     {
 92         buffer_zone_index=1-buffer_zone_index;//切换缓冲区
 93         current_buff=buff_zone[buff_zone_index];
 94         file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
 95         if(file_read_byte!=2000)//如果碰到文件的结束了
 96         {
 97             *(current_buff+file_read_byte)=17;//标记为文件末尾
 98             //因为我们遇到的是字符文件,所以不会出现17这个字符
 99         }
100         buffer_pointer=0;
101         //重新开始读取输入,这里我们默认制表符和空格符不会占用整个缓冲
102         //吃掉所有的空格和制表符
103         while(buffer_pointer<2000)
104         {
105             switch(buffer_zone[buffer_zone_index]+buffer_pointer)
106             {
107             case 17:
108                 return -1;//直接返回,文件已经处理完毕了
109                 break;
110             case ' ':
111                 buffer_pointer++;
112                 break;
113             case '\t':
114                 buffer_pointer++;
115                 break;
116             default:
117                 break;
118             }
119         }
120     }
121 
122     return 1;//代表正常的返回
123 }
124 int lex_char_type(char current)//返回当前字符的前缀集 
125 {
126     char test;
127     test=current;
128     if((test>='a'&&test<='z')||(test>='A'&&test<='Z')||(test=='_'))
129     {
130         return 1;//代表名字
131     }
132     else
133     {
134         if(test>='0'&&test<='9')
135         {
136             return 2;//数字
137         }
138         else
139         {
140             if(test==';'||test=='{'||test=='}')
141             {
142                 return 3;//代表分隔符
143             }
144             else
145             {
146                 if(test=='\'')
147                 {
148                     return 4;//代表字符
149                 }
150                 else
151                 {
152                     if(test=='\"')
153                     {
154                         return 5;//代表字符串 
155                     }
156                     else
157                     {
158                         return 6;//代表运算符
159                     }
160                 }
161             }
162         }
163     }
164 }
165 
166 
167 
168 void first_procedure(FILE* input_file_name)
169 {
170     char* temp_name;//代表词法单元的内容
171     int token_length;//代表读取的词法单元的长度
172     int lex_mode;//代表开始字符所处的token种类
173     int seek_return;
174     char current_char;
175     int for_i,for_j;
176     struct first_lex_token* temp_token;
177     struct first_token_chain token_chain_node;
178     current_buff=malloc(sizeof(char)*4000);
179     buff_zone[0]=current_buff;
180     buff_zone[1]=current_buff+2000;
181     //这里我们其实上把一个4000的缓冲区分裂为两个缓冲区了,这样可以让这两个缓冲区的空间连续
182     file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
183     if(file_read_byte!=2000)//如果碰到文件的结束了
184     {
185         *(current_buff+file_read_byte)=17;//标记为文件末尾
186         //因为我们遇到的是字符文件,所以不会出现17这个字符
187     }
188     buff_zone_index=0;//首先使用第一个缓冲区
189     buffer_pointer=0;
190     seek_return=seek_begin();
191     while(seek_return!=-1)//只要还没有到达末尾
192     {
193         current_char=*(buff_zone[buff_zone_index]+buffer_pointer);
194         lex_mode=lex_char_type(current_char);
195         switch(lex_mode)
196         {
197         case 1://代表名字
198             token_length=0;
199             while((current_char>='a'&&current_char<='z')||(current_char>='A'&&current_char<='Z')||current_char=='_')
200             {
201                 token_length++;
202                 buffer_pointer++;
203                 if(buffer_pointer==2000)
204                 {
205                     buff_zone_index=1-buff_zone_index;
206                     current_buff=buff_zone[buff_zone_index];
207                     file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
208                     if(file_read_byte!=2000)//如果碰到文件的结束了
209                     {
210                         *(current_buff+file_read_byte)=17;//标记为文件末尾
211                         //因为我们遇到的是字符文件,所以不会出现17这个字符
212                     }
213                     buffer_pointer=0;
214                 }
215                 current_char=current_buff[buffer_pointer];
216             }
217             temp_name=malloc(sizeof(char)*(token_length+1));
218             if(token_length<=buffer_pointer)
219             {
220                 for(for_i=0;for_i<token_length;for_i++)
221                 {
222                     temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
223                 }
224             }
225             else
226             {
227                 current_buff=buff_zone[1-buff_zone_index];
228                 for_j=token_length-buffer_pointer;
229                 for(for_i=0;for_i<for_j;for_i++)
230                 {
231                     temp_name[for_i]=current_buff[2000-for_j+for_i];
232                 }
233                 current_buff=buff_zone[buff_zone_index];
234                 for(for_i=0;for_i<buffer_pointer;for_i++)
235                 {
236                     temp_name[for_j+for_i]=current_buff[for_i];
237                 }
238             }
239             temp_name[token_length]='\0';
240             temp_token=malloc(sizeof(struct first_lex_token));
241             temp_token->token_name=temp_name;
242             if(strcmp("sizeof",temp_name)==0)
243             {
244                 temp_token->current_lex_type=an_operator;
245             }
246             else
247             {
248                 temp_token->current_lex_type=name;
249             }
250             break;
251         case 2://对应数字常量的情况
252             token_length=0;
253             while((current_char>='0'&&current_char<='9')||(current_char>='A'&&current_char<='F')||\
254                 (current_char>='a'&&current_char<='f')||current_char=='x'||current_char=='X'||current_char=='.')
255             {
256                 token_length++;
257                 buffer_pointer++;
258                 if(buffer_pointer==2000)
259                 {
260                     buff_zone_index=1-buff_zone_index;
261                     current_buff=buff_zone[buff_zone_index];
262                     file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
263                     if(file_read_byte!=2000)//如果碰到文件的结束了
264                     {
265                         *(current_buff+file_read_byte)=17;//标记为文件末尾
266                         //因为我们遇到的是字符文件,所以不会出现17这个字符
267                     }
268                     buffer_pointer=0;
269                 }
270                 current_char=current_buff[buffer_pointer];
271             }
272             temp_name=malloc(sizeof(char)*(token_length+1));
273             if(token_length<=buffer_pointer)
274             {
275                 for(for_i=0;for_i<token_length;for_i++)
276                 {
277                     temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
278                 }
279             }
280             else
281             {
282                 current_buff=buff_zone[1-buff_zone_index];
283                 for_j=token_length-buffer_pointer;
284                 for(for_i=0;for_i<for_j;for_i++)
285                 {
286                     temp_name[for_i]=current_buff[2000-for_j+for_i];
287                 }
288                 current_buff=buff_zone[buff_zone_index];
289                 for(for_i=0;for_i<buffer_pointer;for_i++)
290                 {
291                     temp_name[for_j+for_i]=current_buff[for_i];
292                 }
293             }
294             temp_name[token_length]='\0';
295             temp_token=malloc(sizeof(struct first_lex_token));
296             temp_token->token_name=temp_name;
297             temp_token->current_lex_type=constant;
298             break;
299         case 3://对应分隔符
300             temp_name=malloc(sizeof(char)*2);
301             temp_name[0]=current_buff[buffer_pointer];
302             temp_name[1]='\0';
303             buffer_pointer++;
304             if(buffer_pointer==2000)
305             {
306                 buff_zone_index=1-buff_zone_index;
307                 current_buff=buff_zone[buff_zone_index];
308                 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
309                 if(file_read_byte!=2000)//如果碰到文件的结束了
310                 {
311                     *(current_buff+file_read_byte)=17;//标记为文件末尾
312                     //因为我们遇到的是字符文件,所以不会出现17这个字符
313                 }
314                 buffer_pointer=0;
315             }
316             current_char=current_buff[buffer_pointer];
317             temp_token=malloc(sizeof(struct first_lex_token));
318             temp_token->token_name=temp_name;
319             temp_token->current_lex_type=delimit;
320             break;
321         case 4://对应字符
322             token_length=0;
323             buffer_pointer++;
324             if(buffer_pointer==2000)
325             {
326                 buff_zone_index=1-buff_zone_index;
327                 current_buff=buff_zone[buff_zone_index];
328                 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
329                 if(file_read_byte!=2000)//如果碰到文件的结束了
330                 {
331                     *(current_buff+file_read_byte)=17;//标记为文件末尾
332                     //因为我们遇到的是字符文件,所以不会出现17这个字符
333                 }
334                 buffer_pointer=0;
335             }
336             current_char=current_buff[buffer_pointer];
337             while(current_char!='\'')
338             {
339                 token_length++;
340                 buffer_pointer++;
341                 if(buffer_pointer==2000)
342                 {
343                     buff_zone_index=1-buff_zone_index;
344                     current_buff=buff_zone[buff_zone_index];
345                     file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
346                     if(file_read_byte!=2000)//如果碰到文件的结束了
347                     {
348                         *(current_buff+file_read_byte)=17;//标记为文件末尾
349                         //因为我们遇到的是字符文件,所以不会出现17这个字符
350                     }
351                     buffer_pointer=0;
352                 }
353                 current_char=current_buff[buffer_pointer];
354             }
355             temp_name=malloc(sizeof(char)*(token_length));
356             if(token_length<=buffer_pointer)
357             {
358                 for(for_i=0;for_i<token_length;for_i++)
359                 {
360                     temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
361                 }
362             }
363             else
364             {
365                 current_buff=buff_zone[1-buff_zone_index];
366                 for_j=token_length-buffer_pointer;
367                 for(for_i=0;for_i<for_j;for_i++)
368                 {
369                     temp_name[for_i]=current_buff[2000-for_j+for_i];
370                 }
371                 current_buff=buff_zone[buff_zone_index];
372                 for(for_i=0;for_i<buffer_pointer;for_i++)
373                 {
374                     temp_name[for_j+for_i]=current_buff[for_i];
375                 }
376             }
377             buffer_pointer++;
378             if(buffer_pointer==2000)
379             {
380                 buff_zone_index=1-buff_zone_index;
381                 current_buff=buff_zone[buff_zone_index];
382                 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
383                 if(file_read_byte!=2000)//如果碰到文件的结束了
384                 {
385                     *(current_buff+file_read_byte)=17;//标记为文件末尾
386                     //因为我们遇到的是字符文件,所以不会出现17这个字符
387                 }
388                 buffer_pointer=0;
389             }
390             temp_name[token_length-1]='\0';
391             if(temp_name[0]=='\\')//处理转义字符
392             {
393                 switch(temp_name[1])
394                 {
395                 case 'n':
396                     temp_name[0]='\n';
397                     temp_name[1]='\0';
398                     break;
399                 case 't':
400                     temp_name[0]='\t';
401                     temp_name[1]='\0';
402                     break;
403                 case '0':
404                     temp_name[0]='\0';
405                     break;
406                 case '\\':
407                     temp_name[1]='\0';
408                     break;
409                 case '\'':
410                     temp_name[0]='\'';
411                     temp_name[1]='\0';
412                     break;
413                 case '\"':
414                     temp_name[0]='\"';
415                     temp_name[1]='\0';
416                     break;
417                 default:
418                     break;
419                 }
420             }
421             temp_token=malloc(sizeof(struct first_lex_token));
422             temp_token->token_name=temp_name;
423             temp_token->current_lex_type=constant;
424             break;
425         case 5://代表字符串
426             token_length=0;
427             buffer_pointer++;
428             if(buffer_pointer==2000)
429             {
430                 buff_zone_index=1-buff_zone_index;
431                 current_buff=buff_zone[buff_zone_index];
432                 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
433                 if(file_read_byte!=2000)//如果碰到文件的结束了
434                 {
435                     *(current_buff+file_read_byte)=17;//标记为文件末尾
436                     //因为我们遇到的是字符文件,所以不会出现17这个字符
437                 }
438                 buffer_pointer=0;
439             }
440             current_char=current_buff[buffer_pointer];
441             while(1)
442             {
443                 while(current_char!='\"'444                 {
445                     token_length++;
446                     buffer_pointer++;
447                     if(buffer_pointer==2000)
448                     {
449                         buff_zone_index=1-buff_zone_index;
450                         current_buff=buff_zone[buff_zone_index];
451                         file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
452                         if(file_read_byte!=2000)//如果碰到文件的结束了
453                         {
454                             *(current_buff+file_read_byte)=17;//标记为文件末尾
455                             //因为我们遇到的是字符文件,所以不会出现17这个字符
456                         }
457                         buffer_pointer=0;
458                     }
459                     current_char=current_buff[buffer_pointer];
460                 }
461                 if(buffer_pointer==0)//判断是否是字符串的结尾
462                 {
463                     if(*(buff_zone[1-buff_zone_index]+1999)!='\\')
464                     {
465                         break;
466                     }
467                     else
468                     {
469                         token_length++;
470                         buffer_pointer++;
471                         //继续下次循环
472                     }
473                 }
474                 else
475                 {
476                     if(current_buff[buffer_pointer-1]!='\\')
477                     {
478                         break;
479                     }
480                     else
481                     {
482                         token_length++;
483                         buffer_pointer++;
484                         if(buffer_pointer==2000)
485                         {
486                             buff_zone_index=1-buff_zone_index;
487                             current_buff=buff_zone[buff_zone_index];
488                             file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
489                             if(file_read_byte!=2000)//如果碰到文件的结束了
490                             {
491                                 *(current_buff+file_read_byte)=17;//标记为文件末尾
492                                 //因为我们遇到的是字符文件,所以不会出现17这个字符
493                             }
494                             buffer_pointer=0;
495                         }
496                         current_char=current_buff[buffer_pointer];
497                     }
498                 }
499 
500 
501 
502             }
503             temp_name=malloc(sizeof(char)*(token_length+1));
504             if(token_length<=buffer_pointer)
505             {
506                 for(for_i=0;for_i<token_length;for_i++)
507                 {
508                     temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
509                 }
510             }
511             else
512             {
513                 current_buff=buff_zone[1-buff_zone_index];
514                 for_j=token_length-buffer_pointer;
515                 for(for_i=0;for_i<for_j;for_i++)
516                 {
517                     temp_name[for_i]=current_buff[2000-for_j+for_i];
518                 }
519                 current_buff=buff_zone[buff_zone_index];
520                 for(for_i=0;for_i<buffer_pointer;for_i++)
521                 {
522                     temp_name[for_j+for_i]=current_buff[for_i];
523                 }
524             }
525             temp_name[token_length]='\0';
526             buffer_pointer++;
527             temp_token=malloc(sizeof(struct first_lex_token));
528             temp_token->token_name=temp_name;
529             temp_token->current_lex_type=string_phrase;
530             break;
531         case 6://代表操作符
532             temp_name=malloc(sizeof(char)*2);
533             temp_name[0]=current_buff[buffer_pointer];
534             temp_name[1]='\0';
535             buffer_pointer++;
536             if(buffer_pointer==2000)
537             {
538                 buff_zone_index=1-buff_zone_index;
539                 current_buff=buff_zone[buff_zone_index];
540                 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
541                 if(file_read_byte!=2000)//如果碰到文件的结束了
542                 {
543                     *(current_buff+file_read_byte)=17;//标记为文件末尾
544                     //因为我们遇到的是字符文件,所以不会出现17这个字符
545                 }
546                 buffer_pointer=0;
547             }
548             temp_token=malloc(sizeof(struct first_lex_token));
549             temp_token->token_name=temp_name;
550             temp_token->current_lex_type=an_operator;
551             break;
552         default:
553             printf(" un_recognised type\n");
554             break;
555         }
556         token_chain_node=malloc(sizeof(struct first_token_chain));
557         token_chain_node->next=NULL;
558         token_chain_node->current_first_token=temp_token;
559         if(token_chain_tail==NULL)
560         {
561             token_chain_tail=token_chain_node;
562             token_chain_head=token_chain_node;
563         }
564         else
565         {
566             token_chain_tail->next=token_chain_node;
567             token_chain_tail=token_chain_node;
568         }
569         seek_return=seek_begin();
570     }
571 }
572     

 

posted @ 2013-07-24 17:52  huangnima  阅读(578)  评论(0编辑  收藏  举报