首页 范文大全 古典文学 职场知识 中国文学 公文书信 外国名著 寓言童话 百家讲坛 散文/诗歌 美文欣赏 礼仪知识 民俗风情
  • 范文大全
  • 古典文学
  • 职场知识
  • 中国文学
  • 公文书信
  • 外国名著
  • 寓言童话
  • 百家讲坛
  • 散文/诗歌
  • 美文欣赏
  • 礼仪知识
  • 民俗风情
  • 谜语大全
  • 名言警句
  • 编译原理实验词法分析实验报告

    时间:2020-07-20 11:45:03 来源:蒲公英阅读网 本文已影响 蒲公英阅读网手机站

    相关热词搜索:实验 词法 编译

      编译技术实验报告

     实验题目:

     词 词 法分析

     学 学

     院:

     信息学院

     专 专

     业:

     计算机科学与技术

     学 学

     号:

      姓 姓

     名:

     一、 实验目的

     (1) 理解词法分析的功能;

     (2) 理解词法分析的实现方法;

      二 、 实验内容

     PL0 的文法 如下

     „< >‟为非终结符。

     „::=‟ 该符号的左部由右部定义,可读作“定义为”。

     „|‟ 表示„或‟,为左部可由多个右部定义。

     „{ }‟ 表示花括号内的语法成分可以重复。在不加上下界时可重复0到任意次数,有上下界时可重复次数的限制。

     „[ ]‟ 表示方括号内的成分为任选项。

     „( )‟ 表示圆括号内的成分优先。

     上述符号为“元符号”, 文法用上述符号作为文法符号时需要用引号„‟括起。

      〈程序〉∷=〈分程序〉.

     〈分程序〉∷= [〈变量说明部分〉][〈过程说明部分〉]〈语句〉

     〈变量说明部分〉∷=VAR〈标识符〉{,〈标识符〉}:INTEGER;

     〈无符号整数〉∷=〈数字〉{〈数字〉}

     〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}

     〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉};

     〈过程首部〉∷=PROCEDURE〈标识符〉;

     〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉

     〈赋值语句〉∷=〈标识符〉∶=〈表达式〉

     〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END

     〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉

     〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉}

     〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}

     〈因子〉∷=〈标识符〉|〈无符号整数〉|"("〈表达式〉")"

     〈加法运算符〉∷=+|-

     〈乘法运算符〉∷=*

     〈关系运算符〉∷=<>|=|<|<=|>|>=

     〈条件语句〉∷=IF〈条件〉THEN〈语句〉

     〈字母〉∷=a|b|…|X|Y|Z

     〈数字〉∷=0|1|2|…|8|9

      现 实现 PL0 的 的 词法分析

     三 、 实验 分析与设计

     PL0 词法分析程序是一个独立的过程,其功能是为语法语义分析提供单词,把输入的字符串形式的源程序分割成一个个单词符号传递给语

     法语义分析。

     其主要方法步骤为从源程序扫描下一个字符,忽略空格、换行、TAB和注释并识别单词,再将不同类别的单词归类输出。

      四 、实验 的 实现

     #include <stdio.h>

     #include<stdlib.h>

     #include<string.h>

     #include<ctype.h>

     #include<stdbool.h>

      #definenorw 11

     //norw-1个关键字

     #defineal 20

     //最长的关键字的长度

     #define ID norw

     #define INT norw+1

     #define COMMA norw+2

     #define ENDF norw+3

     #define COLON norw+4

     #define SEMIC norw+5

     #define ADD norw+6

     #define MINUS norw+7

     #define MULTI norw+8

     #define EVALU norw+9

     #define LE norw+10

     #define NE norw+11

     #define LT norw+12

     #define EQ norw+13

     #define GE norw+14

     #define GT norw+15

     #define FLOAT norw+16

      char TOKEN[20];

     //字符数组用来依次存放单词词文的各个字符

     extern int lookup(char *);

      //以TOKEN字符串查保留字表

     extern void report_error(char);

     //报告程序中的词法错误

     bool isalpha(char);

     //判断接收字符是否为字母

     bool isalnum(char);

     //判断接收字符是否为字母或者数字

     bool isdigit(char);

     //判断接收字符是否为数字

     bool isannotation(char);

     //判断接收字符是否为注释

     extern char letter(char c); //用来将大写字母转化成小写字母

     FILE* fin;

     FILE* fout;

      void scanner()

     {//词法分析的主体程序,对输入的文本文件进行词法分析

      char ch;

      int i,c;

      int error=0;

      //记录文件中词法错误的个数

      ch=fgetc(fin);

     //从输入文件中读取一个字符

     while(ch!=EOF)

      {//当从输入文件接收的字符不是文件结束符时,执行循环

     if(isalpha(ch))

     {//如果从输入文件接收的第一个字符是字母

     ch=letter(ch);

      TOKEN[0]=ch;

      ch=fgetc(fin);i=1;

      while(isalnum(ch))

      {

     ch=letter(ch);

     TOKEN[i]=ch;i++;

     ch=fgetc(fin);

      }

      TOKEN[i]="\0";

      c=lookup(TOKEN);

      //查保留字表

      if(c==0) {fprintf(fout,"(%d,%s)\n", ID,TOKEN);} //输出标识符

      else fprintf(fout,"(%d,%s)\n", c,TOKEN);

     //输出接收单词为保留字

     }

     if(isdigit(ch))

      //如果从输入文件接收的第一个字符是数字

     {

     int cdot=0;

      //统计小数点个数

      TOKEN[0]=ch;

      ch=fgetc(fin);i=1;

      while(isdigit(ch)||ch==".")

      {//从第二个接收字符开始,当是数字或者是小数点时,执行循环

     if(ch==".")

     cdot++;

     TOKEN[i]=ch;i++;

     ch=fgetc(fin);//重复接收字符,直到接收到非数字

     if(cdot>=2)

     {

     error++;

     TOKEN[i]="\0";

     printf("%s is error\n", TOKEN);

     break;

     }

      }

      if(isalpha(ch)) //如果第二个字符是字母

      {

     while(isalpha(ch)) //接收完所有的字母,跳出循环

     {

      TOKEN[i]=ch;i++;

      ch=fgetc(fin);

     }

     TOKEN[i]="\0";

     error++;

     printf("%s is error\n", TOKEN);

      }

     else if(cdot==0)

     //当接收的字符为整型单词时

      {

     fseek(fin,-1,1);

      TOKEN[i]="\0";

     int a,temp=0,c;

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

     {

     a=TOKEN[c] - "0";

     if(c!=0)

     {

     temp=temp*10;

     temp=temp+a;

     }

     else

     {

     temp=a;

     }

     }

     fprintf(fout,"(%d,%d)\n", INT, temp);

     //输出接收单词为整数

      }

      else if(cdot==1)

     {

     fseek(fin,-1,1);

      TOKEN[i]="\0";

     int a,part1=0,jc,b=0;

      //b用来确定小数点所在的位置

     float c=0.1,part2=0.0;

     while(TOKEN[b]!=".")

     {

     b=b+1;

     }

     for(jc=0;jc<b;jc++)

     {

     a=TOKEN[jc] - "0";

     if(jc!=0)

     {

     part1=part1*10;

     part1=part1+a;

     }

     else

     {

     part1=a;

     }

     }

     for(jc=b+1;jc<i;jc++)

     {

     a=TOKEN[jc]-"0";

     part2=a*c+part2;

     c=c*0.1;

     }

     fprintf(fout,"(%d,%f)\n", FLOAT, part1+part2);

     //输出接收单词为小数

     }else if(cdot==2)

     {

     fseek(fin,-1,1);

     }

      }

      else

     //如果从输入文件接收的第一个字符既不是字母又不是数字

     switch(ch)

     {//将所接收到的符号字符进行分类,采取一符一类

      case":":ch=fgetc(fin);

     if(ch=="=") fprintf(fout,"(%d,:=)\n", EVALU);

      //输出接收符号为赋值号

      else

     {ch=fgetc(fin);

      fseek(fin,-1,1);

     //文件接收字符回推一个字符

      fprintf(fout,"(%d,":")\n", COLON);

      //输出冒号

     }

     break;

      case",":fprintf(fout,"(%d,",")\n", COMMA); break;

      //输出逗号

      case".":fprintf(fout,"(%d,".")\n", ENDF);break;

     //输出句号

      case";":fprintf(fout,"(%d,".")\n", SEMIC);break;

      //输出分号

      case"+":fprintf(fout,"(%d,"+")\n", ADD);break;

     //输出加号

      case"-":fprintf(fout,"(%d,"-")\n", MINUS);break;

      //输出减号

      case"*":fprintf(fout,"(%d,"*")\n", MULTI);break;

      //输出乘号

      case"<":ch=fgetc(fin);

     if(ch=="=")fprintf(fout,"(%d,"<=")\n", LE);

      //输出小于或等于号

     else if(ch==">")fprintf(fout,"(%d,"<>")\n", NE);

     //输出不等于号

     else

     {

     fseek(fin,-1,1);

     fprintf(fout,"(%d,"<")\n", LT);;

      //输出小于号

     }

      break;

      case"=":fprintf(fout,"(%d,"=")\n", EQ);break;

     //输出等于号

      case">":ch=fgetc(fin);

     if(ch=="=")fprintf(fout,"(%d,">=")\n", GE);

      //输出大于或等于号

      else

      {

      fseek(fin,-1,1);

      fprintf(fout,"(%d,">")\n", GT);

      //输出大于号

      }

     break;

      case" ":break;

      case"\n":break;

      case"\t":break;

      case"/":ch=fgetc(fin);//检查是否为单行注释

      if(ch=="/"){

      while(ch!="\n"){

      ch=fgetc(fin);

      }

      }

     else {

     fseek(fin,-1,1);

     printf("/ is error\n");

     error++;

     }

     break;

      case"{":

     while(1){

      ch=fgetc(fin);

      if(ch=="}") break;

      if(ch==EOF)

     {

     fseek(fin,-1,1);

     printf("{

     is error\n");

     error++;

     break;

      }

      }

      break;

      default:printf("%c is error\n", ch);

      //接收非上述字符程序报告词法错误

      error++;break;

     }

     ch=fgetc(fin);

     //继续从文件中读取下一个单词,直到文件结束

      }//while循环结束

     printf("共发现%d 个词法错误!",error);

      return;

     }

      int lookup(char *token)

     {

      int j;

     char word[norw][al];

      strcpy(&(word[1][0]), "begin" );

      strcpy(&(word[2][0]), "end");

      strcpy(&(word[3][0]), "var");

      strcpy(&(word[4][0]), "integer");

      strcpy(&(word[5][0]), "while");

      strcpy(&(word[6][0]), "do");

      strcpy(&(word[7][0]), "if");

      strcpy(&(word[8][0]), "then");

      strcpy(&(word[9][0]), "procedure");

      strcpy(&(word[10][0]), "else");

     for(j=1;j<=norw-1;j++)if(strcmp(token,word[j])==0) return j;

      //以TOKEN字符串查保留字表,若查到返回保留字类别码

      return 0;

     //TOKEN不是保留字,返回0

     }

      bool isalpha(char c)

     { //判断接收字符是否为字母

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

      else return 0;

      }

     bool isalnum(char c)

     {//判断接收字符是否为字母或者数字

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

      else return 0;

     }

      bool isdigit(char c)

     {//判断接收字符是否为数字

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

      else return 0;

     }

      char letter(char c) //将大写字母转换成小写字母,即不区分大小写

     {

     if(c>="A"&&c<="Z")

     {

     c=c+32;

     }

     return c;

     }

      int main()

     {

     char filename[20];

     printf("请输入文件名:");

     scanf("%s",filename);

     if((fin=fopen(filename,"r"))==NULL) //打开要读取的文本文件

     {

      printf("不能打开文件.\n");

      exit(0);

     }

      printf("请输入保存分析结果的文件名:");

     scanf("%s",filename);

      if((fout=fopen(filename,"w"))==NULL)

      {

     printf("不能打开文件.\n");

     exit(0);

      }

      scanner();

     //调用词法分析程序

     //getchar();getchar();

      fclose(fin);

     fclose(fout);

     return 0;

     }

      五 、 运行的结果

    • 范文大全
    • 职场知识
    • 精美散文
    • 名著
    • 讲坛
    • 诗歌
    • 礼仪知识