实验一 简单词法分析程序设计
?
?
?
?
?
?
實驗一 簡單詞法分析程序設計
?
一、實驗目的
了解詞法分析程序的基本構造原理,掌握詞法分析程序的手工構造方法。
二、實驗內容
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;
輸出類似下面的錯誤提示信息:
count(integer,10)
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=='\'') //處理字符常量
??{
???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)
??{
???p0++;
???t3++;
??}
??else
??{
???printf("This string isn't a const declaration!");
???exit(0);
??}
?}
}
void measure_iden()
{
?if (*p0!='_'&&(!isalpha(*p0)))
?{
??system("cls");
??printf("\n Const name is wrong . Exit !");
??exit(0);
??? }
?else if (*p0=='_'||isalpha(*p0))
?{
??t1=p1;
??while(*p0!='=')
??{
???*p1=*p0;
???p0++;
???p1++;
??}
??*p1='\0';
//??printf("%s\n",p0);
??p0++;
?}
?printf("%s",t1);
}
void measure_string()
{
?str=p2;?
?while(*(p0)!='\"')
?{
??*p2=*p0;
??if(*(p0)==';')//丟了個分號,直接輸出String? data is wrong. Exit
??{
???system("cls");
???printf("\n String? data is wrong. Exit !");
???exit(0);
??}
??p0++;
??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;
???p0++;
???p2++;
??}
??*p2='\0';
??ci++;
??printf("(integer,%s)\n",digi);
?}
?if(mark==1)
?{
??flo=p2;
??while(*p0!=','&&*p0!=';')
??{
???*p2=*p0;
???p0++;
???p2++;
??}
??*p2='\0';
??cf++;
??printf("(float,%s)\n",flo);
?}
}
?
void measure_char()
{
?char *jud;
?jud=p0;
?if(*(jud+1)=='\''&&*(jud)!='\'')
?{
??cha=*p0;
??p0=p0+2;
??cc++;
?}
?else
?{
??system("cls");
??printf("\n char data is wrong. Exit !");
??exit(0);
?}
?printf("(char,'%c')\n",cha);
}
?
?
?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的实验一 简单词法分析程序设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚拟机系统与宿主机共享上网设置
- 下一篇: [Qt教程] 第11篇 2D绘图(一)绘