• 词法分析之实验报告


     词法分析实验

    一、实验目的

           编制一个词法分析程序

    二、实验内容和要求

         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>库函数里的字符类型判断的函数,这样可以使代码简洁易懂。

                 

  • 相关阅读:
    学生排队 201703-2
    让动画停在最后一帧 forwards animation-fill-mode
    新版本的charles代理本地接口
    移动端调试插件Tencent / vConsole
    HDU
    Codeforces Round #668 (Div. 2)(A B C D)
    The 13th Chinese Northeast Collegiate Programming Contest
    2020, XIII Samara Regional Intercollegiate Programming Contest (B D)
    tarjan算法 双连通分量
    Codeforces Round #666 (Div. 2) (A B C D)
  • 原文地址:https://www.cnblogs.com/crx234/p/5957998.html
Copyright © 2020-2023  润新知