词法分析实验报告

时间:2024.4.20

实验名称:词法分析器

 级:计科0705

 名:

 号:

20##年4月29日

词法分析器

一.   实验目的要求

    用C语言编写一个词法分析器,使之能识别输入串,并把分析结果(单词符号,标识符,关键字等等)输出。输入源程序,输出单词符号,本词法分析器可以辨别关键字,标识符,常数,运算符号,逻辑符号和某些界符,运用了文件读入来获取源程序代码,再对该源程序代码进行词法分析,逐个识别出其中的单词,并将其转换为内部编码形式的单词符号串作确为输出。通常,可采用二元式 (value,class) 来表示一个单词符号的内部编码,其中:class为一类型码,用于表示该单词的类别;value则是该单词之值。

二.  单词分类表

将单词分为五类:

    

 1.:保留字 2:标识符 3:数字符 4:运算符 5:界符

1.对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。

2.本程序我们自行规定(即单词分类表):

(1)关键字:

"auto","double","union","int","struct","break","else","long","switch","case","enum",

"register","typedef","char","extern", "return","const","float","short","unsigned","continue","for","signed","void","default","goto","sizeof", "volatile","do","while","static","if"};

运算符: "+","-","*","/","="

界符:  ",",";","{","}","(",")","[","]",".","#"

(4)其他标记  如字符串,表示以字母开头的标识符。

(5)空格、回车、换行符过滤。

在屏幕上显示如下:

=>1    保留字

 =>2    标识符

 =>3    数字符

 =>4    运算符

 =>5    界符

三.单词状态图

词法分析实验报告

四.算法描述

         由主程序main()先调入index()函数进入主界面,用户根据提示输入要进行词法分析的文件,然后进入analysis()函数调入用户输入的文件进行分析。当所读入的文件不为空时开始分析,1:进行注释判断,将注释消除 2:过滤空格及判断出的注释符 3:判断标识符和保留字 4:判断数字 5:判断运算符和界符(同时进行括号匹配)6:在各部分中增加相对的错误提示 7:将结果输出到界面以及相应的out.txt

五.程序结构

#define Baoliuzi 1

#define Biaoshifu 2

#define Shuzifu 3

#define Yunsuanfu 4

#define Jiefu 5

int main()

int analysis()  /*用来实现:读写文件,判断注释,对空格进行过滤 ,判断注释符,判断标识符和保留字,判断是数字,判断是运算符或者是界符,判断括号匹配。*/

int letterjudge(char ch)   //判断一个字符是否是字母

int numberjudge(char ch)   //判断一个字符是否是数字

六.运行调试结果

      通过运行调试,初步实现所需功能,报错功能仍有较大空间提高

七.个人在词法分析器中的任务

   我在里面负责判断标识符,保留字,数字。

int letterjudge(char ch);

int numberjudge(char ch);  

并且参与程序整体的维护和构架,以及几大模块之间的衔接。在标识符和保留字中,充分利用文件的一些操作和程序。在数字判断方面考虑到数字的类型,分类进行处理,最后的判断输出到文件out.txt中。

八.设计技巧及体会

         进行词法分析器之前,现在网上参考了一些分析器的设计思路,从而确定了自己的设计方向,开始设计完成后仅仅是不到二百行的一个简易程序,通过观察老师检查别的设计小组时提出的问题,发现自己的程序仍存在很大的缺陷,例如:没有报错,无法消除注释和注释符,相同的标识符在输出文件中重复出现。通过全组人员不断的修改调试以及运行结果检测,程序的应用性有了很大的提高。

         通过这次程序设计,加强了我与人配合共同完成一个程序的合作经验,并且更加清楚明白了许多程序设计时需要注意到的细节问题,熟悉了程序语言及构造词法分析器的原理,总之,这次试验让我受益匪浅。

      (注:源程序清单请见电子版,稍后附上)

     (组员:(1)组长:赵楠(2)郑磊(3)孙龙飞)

总体代码如下:

#include

#include

#include

#define Baoliuzi 1

#define Biaoshifu 2

#define Shuzifu 3

#define Yunsuanfu 4

#define Jiefu 5

