词法分析实验报告

时间:2024.5.15

词法分析器

一、实验目的:

通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。

编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。

二、实验要求

文本框: (1,”main”)
(5,”(“)
(5,”)“)
(5,”{“)
(1,”int”)
(2,”a”)
(5,”,”)
(2,”b”)
(5,”;”)
(2,”a”)
(4,”=”)
(3,”10”)
(5,”;”)
(2,”b”)
(4,”=”)
(2,”a”)
(4,”+”)
(3,”20”)
(5,”;”)
(5,”}“)
如源程序为C语言。输入如下一段:

main()

{

int  a,b;

a = 10;

    b = a + 20;

}#

要求输出如右图。

要求:

1、将单词分为五种

识别关键字:main、if、int、for、while、do、return、break、continue;单词种别码为1。

标识符;单词种别码为2。

常数为无符号整形数;单词种别码为3。

运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;

单词种别码为4。

分隔符包括:,、;、{、}、(、); 单词种别码为5。

2、使用一符一种的分法

关键字、运算符和分界符可以每一个均为一种

标识符和常数仍然一类一种

三、实验内容

1、功能描述

改程序是一个实现词法分析的功能,能识别5种单词,其他单词报错。

2、程序结构描述

int IsKey(char *Word)关键字匹配函数,查询是否为关键字,若是,返回值为1,否则为0。

int IsAlpha(char c) 查看是否为字母,若是,返回值为1,否则为0。

int IsNum(char c)  查看是否为数字,若是,返回值为1,否则为0。

void scanner(FILE *fp) 扫描函数,扫描程序中的字符串并调用上述三种函数检查是否是字母、数字,是否是关键字,并输出。

fseek(fp,-1,1) 回退一个字符。

fgetc(fp) 从数据流中区下一个字符。

fopen  文件打开函数,返回指向文件第一个字符的指针

四、实验结果

测试内容为

main()

{

int  a,b;

a = 10;

b = a + 20;

}#

结果

测试代码为

void main()

{

int  a,b;

if(a = 10;)

b +=   20;

c=%;

}#

结果为

测试代码

main()

{

int  a,b;

if(a <= "10")

b +=   20;

c=%@;

return 0;

}#

结果

五、实验过程记录

1、因为用到回退函数fseek(),而以前没有用过这个函数,所以开始时很苦恼,不知道如何回退一个字符,后来问了同学,才明白原来有这么一个函数,顿时豁然开朗。

2、本次试验中word[20]保存字符串时,不能正确保存,总是出错,原因是while(IsNum(ch)||IsAlpha(ch)){  

            Word[i]=ch;

            i++;

            ch=fgetc(fp);

           }中,i++与Word[i]=ch;次序不对,后来多次思索,发现问题。

六、实验总结

本次实验花了将近一个下午才完成。在纸上设计的时间大约40分钟,剩下的时间是录入和调试。本次实验使我认识到,一段时间搁置,不编程序,水平会下降,好多有关c语言的知识会忘掉,所以以后我会经常写写程序。另外,通过本次实验,我又进一步加深对词法分析原理的理解。总的来说,获益匪浅!

附录

#include<string.h>

#include<stdio.h>

#include<stdlib.h>

#include<ctype.h>

#include<iostream.h>

                                    Char*Key[9]={"void","main","int","if","then","else","return","break","continue"};

char ch;                   // 存储识别出的单词流

int IsAlpha(char c) {                //判断是否为字母

    if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;

    else return 0;

}

int IsNum(char c){                //判断是否为数字

    if(c>='0'&&c<='9') return 1;

    else return 0;

}

int IsKey(char *Word){          //识别关键字函数

    int m,i;

    for(i=0;i<8;i++){

       if((m=strcmp(Word,Key[i]))==0)

           return 1;

      

    }

      return 0;

}

