:
if(isletter(),接收完成后比较是否为关键字,不是则将其存入标示符id[50][10]中;
:
elseif(isdigit()),接收完成后存入cst[50][10]中;
:
elseif为界符,比较符,运算符,输出对应的二元编码;
:
接受完毕,输出id[50][10]--标示符,cst[50][10]--常数,列表;
3:
程序代码
#include
#include
#include
intm=0;
intn=0;
intx[50],y[50];//存放对应常数表和字母表每列的长度。
char*reservechar[]={"PROGRAM","CONST","VAR","INTEGER","LONG","PROCEDURE",
"IF","THEN","WHILE","DO","READ","WRITE","BEGIN","END","ODD"};//指针数组地址每次加1读取下一个字符串
//关键字表
charid[50][10];//符号表
charcst[50][10];//常数表
classScanner
{
private:
inti,j;//指针
intlength;
charch,buffer[100],strtoken[20];
public:
Scanner(charstr[],intn);//构造函数
intisdigit();//判断是否整数
intisletter();//首字母的判断
intreserve();//对stroken进行关键字表的查找,返回其编码值
intinsertid();//将stroken中的标识符插入符号表,返回在符号表中的位置
intinsertconst();//将stroken中的常数插入常数表,返回在常数表中的位置
voidgetchar();//将下一输入字符读到ch中,指针后移一字符位置
voidgetbc();//保证ch是一个非空白字符
voidconcat();//将ch连接到字符串stroken的末尾
voidretract();//置ch为空白字符,指针前移一字符位置
voidscan();
};
Scanner:
:
Scanner(charstr[],intn)//构造函数
{
strcpy(buffer,str);
length=n;
i=j=0;
}
intScanner:
:
isdigit()//判断是否整数
{
if(ch>='0'&&ch<='9')
return1;
else
return0;
}
intScanner:
:
isletter()//首字母的判断
{
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
return1;
else
return0;
}
voidScanner:
:
getchar()//将下一输入字符读到ch中,指针后移一字符位置
{
ch=buffer[i];
i++;
}
voidScanner:
:
getbc()//保证ch是一个非空白字符
{
while(ch=='')
getchar();
}
voidScanner:
:
concat()//将ch连接到字符串stroken的末尾
{
strtoken[j]=ch;
j++;
}
voidScanner:
:
retract()//置ch为空白字符,指针前移一字符位置
{
i--;
}
intScanner:
:
reserve()//对stroken进行关键字表的查找,返回其编码值
{
inti,flag=0;
for(i=0;i<15;i++)
{
if((strncmp(reservechar[i],strupr(strtoken),j)==0)&&(j!
=1))//比较出错第一个interger和i无法区分
{
flag=1;
break;
}
}
if(flag==1)returni+1;
elsereturn0;
}
intScanner:
:
insertid()//将stroken中的标识符插入符号表,返回在符号表中的位置
{
for(inta=0;aid[m][a]=strtoken[a];
x[m]=j;
m++;
returnm;
}
intScanner:
:
insertconst()//将stroken中的常数插入常数表,返回在常数表中的位置
{
for(inti=0;icst[n][i]=strtoken[i];
y[n]=j;
n++;
returnn;
}
voidScanner:
:
scan()
{
while(i{
j=0;//自动清0,让strtoken重置
intcode,value;
getchar();//{ch=buffer[i];i++;}
getbc();//{while(ch=='')getchar();}
if(isletter())//如果打头的是字母
{
while(isletter()||isdigit())
{
concat();//将ch连接到字符串stroken的末尾
getchar();
}
retract();//{i--;}
code=reserve();//检测是否是关键字
if(code==0)//如果扫描到的是标识符
{
value=insertid();
cout<<"<字母位置,"<"<<'\n';//表示字母所在数组的位置
}
elsecout<<"<"<"<<'\n';//如果扫描到的是关键字
}
elseif(isdigit())//如果打头的是数字
{
while(isdigit())
{
concat();
getchar();
}
retract();
value=insertconst();
cout<<"<数字位置,"<"<<'\n';
}
elseif(ch=='+')
cout<<"<16__+,*>"<<'\n';
elseif(ch=='-')
cout<<"<17__-,*>"<<'\n';
elseif(ch=='*')
cout<<"<18--*,*>"<<'\n';
elseif(ch=='/')
cout<<"<19--/,*>"<<'\n';
elseif(ch=='=')
cout<<"<20--=,*>"<<'\n';
elseif(ch=='<')
{
getchar();
if(ch=='>')
cout<<"(21--<>,*)"<<'\n';
elseif(ch=='=')
cout<<"(23--<=,*)"<<'\n';
else
{
retract();
cout<<"(22--<,*)"<<'\n';
}
}
elseif(ch=='>')
{
getchar();
if(ch=='=')
cout<<"(25-->=,*)"<<'\n';
else
{
retract();
cout<<"(24-->,*)"<<'\n';
}
}
elseif(ch=='.')
cout<<"<26--.,*>"<<'\n';
elseif(ch==',')
cout<<"<27--,,*>"<<'\n';
elseif(ch==';')
cout<<"<28--;,*>"<<'\n';
elseif(ch==':
')
{
getchar();
if(ch=='=')
cout<<"<30--:
=,*>"<<'\n';
else
{
retract();
cout<<"<29--:
*>"<<'\n';
}
}
elseif(ch=='(')
cout<<"<31--(,*>"<<'\n';
elseif(ch==')')
cout<<"<32--),*>"<<'\n';
elsecout<<"出错"<<'\n';
}
}
voidmain(void)
{
fstreamfile;
file.open("D:
\\pl.txt",ios:
:
in||ios:
:
nocreate);//以只读方式打开
file.unsetf(ios:
:
skipws);//不跳过文本中的空格
charbuffer[100];//缓冲区定义
cout<<"扫描结果如下所示"<<'\n';
while(file.getline(buffer,100))//while每次接收一行字符。
{
ScannerSS(buffer,strlen(buffer));
SS.scan();
}
cout<<"标识符表如下:
\n"<<"编号\t"<<"值\n";
for(inti=0;i{
cout<
for(intj=0;jcout<cout<<'\n';
}
cout<<"常数表如下:
\n"<<"编号\t"<<"值\n";
for(i=0;i{
cout<
for(intj=0;jcout<cout<<'\n';
}
}
4:
D:
\\pl.txt文件内容
varn,i,j,num,s:
integer;
a:
array[0..maxint]ofinteger;
begin
readln(n);
fori:
=1tondo
read(a[i]);
s:
=0;
fori:
=1tondo
begain
end.
writeln(s);
End.
5:
程序运行结果
6:
校验试验结果正确。
6.实验总结:
词法分析程序的设计思路比较清晰,但是对于其中实现的细节还不是很熟练,比如C++文件的读取操作,string函数的使用,二维数组的使用,以及函数调用过程中变量值的改变等等。
经过自己精心修改,终于初步完成了词法的分析程序,其中可能还存在不足,希望自己能够逐渐掌握程序设计的脉路。
说明:
1.实验名称、实验目的、实验内容、实验要求由教师确定,实验前由教师事先填好,然后作为实验报告模版供学生使用;
2.实验准备由学生在实验或上机之前填写,教师应该在实验前检查;
3.实验过程由学生记录实验的过程,包括操作过程、遇到哪些问题以及如何解决等;
4.实验总结由学生在实验后填写,总结本次实验的收获、未解决的问题以及体会和建议等;
5.源程序、代码、具体语句等,若表格空间不足时可作为附录另外附页。