char *baoliuzi[32]={"auto","double","union","int","struct","break","else","long","switch","case","enum","register","typedef","char","extern", "return","const","float","short","unsigned","continue","for","signed","void","default","goto","sizeof", "volatile","do","while","static","if"};

char *yunsuanfu[5]={"+","-","*","/","="};

char *jiefu[10]={",",";","{","}","(",")","[","]",".","#"};

//函数声明

int analysis();

int letterjudge(char ch);

int numberjudge(char ch);

void index()

{

       printf("\n\t\t=========***********欢迎使用词法分析器************==========\n");

       printf("\n\t\t\t");

       printf("\n\t\t\t\t");

       printf("\n\t\t\t");

       printf(" \t ##本词法分析器可为您分析出## \n");

       printf("\n");

       printf("\n");

       printf("\n");

       printf(" \t\t      =>1    保留字\n");

       printf(" \t\t      =>2    标识符\n");

       printf(" \t\t      =>3    数字符\n");

       printf(" \t\t      =>4    运算符\n");

       printf(" \t\t      =>5    界符\n");

       printf("\n\t");

       printf("\n"); 

       printf("\n");

}

//*************************************************************

     int analysis()//词法分析程序算法

        {

              int i=0,k=0;   //k用来表示标识符存储下标

              int sBracketL=0,sBracketR=0,mBracketL=0,mBracketR=0,bBracketL=0,bBracketR=0;  //括号匹配

              char ch;

        char name[20];

             

              char save[20][20]={'\0'};   //用来存储标识符

             

              FILE *fpin;

              FILE *fpout;

              //文件操作

              printf("\n\t\t======================词法分析器======================\n");

              printf("\n\n\t\t请输入需要分析的文件的文件名:");

                       scanf("%s",&name);

                      

              if((fpin=fopen(name,"r"))==NULL)

              {

                     printf ("\t无法打开文件,请重新查看!\n");

                  return(1);

              }

              if((fpout=fopen("out.txt","w+"))==NULL)

              {

                     printf ("\t无法打开文件,请重新查看!\n");

                  return(1);

              }

        printf("\n\t\t=========================词法分析开始======================\n");

              ch=fgetc(fpin);  //获取文件的第一个字符

             

              //对读取进来的字符进行判断

              while(ch!=EOF)

              {

            int a,b,c;

            char buffer[20]={'\0'};  //暂时存储从文件读来的字符并且对buffer进行清空

                             

                  if(ch==EOF) //判断文件是否为空

                     {

                    fclose(fpin);

                      fclose(fpout);

                  }

      

//*************************************判断注释

                     if(ch=='/')

                     {

                            ch=fgetc(fpin);

                            if(ch=='/')                 //消除注释符//后的注释

                            {

                    while(ch!='\n')

                    {     

                                          ch=fgetc(fpin);

                                   }

                                   ch=fgetc(fpin);

                                   continue;

                            }

                            else if(ch=='*')

                            {

                      int flag=0;

                   ch=fgetc(fpin);

                   while(flag!=2)

                               {                   //当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束

                      flag=0;

                      while(ch!='*')

                        ch=fgetc(fpin);

                      flag++;

                      ch=fgetc(fpin);

                      if(ch=='/')

                        flag++;

                      else

                        ch=fgetc(fpin);

                               }

                            }

                else    //若为除号写入输出文件

                            {

                                   buffer[0]=ch;

                    printf("\n\t%s是运算符\n",buffer);

                                fprintf(fpout,"(%i,\"%s\")\n",Yunsuanfu,buffer);  //输出到文件

                             break;

                            }

                        

                            ch=fgetc(fpin);

                            continue;

                           

                     }

           

      

 //*****************************对空格进行过滤    

                     if(ch=='09'||ch=='10'||ch=='12'||ch=='13'||ch==' ')  

                    ch=fgetc(fpin);       //获取文件的下一个字符

 //******************************判断注释符                  

                     if(ch=='\\')  

                     {

                            ch=fgetc(fpin);

                            switch(ch)

                            {

                          case 'n': ;    //  \n  回车换行               10

                              case 't': ;    //  \t  横向跳到下一制表位置   9

                              case 'r': ;    //  \r  回车                   13

                              case 'f': ;    //  \f  走纸换页               12

                             

                              default: ;

                            }

                         ch=fgetc(fpin);

                            continue;

                     }  

                 

                  a=letterjudge(ch);     // a表示字母函数的返回值

                  b=numberjudge(ch);     // b表示数字函数的返回值

                           

                  

 //*********************************判断标识符和保留字

                  if(a==1)         //下一个字符为字母

                  { 

                     int r1,r2;

                     int j=0;

                        while(a)

                        {

                          int m,n;

                           m=letterjudge(ch);     // a表示字母函数的返回值

                           n=numberjudge(ch);     // b表示数字函数的返回值

                                              

                           if(m==1||n==1)

                              {

                             buffer[j]=ch;

                             ch=fgetc(fpin);

                              j++;

                              }

                          else break;

                        }

                       

                         for(i=0;i<32;i++)

                            {

                                r1=strcmp(baoliuzi[i],buffer);   //将字符串同保留字串相对比

                                if(r1==0)

                                   {

                                        printf("\n\t%s是保留字\n",buffer); //输出到界面上

                                     fprintf(fpout,"(%i,\"%s\")\n",Baoliuzi,buffer);  //输出到文件

                                       break;

                                   }

                            }

                         if(r1!=0)       

                            { 

                                for(i=0;i<20;i++)   //判断标识符是否已经出现过

                                   {

                                          r2=strcmp(save[i],buffer);  

                                          if(r2==0)

                                                 break;

                                   }

                                   if(r2!=0)

                                   {

                                          strcpy(save[k],buffer);

                                          printf("\n\t%s是标识符\n",buffer);

                        fprintf(fpout,"(%i,\"%s\")\n",Biaoshifu,buffer);

                                       k++;

                                   }

                            }

                      continue;    //接受下一个字符串

                     }

  

//*************************判断是数字     b表示数字函数的返回值

                  else  if(b==1) 

                     {

                     int j=0;

                     int flag=0;     //小数点个数判断

                        while(b)

                        {

                     

                        int m,n;

                                           

                       m=letterjudge(ch);

                        n=numberjudge(ch);

                       if(n==1)

                             {

                          buffer[j]=ch;

                          ch=fgetc(fpin);

                          j++;

                             }

                       else break;

                             

                             if(letterjudge(ch)==1)    //判断数字后面时候存在标识符

                             {

                               printf("\n\t数字串后出现标识符,出错!按任意键退出修改源文件!");  //出现标识符则报错

                   getchar();

                               getchar();

                               exit (1);

                             }

                             

                             

                             if(ch==*jiefu[6])   //判断数字后面是否存在小数点

                             {

                               

                                   flag++;    //小数点个数加一

                                   if(flag>1)   //出现一次以上的小数点则报错

                                   {

                                     printf("\n\t数字串中存在一个以上小数点,出错!按任意键退出修改源文件!\n");

                      getchar();

                                     getchar();

                                     exit (1);

                                   }

                                   else

                                   {

                                       buffer[j]=ch;

                                          j++;

                                          ch=fgetc(fpin);       //如果是一个小数点则继续读下一个数字

                    }

                             }

                        }

               printf("\n\t%s是数字\n",buffer);

                     fprintf(fpout,"(%i,\"%s\")\n",Shuzifu,buffer);  //输出到文件

                     continue;

                     }

    

  //***********************************判断是运算符或者是界符

                  else

                     {

                      int r1,r2;

                      char ch1;

                            buffer[0]=ch;

                             

                                  

                     //判断是运算符                  

                       for(i=0;i<5;i++)

                             {

                            r1=strcmp(yunsuanfu[i],buffer);

                              if(r1==0)

                                    {

                                 if(ch=='+')

                                          {

                                                 ch1=fgetc(fpin);

                                                 if(ch1=='+')       //判断++符号

                                                 {

                                                        buffer[1]=ch1;

                                                        printf("\n\t%s是运算符\n",buffer);

                                                  fprintf(fpout,"(%i,\"%s\")\n",Yunsuanfu,buffer);  //输出到文件

                                         break;

                                                 }

                                                 else if(ch1=='=')       //判断+=符号

                                                 {

                                                        buffer[1]=ch1;

                                                        printf("\n\t%s是运算符\n",buffer);

                                                  fprintf(fpout,"(%i,\"%s\")\n",Yunsuanfu,buffer);  //输出到文件

                                         break;

                                                 }

                                                 else        //否则输出运算符+

                                                 {

                                                        printf("\n\t%s是运算符\n",buffer);

                                                  fprintf(fpout,"(%i,\"%s\")\n",Yunsuanfu,buffer);  //输出到文件

                                         break;

                                                 }

                                          }

                                          else if(ch=='-')

                                          {

                                                 ch1=fgetc(fpin);

                                                 if(ch1=='-')       //判断--符号

                                                 {

                                                        buffer[1]=ch1;

                                                        printf("\n\t%s是运算符\n",buffer);

                                                  fprintf(fpout,"(%i,\"%s\")\n",Yunsuanfu,buffer);  //输出到文件

                                         break;

                                                 }

                                                 else if(ch1=='=')       //判断-=符号

                                                 {

                                                        buffer[1]=ch1;

                                                        printf("\n\t%s是运算符\n",buffer);

                                                  fprintf(fpout,"(%i,\"%s\")\n",Yunsuanfu,buffer);  //输出到文件

                                         break;

                                                 }

                                                 else        //否则输出运算符-

                                                 {

                                                        printf("\n\t%s是运算符\n",buffer);

                                                  fprintf(fpout,"(%i,\"%s\")\n",Yunsuanfu,buffer);  //输出到文件

                                         break;

                                                 }

                                          }

                                          else

                                          {

                                                 ch1=fgetc(fpin);    //判断*=,/=,==

                                                 if(ch1=='=')

                                                 {

                                buffer[1]=ch1;

                                                        printf("\n\t%s是运算符\n",buffer);

                                                  fprintf(fpout,"(%i,\"%s\")\n",Yunsuanfu,buffer);  //输出到文件

                                         break;

                                                 }

                                                 else

                                                 {

                                                        printf("\n\t%s是运算符\n",buffer);

                                                  fprintf(fpout,"(%i,\"%s\")\n",Yunsuanfu,buffer);  //输出到文件

                                         break;

                                                 }

                                          }

                           

                                    }

                             }

         

              //判断是界符

                       for(i=0;i<10;i++)

                             {

                                    r2=strcmp(jiefu[i],buffer);

                                    if(r2==0)

                                    {

                                           /*switch(ch)     //计算括号数

                                           {

                                           case '(': sBracketL++;

                                           case ')': sBracketR++;

                                           case '[': mBracketL++;

                                           case ']': mBracketR++;

                                           case '{': bBracketL++;

                                           case '}': bBracketR++;

                         defaule: break;

                                           }*/

                                           if(ch=='(')       //计算括号数

                                                  sBracketL++;

                                           else if(ch==')')

                                                  sBracketR++;

                                           else if(ch=='[')

                                                  mBracketL++;

                                           else if(ch==']')

                                                  mBracketR++;

                                           else if(ch=='{')

                                                  bBracketL++;

                                           else if(ch=='}')

                                                  bBracketR++;

                                           else continue;

                                           

                                           printf("\n\t%s是界符\n",buffer);

                                        fprintf(fpout,"(%i,\"%s\")\n",Jiefu,buffer);   //输出到文件

                                         break;

                                    }

                             }

                            ch=fgetc(fpin);

                            continue;              

                     }

  

            break;

         }

        

               printf("%d!!!",sBracketL);

                printf("%d!!!",sBracketR);

                            printf("%d!!!",mBracketL);

                printf("%d!!!",mBracketR);

         if(sBracketL!=sBracketR)             //判断括号匹配

               {

                      printf("\n\t小括号匹配出现问题!按任意键退出修改源文件!\n");

                      getchar();

                      getchar();

                      exit (1);

               }

               if(mBracketL!=mBracketR)

               {

                      printf("\n\t中括号匹配出现问题!按任意键退出修改源文件!\n");

                      getchar();

                      getchar();

                      exit (1);

               }

               if(bBracketL!=bBracketR)

               {

                      printf("\n\t大括号匹配出现问题!按任意键退出修改源文件!\n");

                  getchar();

                      getchar();

                      exit (1);

               }

               

               return 0;

     }                    