void scanner(FILE *fp){        //扫描函数

    char Word[20]={'\0'};

    char ch;

    int i,c;

    ch=fgetc(fp);        //获取字符,指针fp并自动指向下一个字符

    if(IsAlpha(ch)){            //判断该字符是否是字母

       Word[0]=ch;

       ch=fgetc(fp);

       i=1;

       while(IsNum(ch)||IsAlpha(ch)){   //判断该字符是否是字母或数字

           Word[i]=ch;

           i++;

           ch=fgetc(fp);

          }

       Word[i]='\0';       //'\0' 代表字符结束(空格)

       fseek(fp,-1,1);                              //回退一个字符

       c=IsKey(Word);                              //判断是否是关键字

       if(c==0) cout<<"(2,"<<Word<<')'<<endl;//不是关键字

       else     cout<<"(1,"<<Word<<')'<<endl;      //输出关键字

      }

      else                          //开始判断的字符不是字母

         if(IsNum(ch)){                //判断是否是数字

              Word[0]=ch;

              ch=fgetc(fp);

              i=1;

              while(IsNum(ch)){

                   Word[i]=ch;

                   i++;

                   ch=fgetc(fp);

               }

               Word[i]='\0';

               fseek(fp,-1,1);                    //回退

              cout<<"(3,"<<Word<<')'<<endl;

          }

          else         //开始判断的字符不是字母也不是数字

          {

              Word[0]=ch;

              switch(ch){

              case'[':

              case']':

              case'(':

              case')':

              case'{':

              case'}':

              case',':

              case'"':

              case';':cout<<"(5,"<<Word<<')'<<endl; break;

              case'+':ch=fgetc(fp);

                     if(ch=='='||ch=='+'){

                     Word[1]=ch;

                    cout<<"(4,"<<Word<<')'<<endl;//运算符"+="或判断结果为"++"

                     }

                     else {

                     fseek(fp,-1,1);

                     cout<<"(4,"<<Word<<')'<<endl;//判断结果为"+"

                     }

                     break;

              case'-':ch=fgetc(fp);

                     if(ch=='='||ch=='-'){

                        Word[1]=ch;

                     cout<<"(4,"<<Word<<')'<<endl;                 }

                     else {

                     fseek(fp,-1,1);

                    cout<<"(4,"<<Word<<')'<<endl; //判断结果为"-"

                     }

                     break;

              case'*':

              case'/':

              case'!':

              case'=':ch=fgetc(fp);

                      

                 if(ch=='='){

                          Word[1]=ch;

                        cout<<"(4,"<<Word<<')'<<endl;

                     }

                     else {

                     fseek(fp,-1,1);

                     cout<<"(4,"<<Word<<')'<<endl;

                     }

                     break;

              case'<':ch=fgetc(fp);

                    

                     if(ch=='='||ch=='<'){

                        Word[1]=ch;

                        cout<<"(4,"<<Word<<')'<<endl;

                     }

                     else {

                     fseek(fp,-1,1);

                     cout<<"4\t"<<Word<<endl; //判断结果为"<"

                     }

                     break;

               case'>':ch=fgetc(fp);

                     if(ch=='='||ch=='>')

                     {

                        Word[1]=ch;cout<<"(4,"<<Word<<')'<<endl;

                     }

                     else {

                       fseek(fp,-1,1);

                      cout<<"(4,"<<Word<<')'<<endl;

                     }

                     break;

              default:

                 cout<<"(无法识别字符,"<<Word<<')'<<endl; break;

              }

          }

}

void main()

{

    FILE *fp;

    fp=fopen("c:\\1.txt","r");

   if(fp==NULL)   //读取文件内容,并返回文件指针,该指针指向文件的第一个字符

   {cout<<"读入文件错误!"<<endl;

   exit(0);

    }

cout<<"******************* 词法分析结果如下 *******************\n";

 while(ch!='#'){

     ch=fgetc(fp);

     if(ch=='#')   break;         //文件以#结尾,作为扫描结束条件

     else if(ch==' '||ch=='\t'||ch=='\n'){} //忽略空格,空白,和换行

     else{

        fseek(fp,-1,1);           //回退一个字节开始识别单词流

        scanner(fp);

     }

 }

 }


第二篇:词法分析实验报告1


一.目的与要求:通过编写并上机调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将其分解后各类单词的词法分析方法。

二.实验内容:

输入:据教学要求和学生具体情况,从具有代表性的高级程序设计语言中,选取一个适当大小的子集,例如可以选取一类典型单词,也可以尽可能使各种类型的单词都能兼顾到。

输出:单词串的输出形式,所输出的每一单词均按形如(CLASS,VALUE)的二元式编码。对于变量和常数,CLASS字段为相应的类别码,VALUE字段则是该标识符、常数在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。对于关键字和分隔符,采用一词一类的编码形式。由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。不过,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上直接放置单词符号串本身。

三.处理过程:在扫描源程序字符串时,一旦识别出关键字、分隔符、标识符、无符号常数中之一,即以单词形式(各类单词均采用相同的结构,即二元式编码形式)输出。每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直至整个源程序全部扫描完毕,并形成相应的单词串形式的源程序。具体方法如下:

(一)单词的分类:构造上述语言中的各类单词符号及其分类码表如下:

(二)状态转移矩阵

 

(三)词法分析过程

四、词法分析程序的功能

输入:所给文法的原程序字符串。

输出:二元数组。

如:main() { int x,y; x=9; x>=y; return; }#

输出结果为:

(1, main)

error!

error!

(17, {)

(2, int)

(6,x)

(14,,)

(6,y)

(15,;)

(6,x)

(13,>=)

(6,return)

(15,;)

(18,})

五.源程序

#include<string.h>

#include<stdio.h>

#include<stdlib.h>

#include<ctype.h>

char *table[7]={" ","main","int","if","then","else","return"},TOKEN[20],ch;  //定义关键字

int lookup(char *TOKEN){       //关键字匹配函数

      int m,i;

      for(i=1;i<6;i++){

           if((m=strcmp(TOKEN,table[i]))==0)

               return(i);

      }

      return(0);

}

void out(int c,char *TOKEN){      //输出函数

      printf("(%d,%s)\n",c,TOKEN);

}

