词法分析之实验报告

 词法分析实验

一、实验目的

       编制一个词法分析程序

二、实验内容和要求

     1.输入:源程序字符串

     2.输出:二元组(种别,单词本身)

单词与种别码

三、实验方法、步骤及结果测试

    (一).原理分析及流程图

      1.原理分析   

         存储结构:此词法分析程序,我采用的主要存储结构有链队列和指针数组。链队列用于存        储输入的原程序,之所以考虑用链队列,是因为链队列是需要时才申请空间的,更重要的原因      是链队列是先进先出的,这符合我要编写的词法分析程序,而数组是在定义时就要设置好它的      容量,系统会为其分配一个固定容量的存储空间,数组一旦创建后,它的容量就不能更改,所      以它很容易造成数组越界而导致程序终止,数组容量过大就会浪费存储空间,会影响程序的运      行速度。此程序指针数组是用于存储关键字、符、算符、界符等已知其需要多大存储空间的字      符,而且程序上涉及的种别码可以通过获取数组下标得到。

         主要算法:先将源程序用链队列存储起来,然后逐一从链队列中取出单个字符分析,具体         实 现,看下面的流程图

     关键函数的实现:

      void InitQueue()      //初始化一个带节点的空队列

      void Printf()         //输出原程序

      int search(char searchstr[],int wordtype)//符号匹配 返回种别码

      void Analyze()   //词法程序分析

   2.流程图

 

2.主要程序段及其解释:

 1 void Analyze()
 2 {
 3     char str;
 4     char letter[20];         //存放字母的数组
 5     char num[20];          //存放数字的字符数组
 6     char other[20];          //存放其他字符的数组
 7     int i;                  
 8     do                     //循环获取字符分析
 9     {
10         Q.front=Q.front->next;        //获取单个字符 
11         str=Q.front->ch;              //出队列
12         if (isalpha(str)!=0)        //如果是字符 
13         {
14             i=-1;
15            while (isalnum(str)!=0)         //判断下一个字符是否是字母
16           {  
17             letter[++i]=str;                //将字母存放到字符数组
18             Q.front=Q.front->next;          //出队列
19             str=Q.front->ch;               //获取下一个字符
20           }  
21            letter[i+1]='';                 //字符串的结束
22            if (search(letter,1)!=-1) // 调用int search(char searchstr[],int wordtype)函数,判断该字符串是否能和指针数组中的字符串匹配
23           {  
24             printf("( %d,%s )
",search(letter,1),letter);//输出种别码和单词本身
25             
26           }  
27           else  
28           {  
29               printf("( %d,%s )
",71,letter);        //输出种别码和单词本身
30            }  
31         }    
32         else  
33         {  
34             if (isdigit(str)!=0)      //判断是否为数字
35             {
36                 i=-1;
37                 while (isdigit(str)!=0)  //判断下一个字符是否为数字
38                 {  
39                    num[++i]=str;    //将数字存放到数字字符数组里去
40                    Q.front=Q.front->next;    //出队列
41                    str=Q.front->ch;    //获取下一个字符
42                 }  
43                 if(isalpha(str)!=0)         //数字后面是字符   
44                 {  
45                     while(isspace(str)==0)  
46                    {  
47                      num[++i]=str; 
48                      Q.front=Q.front->next;   //出队列
49                      str=Q.front->ch;         //获取下一个字符
50 
51                     }  
52                    num[i+1]='';     //字符串的结束
53                    printf("错误!非法标识符:%s
",num);  
54                 
55                 }  
56                 num[i+1]='';  
57                 printf("( %d,%s )
",72,num);      
58             }
59             else  
60             {
61               i=-1;    
62               if (isspace(str)!=0)     //判断是否为空格
63               {  
64                  Q.front=Q.front->next;   //出队列,即跳过空格
65                  str=Q.front->ch;        //获取下一个字符
66                  
67               }  
68               while ((isspace(str)==0)&&(isalnum(str)==0))    
69               {  
70                   other[++i]=str;  
71                   Q.front=Q.front->next;
72                  str=Q.front->ch; 
73                 
74                  
75                }  
76                   other[i+1]='';  
77               if (search(other,2)!=-1)  
78                   printf("( %d,%s )
",search(other,2),other);     //输出种别码和单词本身
79               else if (search(other,3)!=-1)  
80                   printf("( %d,%s )
",search(other,3),other);  //输出种别码和单词本身
81               else if (search(other,4)!=-1)  
82                   printf("( %d,%s )
",search(other,4),other);  //输出种别码和单词本身
83               else if (search(other,5)!=-1)  
84                   printf("( %d,%s )
",search(other,5),other);  //输出种别码和单词本身
85               else if (search(other,6)!=-1)  
86                   printf("( %s,注释符号 )
",other);  //输出种别码和单词本身
87               else if (search(other,7)!=-1)  
88                   printf("( %d,%s )
",search(other,7),other);  //输出种别码和单词本身
89               else   
90                   printf("错误!非法字符:%s
",other);  
91             }
92         }  
93     }while(Q.front!=Q.rear);  
94      printf("词法分析结束,谢谢使用!
"); 
95 }

3.  运行结果及分析

四、 实验总结

      难点一:. 想将字符串存进数组中去,觉得这样获取种别码比较简单,但是用没有加指针的数组会报错

      解决方法:用一个指针数组存储就可以解决这一问题。

      难点二:如果将所有的字符和数字都存储在同一指针数组,那样指针数组看起来太长,且分析时也比较浪费时间,每次都要从头开始匹配

       解决方法:按类型将字符串和字符分别放在不同的指针数组中,获取种别码时要加上前一个数组的长度。

      难点三:.输入原程序后,对原程序的分析时,要判断各种字符和数字,判断条件太多,代码长且难看懂,很容易把自己绕晕。

      解决方法:调用#include<ctype.h>库函数里的字符类型判断的函数,这样可以使代码简洁易懂。

             

原文地址:https://www.cnblogs.com/crx234/p/5957998.html