//************************判断一个字符是否是字母

   int letterjudge(char ch)

   {

   int flag=0;

   if((ch >= 'a' && ch<='z')||(ch>='A' && ch<='Z'))

    flag=1;

       return flag;

  }

//************************判断一个字符是否是数字

   int numberjudge(char ch)

   {

   int flag=0;

   if(ch>='0' && ch<='9')

    flag=1;

       return flag;

  }

int main()  //主函数

{

index();

analysis();

printf("\n");

printf("\n");

printf("\n\t\t========================词法分析完毕=========================\n");

getchar();

getchar();

return(0);

}

更多相关推荐:
词法分析实验报告

计科101左朝阳词法分析器一实验目的通过设计编制调试一个具体的词法分析程序加深对词法分析原理的理解并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法编制一个读单词过程从输入的源程序中识别...

词法分析器_实验报告

词法分析器实验报告实验目的设计编制调试一个词法分析子程序识别单词加深对词法分析原理的理解实验要求该程序要实现的是一个读单词过程从输入的源程序中识别出各个具有独立意义的单词即基本保留字标识符常数运算符分界符五大类...

编译原理实验报告词法分析

编译原理实验报告词法分析器学院计算机科学与技术时间20xx69一问题描述选择计算机高级程序语言之一C语言运用恰当的词法分析技术线路设计和实现其对应的词法分析器提示技术线路选择如下两种之一正则式NFADFAmin...

