编译原理实验报告.docx
- 文档编号:30521862
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:22
- 大小:31.57KB
编译原理实验报告.docx
《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(22页珍藏版)》请在冰豆网上搜索。
编译原理实验报告
目录
实验一词法分析器的设计与实现1
1)实验目的1
2)实验内容1
3)实验要求1
4)实验原理1
5)实验步骤1
6)状态转化图及词法分析程序2
7)测试7
实验二语法分析器的设计与实现9
1)实验目的9
2)实验内容9
3)实验要求9
4)实验原理9
5)实验步骤9
6)语法分析程序10
7)测试16
专业:
计算机科学与技术
学生姓名:
学号:
1307064248
完成时间:
2018年9月20日
编译原理实验报告
实验一词法分析器的设计与实现
1)实验目的
1掌握正规式、状态转换图、C语言单词符号的划分及词法分析器的实现
2掌握词法分析程序的作用和接口。
2)实验内容
设计及实现C语言程序的词法分析器。
3)实验要求
1对任给的一个C语言源程序,能够虑掉空格、回车换行符、tab键及注释。
2识别各类单词符号,如关键字、标识符、运算符、常数、界符,结果以二元式形式输出。
并构造符号表。
3输出有词法错误的单词及所在行号。
4)实验原理
根据扫描到的单词符号的第一个字符的种类,分别转到相应的程序进行处理。
这些程序的功能就是识别以相应字符开头的各类单词符号。
5)实验步骤
1根据C语言各类单词的正规式,构造能识别各类单词的状态转换图。
2根据状态转换图,构造识别各类单词的词法分析器。
6)状态转化图及词法分析程序
#include"ctype.h"
#include"string.h"
#include"stdio.h"
FILE*fp;
intid;
voidmain()
{
charcbuffer;
charalphaprocess(charbuffer);
chardigitprocess(charbuffer);
charotherprocess(charbuffer);
if((fp=fopen("example.c","r"))==NULL)/*以只读方式打开文件"example.c",NULL在stdio.h文件中已被定义为0*/
printf("error");
else
{
cbuffer=fgetc(fp);/*文件不为空则从文件中取字符*/
while(cbuffer!
=EOF)/*EOF文件结束标志*/
{
if(cbuffer==''||cbuffer=='\n')/*掠过空格和回车符*/
{
cbuffer=fgetc(fp);
id=4;
}
elseif(isalpha(cbuffer))
cbuffer=alphaprocess(cbuffer);/*检查cbuffer是否为字母,是则调用alphaprocess()函数*/
elseif(isdigit(cbuffer))
cbuffer=digitprocess(cbuffer);/*检查cbuffer是否为数字0~9,是则调用digitprocess()函数*/
elsecbuffer=otherprocess(cbuffer);/*非上述两者则调用otherprocess()函数*/
}
}
}
charalphaprocess(charbuffer)
{
intsearch(charsearchchar[],intwordtype);/*函数声明*/
intatype;
inti=-1;
charalphatp[20];/*字符数组存储从文件中读取的字符*/
while((isalpha(buffer))||(isdigit(buffer))||buffer=='_')/*标识符的组成成分*/
{
alphatp[++i]=buffer;/*将当前读取的字符存如数组*/
buffer=fgetc(fp);/*读取下一个字符*/
}
alphatp[i+1]='\0';/*字符串以'\0'作为结束标志*/
atype=search(alphatp,1);/*调用函数,判断当前字符串是否为关键字*/
if(atype!
=0)/*是关键字则输出该关键字,编号为1,并输出该关键字在关键字表中的位子*/
{
printf("(%s,(1,%d))\n",alphatp,atype);
id=1;/*关键字的ID为1*/
}
else
{
printf("(%s,2)\n",alphatp);/*为标识符时,编号为2*/
id=2;/*标识符的ID为2*/
}
return(buffer);
}
/*判断字符串是否为关键字*/
intsearch(charsearchchar[],intwordtype)
{
char*key[32]={"auto","break","case","char","const","continue","default","do",
"double","else","enum","extern","float","for","goto","if","int","long",
"register","return","short","signed","sizeof","static","struct",
"volatile","while","switch","typedef","union","unsigned","void"};
/*设置数组指针存储c语言中的32个关键字*/
inti;
intp;
switch(wordtype)
{
case1:
for(i=0;i<=31;i++)
{
if(strcmp(key[i],searchchar)==0)/*比较字符串,为关键字则定位该关键字的序号*/
{p=i+1;break;}
elsep=0;
}
return(p);
}
}
chardigitprocess(charbuffer)
{
inti=-1;
chardigittp[20];
while((isdigit(buffer))||buffer=='.'||buffer=='e'||buffer=='E')//考虑数字为小数和指数时的情况
{
digittp[++i]=buffer;
buffer=fgetc(fp);/*同上*/
}
digittp[i+1]='\0';
printf("(%s,3)\n",digittp);/*输出该数字,编号为3*/
id=3;/*设置ID为3*/
return(buffer);
}
charotherprocess(charbuffer)
{
intn=0;
charch[20];
ch[0]=buffer;
ch[1]='\0';
if(ch[0]=='%'||ch[0]=='\\')
{buffer=fgetc(fp);
ch[1]=buffer;
ch[2]='\0';
printf("(%s,5)\n",ch);
id=4;
buffer=fgetc(fp);
return(buffer);
}
if(ch[0]=='&')
{
buffer=fgetc(fp);
if(buffer!
='&')
{
printf("(%s,5)\n",ch);
id=4;
return(buffer);
}
if(buffer=='&')
{
ch[1]=buffer;
ch[2]='\0';
printf("(%s,4)\n",ch);
id=3;
buffer=fgetc(fp);
return(buffer);
}
}
if(ch[0]==','||ch[0]==';'||ch[0]=='{'||ch[0]=='}'||ch[0]=='('||ch[0]==')')
{
printf("(%s,5)\n",ch);
buffer=fgetc(fp);
id=4;
return(buffer);
}
if(ch[0]=='*'||ch[0]=='/')
{
printf("(%s,4)\n",ch);
buffer=fgetc(fp);
id=4;
return(buffer);
}
if(ch[0]=='='||ch[0]=='!
'||ch[0]=='<'||ch[0]=='>')
{
buffer=fgetc(fp);
if(buffer=='=')/*防止'==','!
=','<=','>='符号的分离*/
{
ch[1]=buffer;
ch[2]='\0';
printf("(%s,4)\n",ch);
}
else
{
printf("(%s,4)\n",ch);
id=4;
return(buffer);
}
buffer=fgetc(fp);
id=4;
return(buffer);
}
if(ch[0]=='+'||ch[0]=='-')
{
if(id==4)/*如果'+','-'前ID为4的字符则可能为正负数或'++','--',否则为加减号*/
{
for(inti=1;i<10;i++)
{
buffer=fgetc(fp);
if(buffer=='+')
{
ch[1]='+';ch[2]='\0';
id=4;
printf("(%s,4)\n",ch);
buffer=fgetc(fp);
id=4;
return(buffer);
}
if(buffer=='-')
{
ch[1]='-';
ch[2]='\0';
id=4;
printf("(%s,4)\n",ch);
buffer=fgetc(fp);
id=4;
return(buffer);
}
if((buffer==',')||(buffer==';')||(buffer=='+')||(buffer=='-')||(buffer==')'))
break;/*防止将+562;+562,+562+,+562-,+561)作为整体输出*/
ch[i]=buffer;
ch[i+1]='\0';
}
printf("(%s,3)\n",ch);
id=3;
//buffer=fgetc(fp);
return(buffer);
}
ch[2]='\0';
}
printf("(%s,wrongword!
)\n",ch);
buffer=fgetc(fp);
id=4;
return(buffer);
}
7)测试
实验二语法分析器的设计与实现
1)实验目的
掌握自上而下语法分析方法、自下而上语法分析方法分析思路。
2)实验内容
1设计及实现能够识别表达式的预测分析程序。
文法如下:
G[E]:
E->E+T|T
T->T*F|F
F->(E)|i
2设计及实现能够识别表达式的LR分析程序。
文法如下:
G[E]:
E->E+T|T
T->T*F|F
F->(E)|i
3)实验要求
1对已给的一个二元式形式表达式,能够检查有无语法错误。
并指定出错位置。
2将表达式的语法分析过程输出。
4)实验原理
根据自上而下和自下而上的语法分析思想实现语法分析程序。
5)实验步骤
1根据文法构造语法分析表。
2编写总控程序实现语法分析。
6)语法分析程序
#include"stdafx.h"
#include"malloc.h"
#include"stdio.h"
#include"string.h"
#defineSTACK_INIT_SIZE20
#defineSENTENCE_LEN10
#definetrue1
#definefalse0
//分析表存储。
为了计算对应关系方便,为每个数组多分配一个空间,
//vn[0],vt[0],candistring[0],并不使用
//每个候选式与vn,vt的关系是:
(i-1)*6+j,i为vn的标号,j为vt的下标
//用?
替代ε
charvn[6]={'\0','E','A','T','B','F'};
charvt[7]={'\0','i','+','*','(',')','#'};
charcandistring[31][4]={{"\0"},
{"AT"},{""},{""},{"AT"},{""},{""},
{""},{"AT+"},{""},{""},{"?
"},{"?
"},
{"BF"},{""},{""},{"BF"},{""},{""},
{""},{"?
"},{"BF*"},{""},{"?
"},{"?
"},
{"i"},{""},{""},{")E("},{""},{""}
};
//i
//ETE'
//栈结构设计
structstack
{
char*base;
char*top;
intstacksize;
};
//栈初始化
intInitStack(stack&s)
{
s.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
if(!
s.base){
printf("stackoverflow!
\n");
return0;
}
s.top=s.base-1;
s.stacksize=STACK_INIT_SIZE;
return1;//说明空间分配成功
}
//入栈操作,成功返回1。
只入栈,没有判断栈是否满
intPushStack(stack&s,charchstring[4])
{
inti=0;
while(chstring[i]!
='\0'){
s.top++;
*(s.top)=chstring[i];
i++;
}
return1;
}
//出栈操作。
未判断栈是否空。
若成功,返回出栈符号。
charPopStack(stack&s)
{
charch;
ch=*(s.top);
s.top--;
returnch;
}
intSearch(charresultstring[4],charvnchar,charinputchar)
{
inti,j;
//查询非终结符的编号存入i
for(i=1;i<6;i++){
if(vnchar==vn[i])break;
}
//查询与输入符号同的终结符的编号存入j
for(j=1;j<7;j++){
if(inputchar==vt[j])break;
}
strcpy(resultstring,candistring[(i-1)*6+j]);
if(resultstring=="")
return0;
elsereturn1;
}
//初始化化sentence,读取句子,并将最后字符之后增加#
intreadsentence(chars[])
{
inti;
scanf("%s",s);
i=0;
while(s[i]!
='\0'){
i++;
}
s[i]='#';
s[i+1]='\0';
return1;
}
//判断x是否为vt。
//和charvt[7]={'\0','i','+','*','(',')','#'}中除#元素进行比较。
intxIsVt(charx)
{
intflag;
inti=1;
flag=false;
while(!
flag&&i<5){
if(x==vt[i])
flag=true;
else
i++;
}
if(flag)
return1;//说明x是终结符
else
return0;
}
//出错处理
voiderrordo(charch)
{
printf("%ciswronghere!
\n",ch);
}
//分析过程输出
voidOutputAnalyse(intoutnum,stack&s,charsenstring[SENTENCE_LEN],charnowi,charvnchar,charresults[4])
{
charp[STACK_INIT_SIZE]="";
//r[7]用来存储所用产生式
charr[7];
char*q=s.base;
inti=0,j=0;
//输出编号
printf("%-5d",outnum);
//输出栈中内容
while(q<=s.top){
p[i]=*q;
i++;
q++;
}
p[i]='\0';
printf("%-20s%",p);
//输出句子中剩余内容
q=&(senstring[nowi]);
printf("%10s",q);
//输出所用产生式
if(results[0]=='\0')
printf("\n");
else{
r[0]=vnchar;
r[1]='-';
r[2]='>';
i=0;
//找到逆候选式的末尾之后
while(results[i]!
='\0')i++;
//找到逆候选式的末尾符号result[i]
i--;
//存储候选式正序内容
j=3;
while(i>=0){
r[j]=results[i];
j++;
i--;
}
r[j]='\0';
printf("%20s\n",r);
}
}
intmain(intargc,char*argv[])
{
//flag用来标识识别过程是否继续
intflag;
inti=0;
charsentence[SENTENCE_LEN];//存储要识别的句子。
//ch用于读取识别句子中的字符,X用于存储上托出去的栈顶符号
charch,x;
//results用来存储查找分析表的结果
charresults[4]="";
//outnum描述输出编号
intoutnum=0;
//定义存储分析过程的栈
stacks;
//为栈分配空间
InitStack(s);
//初始化化sentence,读取句子,并将最后字符之后增加#。
readsentence(sentence);
//初始化栈和输入符号
PushStack(s,"#E");
ch=sentence[i];
//初始化输出内容
printf("%-5d%-20s%10s%20s\n",outnum,"符号栈","输入串","产生式");
outnum++;
//识别句子是否合法,并将分析过程输出
//flag用来标识识别过程是否继续
flag=true;
//通过循环反复执行匹配、推导,成功或出错处理操作
while(flag){
x=PopStack(s);
if(xIsVt(x)){
if(x==ch){
OutputAnalyse(outnum,s,sentence,i+1,x,"");
outnum++;
i++;
ch=sentence[i];
}
else{
errordo(ch);//ch的出现是语法错误
break;
}
}
elseif(x=='#'){
if(x==ch){
flag=false;
printf("%-5d%-20s%10s%20s\n",outnum,"#","#","");
printf("分析成功!
");
}
else{
errordo(ch);
break;
}
}
elseif(Search(results,x,ch)){
if(results[0]!
='?
')
PushStack(s,results);
OutputAnalyse(outnum,s,sentence,i,x,results);
outnum++;
}
else{
errordo(ch);
break;
}
}
return0;
}
7)测试
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告