一、实验目的:
设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。
二、实验要求:
1.对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。
2.本程序自行规定:
(1)关键字"begin","end","if","then","else","while","write","read",
"do", "call","const","char","until","procedure","repeat"
(2)运算符:"+","-","*","/","="
(3)界符:"{","}","[","]",";",",",".","(",")",":"
(4)其他标记 如字符串,表示以字母开头的标识符。
(5)空格、回车、换行符跳过。
在屏幕上显示如下:
( 1 , 无符号整数)
( begin , 关键字 )
( if , 关键字 )
( +, 运算符 )
( ; , 界符 )
( a , 普通标识符 )
三、使用环境:
Windows下的visual c++6.0;
四、调试程序:
1.举例说明
文件位置:f:、、11.txt
目标程序如下:
begin
x:=9
if x>0 then x:=x+1;
while a:=0 do
b:=2*x/3;
end;
2.运行结果:
五、程序源代码:
#include <iostream>
#include<string>
using namespace std;
#define MAX 22
char ch =' ';
string key[15]={"begin","end","if","then","else","while","write","read",
"do", "call","const","char","until","procedure","repeat"};
int Iskey(string c){ //关键字判断
int i;
for(i=0;i<MAX;i++) {
if(key[i].compare(c)==0) return 1;
}
return 0;
}
int IsLetter(char c) { //判断是否为字母
if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;
else return 0;
}
int IsDigit(char c){ //判断是否为数字
if(c>='0'&&c<='9') return 1;
else return 0;
}
void analyse(FILE *fpin){
string arr="";
while((ch=fgetc(fpin))!=EOF) {
arr="";
if(ch==' '||ch==' '||ch==' '){}
else if(IsLetter(ch)){
while(IsLetter(ch)||IsDigit(ch)) {
if((ch<='Z')&&(ch>='A')) ch=ch+32;
arr=arr+ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
if (Iskey(arr)){cout<<arr<<" $关键字"<<endl;}
else cout<<arr<<" $普通标识符"<<endl;
}
else if(IsDigit(ch)){
while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin))){
arr=arr+ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
cout<<arr<<" $无符号实数"<<endl;
}
else switch(ch){
case'+':
case'-' :
case'*' :
case'=' :
case'/' :cout<<ch<<" $运算符"<<endl;break;
case'(' :
case')' :
case'[' :
case']' :
case';' :
case'.' :
case',' :
case'{' :
case'}' :cout<<ch<<" $界符"<<endl;break;
case':' :{ch=fgetc(fpin);
if(ch=='=') cout<<":="<<" $运算符"<<endl;
else {cout<<"="<<" $运算符"<<endl;;
fseek(fpin,-1L,SEEK_CUR);}
}break;
case'>' :{ch=fgetc(fpin);
if(ch=='=') cout<<">="<<" $运算符"<<endl;
if(ch=='>')cout<<">>"<<" $输入控制符"<<endl;
else {cout<<">"<<" $运算符"<<endl;
fseek(fpin,-1L,SEEK_CUR);}
}break;
case'<' :{ch=fgetc(fpin);
if(ch=='=')cout<<"<="<<" $运算符"<<endl;
else if(ch=='<')cout<<"<<"<<" $输出控制符"<<endl;
else if(ch=='>') cout<<"<>"<<" $运算符"<<endl;
else{cout<<"<"<<" $运算符"<<endl;
fseek(fpin,-1L,SEEK_CUR);}
}break;
default : cout<<ch<<" $无法识别字符"<<endl;
}
}
}
void main(){
char in_fn[30];
FILE * fpin;
cout<<"请输入源文件名(包括路径和后缀名):";
for(;;){
cin>>in_fn;
if((fpin=fopen(in_fn,"r"))!=NULL) break;
else cout<<"文件路径错误!请输入源文件名(包括路径和后缀名):";
}
cout<<" ********************分析如下*********************"<<endl;
analyse(fpin);
fclose(fpin);
}
六、实验心得:
通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,使用某种高级语言(例如C++语言)直接编写此法分析程序。另外,也让我重新熟悉了C++语言的相关内容,加深了对C++语言的用途的理解。