实验一 词法分析实验报告

实验一 词法分析实验报告,内容附图。

编译原理词法分析实验报告

词法分析器实验报告按<<>编译原理>课程的要求,根据词法分析器的基本原理,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。一、实验要求2.1待分析的简单的词法(1)关键字:beginifthenwh…

词法分析实验报告(含代码)

词法分析一实验目的通过本教材附录B词法分析程序调试改编一个词法分析程序加深对词法分析原理的理解二实验要求21待分析的简单的词法1保留字ifelseforwhiledointreadwriterealchar2纯...

编译原理词法分析器实验报告

曲阜师范大学实验报告计算机系20xx年级软件工程一班组日期20xx年10月17日星期日姓名陈金金同组者姓名课程编译原理成绩实验名称教师签章词法分析器一实验目的1掌握词法分析的原理2熟悉保留字表等相关的数据结构与...

编译原理词法分析实验报告1

实验1词法分析实验报告一实验目的调试并完成一个词法分析程序加深对词法分析原理的理解二实验要求1待分析的简单语言的词法beginifthenwhiledoend所有关键字都是小写2运算符和界符ltltltgtgt...

《编译原理》课程实验报告(词法分析)完整版

编译原理课程实验报告题目专业计算机指导教师签名华东理工大学信息学院计算机系20xx年4月10日一实验序号编译原理第一次实验二实验题目词法分析三实验日期20xx32720xx410四实验环境操作系统开发语言操作系...

C_minus语言词法分析器实验报告--宁剑

编译原理实验报告题目:C_minus语言词法分析器学院计算机科学与技术专业学号姓名指导教师20xx年xx月xx日C_minus语言词法分析器一、实验目的1.理解词法分析器的设计方法:利用DFA编写相应的程序。2…

编译原理语法分析实验报告

实验2语法分析1实验题目和要求题目语法分析程序的设计与实现实验内容编写语法分析程序实现对算术表达式的语法分析要求所分析算术表达式由如下的文法产生EETETTTTFTFFFidEnum实验要求在对输入表达式进行分...

LL(1)语法分析设计原理与实现技术实验报告文档

LL1语法分析设计原理与实现技术实验报告LL1语法分析设计原理与实现技术实验报告1LL1语法分析设计原理与实现技术实验报告变更说明2LL1语法分析设计原理与实现技术实验报告一实验目的本实验的目的在于在教师的引导...

词法分析实验报告(31篇)