void scanner(FILE *fp){            //扫描函数

      char TOKEN[20]={'\0'};

      char ch;

      int i,c;

      ch=fgetc(fp);               //获取字符,指针fp并自动指向下一个字符

      if(isalpha(ch)){               //判断该字符是否是字母

           TOKEN[0]=ch;

           ch=fgetc(fp);

          i=1;

           while(isalnum(ch)){        //判断该字符是否是字母或数字

                 TOKEN[i]=ch;

                 i++;

                 ch=fgetc(fp);

           }

           TOKEN[i]='\0';

           fseek(fp,-1,1);            //回退一个字符

           c=lookup(TOKEN);

           if(c==0)

                 out(6,TOKEN);        //输出标识符

           else out(c,TOKEN);         //输出关键字

      }

      else

           if(isdigit(ch)){           //判断是否是数字

                 TOKEN[0]=ch;

                 ch=fgetc(fp);

                 i=1;

                 while(isdigit(ch)){

                      TOKEN[i]=ch;

                      i++;

                      ch=fgetc(fp);

                 }

                 TOKEN[i]='\0';

                 fseek(fp,-1,1);

                 out(7,TOKEN);

           }

           else

            {

               TOKEN[0]=ch;

               switch(ch){

                     case'{':out(17,TOKEN);

                            break;

                      case'}':out(18,TOKEN);

                            break;

                     case',':out(14,TOKEN);

                            break;

                      case';':out(15,TOKEN);

                            break;

                     case'<':ch=fgetc(fp);

                            TOKEN[1]=ch;

                          if(ch=='='){

                            out(9,TOKEN);

                      }

                          else if(ch=='>'){

                            out(11,TOKEN);

                      }

                          else {

                            fseek(fp,-1,1);

                            out(8,TOKEN);

                      }

                          break;

                     case'=':out(10,TOKEN);

                          break;

                    case'>':ch=fgetc(fp);

                            TOKEN[1]=ch;

                          if(ch=='=') out(13,TOKEN);

                          else {

                                fseek(fp,-1,1);

                                out(12,TOKEN);

                            }

                          break;

                     default:printf("error!\n");

                          break;

                 }

           }

}

main()

{

      FILE *fp;

      if((fp=fopen("E:\\222.txt","r"))==NULL){   //读取文件内容,并返回文件指针,该指针指向文件的第一个字符

           fprintf(stderr,"error opening.\n");

           exit(1);

      }

      do{

          ch=fgetc(fp);

           if(ch=='#')                //文件以#结尾,作为扫描结束条件            

                 break;

           if(ch==' ')                //如果是空格,自动跳到下个字符

                 scanner(fp);

           else{

                 fseek(fp,-1,1);        //如果不是空格,则回退一个字符并扫描

               scanner(fp);

           }

      }while(ch!='#');

      return(0);

}

六.函数说明

1. int lookup(char *TOKEN)  关键字匹配函数,查询所述程序中的关键字

2. void out(int c,char *TOKEN)  输出函数

3. void scanner(FILE *fp)  扫描函数,扫描程序中的字符串并调用lookup函数检查是否是关键字,再调用out函数输出二元组

4.fseek(fp,-1,1) 回退一个字符

5.isalpha(ch) 字母判断函数,若ch指的是字母,返回非0,否则返回0

6.isalnum(h) 字母或数字判断函数,若ch指的是字母或数字,返回非0,否则返回0

7.isdigit(ch) 数字判断函数,若ch指的是数字,返回非0,否则返回0

8.fgetc(fp) 从数据流中区下一个字符

9.fopen  文件打开函数,返回指向文件第一个字符的指针

七.实验结果及截图

 

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

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

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

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

实验一 词法分析实验报告

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

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

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

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

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

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

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

词法分析实验报告

编译原理实验名称:词法分析器班级:计科0705姓名:学号:20##年4月29日词法分析器一.实验目的要求用C语言编写一个词法分析器,使之能识别输入串,并把分析结果(单词符号,标识符,关键字等等)输出。输入源程序…

词法分析器实验报告

王超计科138词法分析器实验报告词法分析器设计一实验目的对C语言的一个子集设计并实现一个简单的词法分析器掌握利用状态转换图设计词法分析器的基本方法利用该词法分析器完成对源程序字符串的词法分析输出形式是源程序的单...

词法分析器的设计与实现 编译原理实验报告

中北大学软件学院实验报告专业课程名称学号姓名辅导教师张静成绩

实验安排+词法分析程序设计与实现

实验一词法分析程序设计与实现一实验目的加深对词法分析器的工作过程的理解加强对词法分析方法的掌握能够采用一种编程语言实现简单的词法分析程序能够使用自己编写的分析程序对简单的程序段进行词法分析二实验内容自定义一种程...

编译原理词法语法分析等实验1

实验一熟悉C语言的运行环境1实验目的11熟悉利用VisualC60编辑运行C程序的方法和步骤12运行调试简单的C语言程序2实验方法及步骤21熟悉利用VisualC60编辑运行C程序的方法和步骤1打开Visual...

词法分析器实验报告

词法分析器实验报告姓名实验内容用flex工具生成一个PL0语言的词法分析程序对PL0语言的源程序进行扫描识别出单词符号的类别统计输出各种符号的信息学号时间实验目的abcd理解编译器的工作机制掌握编译器的构造方法...

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