编译原理实验报告.docx
《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(17页珍藏版)》请在冰点文库上搜索。
编译原理实验报告
编译原理
实验报告
系别
电子信息系
专业
计算机科学与技术
班级学号
姓名
指导教师
实验一词法分析程序的设计和实现
【实验目的和要求】
设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解。
【实验内容】
通过丢PL/0词法分析程序的分析,并在此基础上按照附录A中给出的PL/0语言的语法描述,编写一个PL/0语言的词法分析程序。
此程序应具有如下功能:
输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词,类别)所组成的二元组序列。
有一定的检查错误的能力,例如发现2A这类不能作为单词的字符串。
【实验环境】
WindowsPC机
【程序源代码以及所要分析的PL/0源文件】
1.词法分析程序源代码
#include
#include
#include
#include
#include
#defineNULL0
FILE*fp;
charcbuffer;
char*key[8]={"if","else","for","while","do","return","break","continue"};
char*border[6]={",",";","{","}","(",")"};
char*arithmetic[4]={"+","-","*","/"};
char*relation[6]={"<","<=","=",">",">=","<>"};
char*consts[20];
char*label[20];
intconstnum=0,labelnum=0;
intsearch(charsearchchar[],intwordtype)
{inti=0;
switch(wordtype)
{case1:
for(i=0;i<=7;i++)
{if(strcmp(key[i],searchchar)==0)
return(i+1);
}
case2:
{for(i=0;i<=5;i++)
{if(strcmp(border[i],searchchar)==0)
return(i+1);
}
return0;
}
case3:
{for(i=0;i<=3;i++)
{if(strcmp(arithmetic[i],searchchar)==0)
return(i+1);
}
return0;
}
case4:
{for(i=0;i<=5;i++)
{if(strcmp(relation[i],searchchar)==0)
return(i+1);
}
return0;
}
case5:
{for(i=0;i<=constnum;i++)
{if(strcmp(consts[i],searchchar)==0)
return(i+1);
}
consts[i-1]=(char*)malloc(sizeof(searchchar));
strcpy(consts[i-1],searchchar);
constnum++;
returni;
}
case6:
{for(i=0;i{if(strcmp(label[i],searchchar)==0)
return(i+1);
}
label[i-1]=(char*)malloc(sizeof(searchchar));
strcpy(label[i-1],searchchar);
labelnum++;
returni;
}
}
}
charalphaprocess(charbuffer)
{intatype;
inti=-1;
charalphatp[20];
while(isalpha(buffer)||isdigit(buffer))
{alphatp[++i]=buffer;
buffer=fgetc(fp);
}
alphatp[i+1]='\0';
if(atype=search(alphatp,1))
printf("%s(6,%d)\n",alphatp,atype-1);
else
{atype=search(alphatp,6);
printf("%s(6,%d)\n",alphatp,atype-1);
}
returnbuffer;
}
chardigitprocess(charbuffer)
{inti=-1;
chardigittp[20];
intdtype;
while(isdigit(buffer))
{digittp[++i]=buffer;
buffer=fgetc(fp);
}
digittp[i+1]='\0';
dtype=search(digittp,5);
printf("%s(5,%d)\n",digittp,dtype-1);
returnbuffer;
}
charotherprocess(charbuffer)
{inti=-1;
charothertp[20];
intotype,otypetp;
othertp[0]=buffer;
othertp[1]='\0';
if(otype==search(othertp,3))
{printf("%s(3,%d)\n",othertp,otype-1);
buffer=fgetc(fp);
gotoout;
}
if(otype==search(othertp,4))
{buffer=fgetc(fp);
othertp[1]=buffer;
othertp[2]='\0';
if(otypetp==search(othertp,4))
{printf("%s(4,%d)\n",othertp,otypetp-1);
gotoout;
}
else
othertp[1]='\0';
printf("%s(4,%d)\n",othertp,otype-1);
gotoout;
}
if(buffer==':
')
{buffer=fgetc(fp);
if(buffer=='=')
printf(":
=(2,2)\n");
buffer=fgetc(fp);
gotoout;
}
else
{if(otype==search(othertp,2))
{printf("%s(2,%d)\n",othertp,otype-1);
buffer=fgetc(fp);
gotoout;
}
}
if(buffer!
='\n'&&buffer!
='')
printf("%cerror,notaword\n",buffer);
buffer=fgetc(fp);
out:
returnbuffer;
}
voidmain()
{inti;
for(i=0;i<=20;i++)
{label[i]=NULL;
consts[i]=NULL;
}
if((fp=fopen("example.c","r"))==NULL)
printf("error");
else{
cbuffer=fgetc(fp);
while(cbuffer!
=EOF)
{if(isalpha(cbuffer))
cbuffer=alphaprocess(cbuffer);
elseif(isdigit(cbuffer))
cbuffer=digitprocess(cbuffer);
else
cbuffer=otherprocess(cbuffer);
}
printf("over\n");
getchar();
}
}
2.PL/0源文件
dotestifelseforwhiledoreturnbreakcontinue>=*-+<();{}
【程序运行结果】
实验二递归子程序分析器的设计与实现
【实验目的和要求】
设计、编译、调试一个典型的语法分析程序,实现对如下文法的递归子程序语法分析,进一步掌握常用的语法分析方法。
【实验内容】
(1)本分析程序所分析的文法如下:
E->TG
T->FS
G->+TG
G->^
S->*FS
S->^
F->(E)
F->i
(2)针对上述文法编写一递归子程序分析程序,该程序的输入是任意符号串,输出时本次输入的符号串是否是该文法的句子的结论
【实验环境】
WindowsPC机
【程序源代码】
#include
#include
#include
chara[50],b[50],d[200],e[10];
charch;
intn1,i1=0,flag=1,n=5;
intE();
intE1();
intT();
intG();
intS();
intF();
voidinput();
voidinput1();
voidoutput();
voidmain()
{intf,p,j=0;
charx;
d[0]='E';
d[1]='=';
d[2]='>';
d[3]='T';
d[4]='G';
d[5]='#';
printf("请输入字符串(长度<50,以#号结束)\n");
do{
scanf("%c",&ch);
a[j]=ch;
j++;
}while(ch!
='#');
n1=j;
ch=b[0]=a[0];
printf("文法\t分析串\t分析字符\t剩余串\n");
f=E1();
if(f==0)return;
if(ch=='#')
{printf("accept\n");
p=0;
x=d[p];
while(x!
='#')
{printf("%c",x);p=p+1;x=d[p];
}
}
else{
printf("error\n");
printf("回车返回\n");
getchar();getchar();
return;
}
printf("\n");
printf("回车返回\n");
getchar();
getchar();
}
intE1()
{intf,t;
printf("E->TG\t");
flag=1;
input();
input1();
f=T();
if(f==0)return0;
t=G();
if(t==0)return0;
elsereturn1;
}
intE()
{intf,t;
printf("E->TG\t");
e[0]='E';e[1]='>';e[3]='T';e[4]='G';e[5]='#';
output();
flag=1;
input();
input1();
f=T();
if(f==0)return0;
t=G();
if(t==0)return0;
elsereturn1;
}
intT()
{intf,t;
printf("T->FS\t");
e[0]='T';e[1]='=';e[2]='>';e[3]='F';e[4]='S';e[5]='#';
output();
flag=1;
input();
input1();
f=F();
if(f==0)return0;
t=S();
if(t==0)return0;
elsereturn1;
}
intG()
{intf;
if(ch=='+')
{b[i1]=ch;
printf("G->+TG\t");
e[0]='G';e[1]='=';e[2]='>';e[3]='+';e[4]='T';e[5]='G';e[6]='#';
output();
flag=0;
input();input1();
ch=a[++i1];
f=T();
if(f==0)return0;
G();
return1;
}
printf("G->^\t");
e[0]='G';e[1]='=';e[2]='>';e[3]='^';e[4]='#';
output();
flag=1;
input();
input1();
return1;
}
intS()
{intf,t;
if(ch=='*')
{b[i1]=ch;
printf("S->*FS\t");
e[0]='S';e[1]='=';e[2]='>';e[3]='*';e[4]='F';e[5]='S';e[6]='#';
output();
flag=0;
input();input1();
ch=a[++i1];
f=F();
if(f==0)return0;
t=S();
if(t==0)return0;
elsereturn1;
}
printf("S->^\t");
e[0]='S';e[1]='=';e[2]='>';e[3]='^';e[4]='#';
output();
flag=1;
a[i1]=ch;
input();
input1();
return1;
}
intF()
{intf;
if(ch=='('){
b[i1]=ch;printf("F->(E)\t");
e[0]='F';e[1]='=';e[2]='>';e[3]='(';e[4]='E';e[5]=')';e[6]='#';
output();
flag=0;
input();input1();
ch=a[++i1];
f=E();
if(f==0)return0;
if(ch==')')
{b[i1]=ch;printf("F->(E)\t");
flag=0;input();input1();
ch=a[++i1];
}
else
{printf("error\n");
return0;
}
}
elseif(ch=='i'){
b[i1]=ch;printf("F->i\t");
e[0]='F';e[1]='=';e[2]='>';e[3]='i';e[4]='#';
output();
flag=0;input();input1();
ch=a[++i1];
}
else{printf("error\n");return0;}
return1;
}
voidinput()
{intj=0;
for(;j<=i1-flag;j++)
printf("%c",b[j]);
printf("\t\t");
printf("%c\t\t",ch);
}
voidinput1()
{
intj;
for(j=i1+1-flag;jprintf("%c",a[j]);
printf("\n");
}
voidoutput()
{intm,k,j,q;
inti=0;m=0;k=0;q=0;i=n;
d[n]='=';d[n+1]='>';d[n+2]='#';n=n+2;i=n;
i=i-2;
while(d[i]!
='>'&&i!
=0)i=i-1;
i=i+1;
while(d[i]!
=e[0])i=i+1;
q=i;
m=q;k=q;
while(d[m]!
='>')m=m-1;
m=m+1;
while(m!
=q){d[n]=d[m];m=m+1;n=n+1;}
d[n]='#';
for(j=3;e[j]!
='#';j++)
{d[n]=e[j];
n=n+1;}
k=k+1;
while(d[k]!
='='){
d[n]=d[k];n=n+1;k=k+1;
}
d[n]='#';
}
【程序运行结果】
实验总结:
通过本次实验,我对编译器的工作原理有了更深的了解。
编译器是计算机软件与硬件之间实现衔接的桥梁,允许所有计算机用户忽略与机器相关的机器语言的细节。
词法分析是编译的第一个阶段。
词法分析程序也称扫描器,其主要的功能是将输入字符分组为词法记号,并将有关字符组合成单词并输出,同时进行词法检查。
语法分析是编译程序的核心部分,语法分析的主要任务是分析文法的句子结构,即识别由词法分析所输出的单词符号序列是否是给定的文法的正确的句子。