天天看點

實驗一  簡單詞法分析程式設計

實驗一  簡單詞法分析程式設計

一、實驗目的

了解詞法分析程式的基本構造原理,掌握詞法分析程式的手工構造方法。

二、實驗内容

1、了解編譯程式的詞法分析過程。

2、根據pascal語言的說明語句形式,用手工方法構造一個對說明語句進行詞法分析的程式。該程式能對從鍵盤輸入或從檔案讀入的形如:

“const count=10,sum=81.5,char1=’f’,string1=”hj”, max=169;”

的常量說明串進行處理,分析常量說明串中各常量名、常量類型及常量值,并統計各種類型常量個數。

三、實驗要求

1、輸入的常量說明串,要求最後以分号作結束标志;

2、根據輸入串或讀入的文本檔案中第一個單詞是否為“const”判斷輸入串或文本檔案是否為常量說明内容;

3、識别輸入串或打開的文本檔案中的常量名。常量名必須是辨別符,定義為字母開頭,後跟若幹個字母,數字或下劃線;

4、根據各常量名緊跟等号“=”後面的内容判斷常量的類型。其中:字元型常量定義為放在單引号内的一個字元;字元串常量定義為放在雙引号内所有内容;整型常量定義為帶或不帶+、-

号,不以0開頭的若幹數字的組合;實型常量定義為帶或不帶+、-

号,不以0開頭的若幹數字加上小數點再後跟若幹數字的組合;

5、統計并輸出串或檔案中包含的各種類型的常量個數;

6、以二進制組(類型,值)的形式輸出各常量的類型和值;

7、根據常量說明串置于進階語言源程式中時可能出現的錯誤情況,模仿進階語言編譯器對不同錯誤情況做出相應處理。

四、運作結果

1、輸入如下正确的常量說明串:

const count=10,sum=81.5,char1=‘f’,max=169,str1=“h*54 2..4s!aasj”, char2=‘@’,str2=“aa!+h”;

輸出:

count(integer,10)

sum(float,81.5)

char1(char, ‘f’)

max(integer,169)

str1(string,“h*54 

2..4s!aasj”)

char2(char, ‘@’)

str2(string,“aa!+h”)

int_num=2; 

char_num=2; string_num=2; float_num=1.

2、輸入類似如下的保留字const錯誤的常量說明串:

aconstt count=10,sum=81.5,char1=‘f’;

輸出類似下面的錯誤提示資訊:

it is not a constant declaration statement!

please input a string again!

3、輸入類似如下含常量名或常量值錯誤的常量說明串:

const count=10,12sum=81.5,char1=‘ff’,max=0016;

12sum(wrong! it is not a identifier!)

char1(wrong! there are 

more than one char in ‘’.)

max(wrong! the integer can’t be started with ‘0’.)

int_num=1; 

char_num=0; string_num=0; float_num=0.

4、其他類型的錯誤處理情況(略)。

五、提示

本實驗重點有三個:一是作為常量名的辨別符的識别;二是如何根據“=”後出現的内容來判斷常量類型;三是對各種錯誤的處理。難點是對整型和實型常量的判斷必須綜合考慮多種可能情況。

建議:1、用指針或數組與指針相結合來處理輸入的常量說明串;2、對整型和實型常量處理時,重點考慮常數中‘0’的位置。

六、分析與讨論

1、若考慮用e或e的科學計數法來表示整數和實數,應該如何實作?

2、若考慮布爾型常量,且規定其值隻能為true或false,應該如何實作?

3、如何對手工構造的詞法分析程式做進一步的優化,以提高代碼品質和運作效率?

#include<ctype.h>

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define  n 80

#define  m 16

void check_const();

void measure_iden();

void measure_string();

void measure_digit();

void measure_char();

char cha;

int ci=0,cf=0,cc=0,cs=0;

char *p0,*t0,*p1,*t1, *p2,*str,*p3,*t3="const",*digi,*flo;

void main()

{

 printf("please input string: \n");

 p0=(char *)malloc(n*sizeof(char));

 p1=(char *)malloc(m*sizeof(char));

 p2=(char *)malloc(m*sizeof(char));

 p3=(char *)malloc(m*sizeof(char));

 gets(p0);

 printf("\n");

 check_const();

/* 開始處理輸入串 p0  */

 while(*(p0)==' '||*(p0)==',')  /*從串p0中取辨別符,并将其作為常量名存放到串p1中 */

    {

  p0++;

  if(*(p0)==' '||*(p0)==',')

   continue;

  else

  {

  measure_iden();      //*p0=="="

  if(!isdigit(*p0)&&*p0!='\"'&&*p0!='\'')//注意'和"做字元表示時用\'和\"

   system("cls");

   printf("\n const data is wrong . exit !");

   exit(0);

     }

  else if(*p0=='\"')   /* 處理字元串常量 */

  { 

   p0++;

   measure_string();

  }

  else if(isdigit(*p0))  /* 處理數字 */

   measure_digit();

  else if(*p0=='\'') //處理字元常量

   measure_char();

 }

 if(*p0!=';')

 {

  system("cls");

  printf("\n this centence is wrong . exit !");

  exit(0);

 else

  printf("int_num=%d;  char_num=%d; string_num=%d; float_num=%d.\n",ci,cc,cs,cf);

}

/*    檢查輸入串是否以"'const"開頭   */

void check_const()

 while(*p0!=' ') 

  if(*p0==*t3)

   t3++;

   printf("this string isn't a const declaration!");

void measure_iden()

 if (*p0!='_'&&(!isalpha(*p0)))

  printf("\n const name is wrong . exit !");

    }

 else if (*p0=='_'||isalpha(*p0))

  t1=p1;

  while(*p0!='=')

   *p1=*p0;

   p1++;

  *p1='\0';

//  printf("%s\n",p0);

 printf("%s",t1);

void measure_string()

 str=p2; 

 while(*(p0)!='\"')

  *p2=*p0;

  if(*(p0)==';')//丢了個分号,直接輸出string  data is wrong. exit

   printf("\n string  data is wrong. exit !");

  p2++;

 *p2='\0';

 p0++;

 cs++;

 printf("(string,\"%s\")\n",str);

void measure_digit()

 char *jud;

 int mark=0;

 jud=p0;

 for(;*(jud)!=','&&*(jud)!=';';jud++)

  if(*jud=='.')

   mark=1;

   break;

 if(mark==0)

  digi=p2;

  while(*p0!=','&&*p0!=';')

   *p2=*p0;

   p2++;

  *p2='\0';

  ci++;

  printf("(integer,%s)\n",digi);

 if(mark==1)

  flo=p2;

  cf++;

  printf("(float,%s)\n",flo);

void measure_char()

 if(*(jud+1)=='\''&&*(jud)!='\'')

  cha=*p0;

  p0=p0+2;

  cc++;

  printf("\n char data is wrong. exit !");

 printf("(char,'%c')\n",cha);

繼續閱讀