完整word版编译原理词法分析程序实现实验报告doc.docx
- 文档编号:30098966
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:81
- 大小:355.19KB
完整word版编译原理词法分析程序实现实验报告doc.docx
《完整word版编译原理词法分析程序实现实验报告doc.docx》由会员分享,可在线阅读,更多相关《完整word版编译原理词法分析程序实现实验报告doc.docx(81页珍藏版)》请在冰豆网上搜索。
完整word版编译原理词法分析程序实现实验报告doc
实验一词法分析程序实现
一、实验内容
选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。
输入:
由无符号数和+,-,*,/,(,)构成的算术表达式,如1.5E+2-100。
输出:
对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
二、设计部分
因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:
GOTO1:
GOTO2:
三、源程序代码部分
#include
#include
#include
#defineMAX100
#defineUNSIGNEDNUMBER1
#definePLUS2
#defineSUBTRACT3
#defineMULTIPLY4
#defineDIVIDE5
#defineLEFTBRACKET6
#defineRIGHTBRACKET7
#defineINEFFICACIOUSLABEL8
#defineFINISH111
intcount=0;
intClass;
voidStoreType();
intType[100];
charStore[20]={'\0'};
voidShowStrFile();//已经将要识别的字符串存在文件a中
voidOutput(inta,char*p1,char*p2);//字符的输出过程
intSign(char*p);//'+''-''*''/'整体识别过程
intUnsignedNum(char*p);//是否适合合法的正整数0~9
intLegalCharacter(char*p);//是否是合法的字符:
Sign(p)||UnsignedNum(p)||'E'||'.'
voidDistinguishSign(char*p);//'+''-''*''/'具体识别过程
voidTypyDistinguish();//字符的识别过程
voidShowType();//将类别码存储在Type[100]中,为语法分析做准备
voidShowStrFile()//已经将要识别的字符串存在文件a中
{
FILE*fp_s;
charch;
if((fp_s=fopen("a.txt","r"))==NULL)
{printf("TheFILEcannotopen!
");
exit(0);
}
else
ch=fgetc(fp_s);
while(ch!
=EOF)
{
putchar(ch);
ch=fgetc(fp_s);
}
printf("\n");
}
voidStoreStr()//将文件中的字符串存储到数组Store[i]
{
FILE*fp=fopen("a.txt","r");
charstr;
inti=0;
while(!
feof(fp))
{
fscanf(fp,"%c",&str);
if(str=='?
')
{
Store[i]='\0';
break;
}
Store[i]=str;
i++;
}
Store[i]='\0';
}
voidShowStore()
{inti;
for(i=0;Store[i]!
='\0';i++)
printf("%c",Store[i]);
printf("\n");
}
voidOutput(inta,char*p1,char*p2)
{
printf("%3s\t%d\t%s\t","CLASS",a,"VALUE");
while(p1<=p2)
{
printf("%c",*p1);
p1++;
}
printf("\n");
}
intSign(char*p)
{
charch=*p;
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')')
return1;
else
return0;
}
intUnsignedNum(char*p)
{
charch=*p;
if('0'<=ch&&ch<='9')
return1;
else
return0;
}
intLegalCharacter(char*p)
{
charch=*p;
if(Sign(p)||UnsignedNum(p)||ch=='E'||ch=='.')
return1;
elsereturn0;
}
voidDistinguishSign(char*p)
{intClass;
charch=*p;
switch(ch)
{
case'+':
Output(PLUS,p,p);Type[count++]=PLUS;break;
case'-':
Output(SUBTRACT,p,p);Type[count++]=SUBTRACT;break;
case'*':
Output(MULTIPLY,p,p);Type[count++]=MULTIPLY;break;
case'/':
Output(DIVIDE,p,p);Type[count++]=DIVIDE;break;
case'(':
Output(LEFTBRACKET,p,p);Type[count++]=LEFTBRACKET;break;
case')':
Output(RIGHTBRACKET,p,p);Type[count++]=RIGHTBRACKET;break;
default:
break;
}
}
voidTypyDistinguish()
{
printf("词法开始,分析结果如下:
\n");
char*p;
p=&Store[0];
while(*p!
='\0')
{
if(Sign(p))
{
DistinguishSign(p++);
continue;
}
elseif(UnsignedNum(p)||*p=='.')
{
char*p1=p;
if(UnsignedNum(p))
{
while(UnsignedNum(p))
p++;
if(*p=='\0')
{
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
elseif(*p=='E')
{
p++;
if(UnsignedNum(p))
{
while(UnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
elseif(*p=='+'||*p=='-')
{
p++;
while(UnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
else
{
Output(INEFFICACIOUSLABEL,p1,--p);
printf("输入的这个符号是不合法的!
");break;
Type[count++]=INEFFICACIOUSLABEL;
p++;
continue;
}
}
elseif(*p=='.')
{
p++;
while(UnsignedNum(p))
p++;
if(*p=='\0')
{
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
elseif(*p=='E')
{
p++;
if(UnsignedNum(p))
{
while(UnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
elseif(*p=='+'||*p=='-')
{
p++;
if(UnsignedNum(p))
{
while(UnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
else
{
Output(INEFFICACIOUSLABEL,p1,--p);
printf("输入的这个符号是不合法的!
/n");
break;
Type[count++]=INEFFICACIOUSLABEL;
p++;
continue;
}
}
else
{
Output(INEFFICACIOUSLABEL,p1,--p);
printf("输入的这个符号是不合法的!
因为他的后面既不是0~9也不是“+”或者“-‘");
break;//1.5E*2这样的字符串不是无符号数
Type[count++]=INEFFICACIOUSLABEL;
p++;
continue;
}
}
else
{
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
}
else
{
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
}
if(*p=='.')
{
p++;
if(UnsignedNum(p))
{
p++;
while(UnsignedNum(p))
p++;
if(*p=='\0')
{
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
elseif(*p=='E')
{
p++;
if(UnsignedNum(p))
{
while(UnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
elseif(*p=='+'||*p=='-')
{
p++;
while(UnsignedNum(p))
p++;
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
}
else
{
Output(UNSIGNEDNUMBER,p1,--p);
Type[count++]=UNSIGNEDNUMBER;
p++;
continue;
}
}
else
{
Output(INEFFICACIOUSLABEL,p1,--p);
printf("输入的这个符号是不合法的!
");break;
Type[count++]=INEFFICACIOUSLABEL;
p++;
continue;
}
}
}
elseif(*p=='E')
{
Output(INEFFICACIOUSLABEL,p,p);break;
Type[count++]=INEFFICACIOUSLABEL;
printf("输入的这个符号是不合法的!
");
p++;
continue;
}
}
printf("\n\n词法分析完毕!
");
}
voidShowType()//将类别码存储在Type[100]中,为语法分析做准备
{
printf("\n用类别码表示输入的字符如下:
\n");
inti;
printf("\n");
for(i=0;Type[i]!
=FINISH;i++)
{printf("%d",Type[i]);
}
printf("\n\n");
}
voidmain()
{
//词法分析部分
StoreStr();
ShowStore();
TypyDistinguish();
Type[count]=FINISH;
ShowType();
}
四、实验结果
正确的结果:
错误的结果:
输入的字符串中有1.5E*2
因为实验是以文件的形式进行读取的所以,在读取不合法的过程中只是将存在project中的a.txt中的内容改变改为1.5E*2+100*555
实验结果如下:
结果分析:
对于正确的结果,我以二元式的形式输出,包括他的值和他的类别码,其中将类别码存放在另外的一个数组中,为了在实验二中的语法识别打下基础。
对于错误的结果,我选择的是跳出这个程序,并且能过分析出错的原因。
改进设计:
(1)字符串是以文件的形式输出的,连续重复输入存在局限性
(2)能够跳过错误的字符继续识别剩下的字符
实验一扩展
李晓萌088330
一、实验内容:
试对基础实验识别的单词种类进行扩充,构造识别以下单词的词法分析程序。
语言中具有的单词包括五个有代表性的关键字begin、end、if、then、else;标识符;整型常数;六种关系运算符;一个赋值符和四个算术运算符。
二、设计部分
基础实验和扩展实验的差别在基础实验的关键在于无符号数的判断,但是,扩展实验的关键在于关键字和标识符的识别。
关于关键字的识别,通过和题目中给出的几个关键字的对比,若相同则可以确定是关键字,否则,就可自动确定为标识符
具体实现的流程图如下:
三、源程序代码部分
#include
#include
#defineBEGIN1
#defineEND2
#defineIF3
#defineTHEN4
#defineELSE5
#defineID6
#defineINT7
#defineLT8
#defineLE9
#defineEQ10
#defineNE11
#defineGT12
#defineGE13
#defineIS14
#definePL15
#defineMI16
#defineMU17
#defineDI18
char*KeyWord[5]={"begin","end","if","then","else"};
inti=0,j=0,k=0,t=0;//搜索指示器
charch;//存放最新读入的原程序字符
charstrToken[20];//存放构成单词符号的字符串
char*chr_form[100];//字符表
char*int_form[100];//常数表
charform[1000];
intq=0;
inttemp;
voidGetChar()//将下一个字符读入ch中,搜索指示器前移一字符位
{
ch=form[k];
k++;
}
voidGetBC()//检查ch中的字符是否为空白,若是则调用Getchar直至ch中进入
//一个非空白字符
{
while(ch=='')
{
//k--;
GetChar();
}
}
voidConcat()//将ch中的字符连接到strToken之后,
{
strToken[i]=ch;
i++;
}
boolIsLetter()//判断ch中的字符是否为字符
{
if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))
return
(1);
else
return(0);
}
boolIsDigit()//判断ch中的字符是否为数字
{
//k--;
if(((ch)<='9')&&((ch)>='0'))
return
(1);
else
return(0);
}
intReserve()//对strToken中的字符串查找保留字表,若它是一个保留字
//则返回它的编码,否则返回-1值
{
for(intq=0;q<5;q++)
{
if(strcmp(KeyWord[q],strToken)==0)
returnq;
if(q==4)
return-1;
}
}
voidRetract()//将搜索指示器回调一个字符位置,将ch置为空白字符
{
k--;
ch=NULL;
}
char*InsertId()//将strToken中的标识符插入符号表,返回符号表的指针
{
chr_form[j]=strToken;
j++;
returnchr_form[0];
}
char*InsertConst()//将strToken中的常数插入常数表,返回常数表指针
{
int_form[t]=strToken;
t++;
returnint_form[0];
}
intcode;
//////////////////////////////////////////////////////////////////////
voidOutput(inta,char*p1,char*p2)
{
cout<<"\t类别码(CLASS):
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整 word 编译 原理 词法 分析 程序 实现 实验 报告 doc