狠狠干影院/欧美午夜电影在线观看/高黄文/国产精品一区二区在线观看完整版

編譯原理實驗詞法分析實驗報告

| 瀏覽次數(shù):

  編譯技術實驗報告

 實驗題目:

 詞 詞 法分析

 學 學

 院:

 信息學院

 專 專

 業(yè):

 計算機科學與技術

 學 學

 號:

  姓 姓

 名:

 一、 實驗目的

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

 (2) 理解詞法分析的實現(xiàn)方法;

  二 、 實驗內(nèi)容

 PL0 的文法 如下

 „< >?為非終結符。

 „::=? 該符號的左部由右部定義,可讀作“定義為”。

 „|? 表示„或?,為左部可由多個右部定義。

 „{ }? 表示花括號內(nèi)的語法成分可以重復。在不加上下界時可重復0到任意次數(shù),有上下界時可重復次數(shù)的限制。

 „[ ]? 表示方括號內(nèi)的成分為任選項。

 „( )? 表示圓括號內(nèi)的成分優(yōu)先。

 上述符號為“元符號”, 文法用上述符號作為文法符號時需要用引號„?括起。

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

 〈分程序〉∷= [〈變量說明部分〉][〈過程說明部分〉]〈語句〉

 〈變量說明部分〉∷=VAR〈標識符〉{,〈標識符〉}:INTEGER;

 〈無符號整數(shù)〉∷=〈數(shù)字〉{〈數(shù)字〉}

 〈標識符〉∷=〈字母〉{〈字母〉|〈數(shù)字〉}

 〈過程說明部分〉∷=〈過程首部〉〈分程序〉{;〈過程說明部分〉};

 〈過程首部〉∷=PROCEDURE〈標識符〉;

 〈語句〉∷=〈賦值語句〉|〈條件語句〉|〈過程調用語句〉|〈讀語句〉|〈寫語句〉|〈復合語句〉|〈空〉

 〈賦值語句〉∷=〈標識符〉∶=〈表達式〉

 〈復合語句〉∷=BEGIN〈語句〉{;〈語句〉}END

 〈條件〉∷=〈表達式〉〈關系運算符〉〈表達式〉

 〈表達式〉∷=〈項〉{〈加法運算符〉〈項〉}

 〈項〉∷=〈因子〉{〈乘法運算符〉〈因子〉}

 〈因子〉∷=〈標識符〉|〈無符號整數(shù)〉|"("〈表達式〉")"

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

 〈乘法運算符〉∷=*

 〈關系運算符〉∷=<>|=|<|<=|>|>=

 〈條件語句〉∷=IF〈條件〉THEN〈語句〉

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

 〈數(shù)字〉∷=0|1|2|…|8|9

  現(xiàn) 實現(xiàn) PL0 的 的 詞法分析

 三 、 實驗 分析與設計

 PL0 詞法分析程序是一個獨立的過程,其功能是為語法語義分析提供單詞,把輸入的字符串形式的源程序分割成一個個單詞符號傳遞給語

 法語義分析。

 其主要方法步驟為從源程序掃描下一個字符,忽略空格、換行、TAB和注釋并識別單詞,再將不同類別的單詞歸類輸出。

  四 、實驗 的 實現(xiàn)

 #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];

 //字符數(shù)組用來依次存放單詞詞文的各個字符

 extern int lookup(char *);

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

 extern void report_error(char);

 //報告程序中的詞法錯誤

 bool isalpha(char);

 //判斷接收字符是否為字母

 bool isalnum(char);

 //判斷接收字符是否為字母或者數(shù)字

 bool isdigit(char);

 //判斷接收字符是否為數(shù)字

 bool isannotation(char);

 //判斷接收字符是否為注釋

 extern char letter(char c); //用來將大寫字母轉化成小寫字母

 FILE* fin;

 FILE* fout;

  void scanner()

 {//詞法分析的主體程序,對輸入的文本文件進行詞法分析

  char ch;

  int i,c;

  int error=0;

  //記錄文件中詞法錯誤的個數(shù)

  ch=fgetc(fin);

 //從輸入文件中讀取一個字符

 while(ch!=EOF)

  {//當從輸入文件接收的字符不是文件結束符時,執(zhí)行循環(huán)

 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))

  //如果從輸入文件接收的第一個字符是數(shù)字

 {

 int cdot=0;

  //統(tǒng)計小數(shù)點個數(shù)

  TOKEN[0]=ch;

  ch=fgetc(fin);i=1;

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

  {//從第二個接收字符開始,當是數(shù)字或者是小數(shù)點時,執(zhí)行循環(huán)

 if(ch==".")

 cdot++;

 TOKEN[i]=ch;i++;

 ch=fgetc(fin);//重復接收字符,直到接收到非數(shù)字

 if(cdot>=2)

 {

 error++;

 TOKEN[i]="\0";

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

 break;

 }

  }

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

  {

 while(isalpha(ch)) //接收完所有的字母,跳出循環(huán)

 {

  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);

 //輸出接收單詞為整數(shù)

  }

  else if(cdot==1)

 {

 fseek(fin,-1,1);

  TOKEN[i]="\0";

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

  //b用來確定小數(shù)點所在的位置

 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);

 //輸出接收單詞為小數(shù)

 }else if(cdot==2)

 {

 fseek(fin,-1,1);

 }

  }

  else

 //如果從輸入文件接收的第一個字符既不是字母又不是數(shù)字

 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);

 //繼續(xù)從文件中讀取下一個單詞,直到文件結束

  }//while循環(huán)結束

 printf("共發(fā)現(xiàn)%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)

 {//判斷接收字符是否為字母或者數(shù)字

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

  else return 0;

 }

  bool isdigit(char c)

 {//判斷接收字符是否為數(shù)字

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

  else return 0;

 }

  char letter(char c) //將大寫字母轉換成小寫字母,即不區(qū)分大小寫

 {

 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;

 }

  五 、 運行的結果

推薦訪問: 實驗 詞法 編譯

【編譯原理實驗詞法分析實驗報告】相關推薦

工作總結最新推薦

NEW