编译原理实验词法分析实验报告.docx
- 文档编号:6854703
- 上传时间:2023-01-11
- 格式:DOCX
- 页数:13
- 大小:38.27KB
编译原理实验词法分析实验报告.docx
《编译原理实验词法分析实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验词法分析实验报告.docx(13页珍藏版)》请在冰豆网上搜索。
编译原理实验词法分析实验报告
编译技术实验报告
实验题目:
词法分析
学院:
信息学院
专业:
计算机科学与技术
学号:
姓名:
一、实验目的
(1)理解词法分析的功能;
(2)理解词法分析的实现方法;
二、实验内容
PL0的文法如下
‘<>’为非终结符。
‘:
:
=’该符号的左部由右部定义,可读作“定义为”。
‘|’表示‘或’,为左部可由多个右部定义。
‘{}’表示花括号内的语法成分可以重复。
在不加上下界时可重复0到任意次数,有上下界时可重复次数的限制。
‘[]’表示方括号内的成分为任选项。
‘()’表示圆括号内的成分优先。
上述符号为“元符号”,文法用上述符号作为文法符号时需要用引号‘’括起。
〈程序〉∷=〈分程序〉.
〈分程序〉∷=[〈变量说明部分〉][〈过程说明部分〉]〈语句〉
〈变量说明部分〉∷=VAR〈标识符〉{,〈标识符〉}:
INTEGER;
〈无符号整数〉∷=〈数字〉{〈数字〉}
〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}
〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉};
〈过程首部〉∷=PROCEDURE〈标识符〉;
〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉
〈赋值语句〉∷=〈标识符〉∶=〈表达式〉
〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END
〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉
〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉}
〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}
〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')'
〈加法运算符〉∷=+|-
〈乘法运算符〉∷=*
〈关系运算符〉∷=<>|=|<|<=|>|>=
〈条件语句〉∷=IF〈条件〉THEN〈语句〉
〈字母〉∷=a|b|…|X|Y|Z
〈数字〉∷=0|1|2|…|8|9
实现PL0的词法分析
三、实验分析与设计
PL0词法分析程序是一个独立的过程,其功能是为语法语义分析提供单词,把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析。
其主要方法步骤为从源程序扫描下一个字符,忽略空格、换行、TAB和注释并识别单词,再将不同类别的单词归类输出。
四、实验的实现
#include
#include
#include
#include
#include
#definenorw11//norw-1个关键字
#defineal20//最长的关键字的长度
#defineIDnorw
#defineINTnorw+1
#defineCOMMAnorw+2
#defineENDFnorw+3
#defineCOLONnorw+4
#defineSEMICnorw+5
#defineADDnorw+6
#defineMINUSnorw+7
#defineMULTInorw+8
#defineEVALUnorw+9
#defineLEnorw+10
#defineNEnorw+11
#defineLTnorw+12
#defineEQnorw+13
#defineGEnorw+14
#defineGTnorw+15
#defineFLOATnorw+16
charTOKEN[20];//字符数组用来依次存放单词词文的各个字符
externintlookup(char*);//以TOKEN字符串查保留字表
externvoidreport_error(char);//报告程序中的词法错误
boolisalpha(char);//判断接收字符是否为字母
boolisalnum(char);//判断接收字符是否为字母或者数字
boolisdigit(char);//判断接收字符是否为数字
boolisannotation(char);//判断接收字符是否为注释
externcharletter(charc);//用来将大写字母转化成小写字母
FILE*fin;
FILE*fout;
voidscanner()
{//词法分析的主体程序,对输入的文本文件进行词法分析
charch;
inti,c;
interror=0;//记录文件中词法错误的个数
ch=fgetc(fin);//从输入文件中读取一个字符
while(ch!
=EOF)
{//当从输入文件接收的字符不是文件结束符时,执行循环
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);}//输出标识符
elsefprintf(fout,"(%d,%s)\n",c,TOKEN);//输出接收单词为保留字
}
if(isdigit(ch))//如果从输入文件接收的第一个字符是数字
{
intcdot=0;//统计小数点个数
TOKEN[0]=ch;
ch=fgetc(fin);i=1;
while(isdigit(ch)||ch=='.')
{//从第二个接收字符开始,当是数字或者是小数点时,执行循环
if(ch=='.')
cdot++;
TOKEN[i]=ch;i++;
ch=fgetc(fin);//重复接收字符,直到接收到非数字
if(cdot>=2)
{
error++;
TOKEN[i]='\0';
printf("%siserror\n",TOKEN);
break;
}
}
if(isalpha(ch))//如果第二个字符是字母
{
while(isalpha(ch))//接收完所有的字母,跳出循环
{
TOKEN[i]=ch;i++;
ch=fgetc(fin);
}
TOKEN[i]='\0';
error++;
printf("%siserror\n",TOKEN);
}
elseif(cdot==0)//当接收的字符为整型单词时
{
fseek(fin,-1,1);
TOKEN[i]='\0';
inta,temp=0,c;
for(c=0;c
{
a=TOKEN[c]-'0';
if(c!
=0)
{
temp=temp*10;
temp=temp+a;
}
else
{
temp=a;
}
}
fprintf(fout,"(%d,%d)\n",INT,temp);//输出接收单词为整数
}
elseif(cdot==1)
{
fseek(fin,-1,1);
TOKEN[i]='\0';
inta,part1=0,jc,b=0;//b用来确定小数点所在的位置
floatc=0.1,part2=0.0;
while(TOKEN[b]!
='.')
{
b=b+1;
}
for(jc=0;jc
{
a=TOKEN[jc]-'0';
if(jc!
=0)
{
part1=part1*10;
part1=part1+a;
}
else
{
part1=a;
}
}
for(jc=b+1;jc
{
a=TOKEN[jc]-'0';
part2=a*c+part2;
c=c*0.1;
}
fprintf(fout,"(%d,%f)\n",FLOAT,part1+part2);//输出接收单词为小数
}elseif(cdot==2)
{
fseek(fin,-1,1);
}
}
else//如果从输入文件接收的第一个字符既不是字母又不是数字
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);//输出小于或等于号
elseif(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("/iserror\n");
error++;
}
break;
case'{':
while
(1){
ch=fgetc(fin);
if(ch=='}')break;
if(ch==EOF){
fseek(fin,-1,1);
printf("{iserror\n");
error++;
break;
}
}
break;
default:
printf("%ciserror\n",ch);//接收非上述字符程序报告词法错误
error++;break;
}
ch=fgetc(fin);//继续从文件中读取下一个单词,直到文件结束
}//while循环结束
printf("共发现%d个词法错误!
",error);
return;
}
intlookup(char*token)
{
intj;
charword[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)returnj;//以TOKEN字符串查保留字表,若查到返回保留字类别码
return0;//TOKEN不是保留字,返回0
}
boolisalpha(charc)
{//判断接收字符是否为字母
if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))return1;
elsereturn0;
}
boolisalnum(charc)
{//判断接收字符是否为字母或者数字
if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9'))return1;
elsereturn0;
}
boolisdigit(charc)
{//判断接收字符是否为数字
if(c>='0'&&c<='9')return1;
elsereturn0;
}
charletter(charc)//将大写字母转换成小写字母,即不区分大小写
{
if(c>='A'&&c<='Z')
{
c=c+32;
}
returnc;
}
intmain()
{
charfilename[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);
return0;
}
五、运行的结果
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 词法 分析 报告