编译原理实验报告.docx
《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
编译原理实验报告
编译原理
实验报告
系别
电子信息系
专业
计算机科学与技术
班级学号
姓名
指导教师
成绩
2010年12月28号
实验一词法分析
一.实验要求:
用C语言编写程序,用于实现对给定文件
中内容进行词法分析。
二.实验目的:
通过编写程序实现对给定文件中内容进行
词法分析,加深对词法分析的理解,并将其掌握。
三.实验源程序代码:
//词法分析.cpp:
定义控制台应用程序的入口点。
#include
#include
#include
#include
#include
#include
usingnamespacestd;
boolisLetter(charch){
if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))returntrue;
elsereturnfalse;
}
boolisDigit(charch){
if(ch>='0'&&ch<='9')returntrue;
elsereturnfalse;
}
boolisP(charch){
if(ch=='+'||ch=='*'||ch=='-'||ch=='/')returntrue;
//ch==':
'||ch==','||ch=='='||ch==';'||ch=='('||ch==')'
elsereturnfalse;
}
boolisJ(charch){
if(ch==','||ch==';'||ch=='.'||ch=='('||ch==')'||ch=='['||ch==']'||ch=='='||ch==':
'||ch=='<'||ch=='>'||ch=='{'||ch=='}'||ch=='#')returntrue;
//
elsereturnfalse;
}
boolisBlank(charch){
if(ch==''||ch=='\t')returntrue;
elsereturnfalse;
}
intmain(){
stringsrc,ste,s;
charch0,ch,ch1[2];
charktt[48][20]={"and","begin","const","div","do","else","end","function","if","integer",
"not","or","procedure","program","read","real","then","type","var","while","write","标识符","无符号数",
",",";",":
",".","(",")","[","]","..","++","--","+","-","*","/","=","<",">","<>","<="
">=",":
=","{","}","#"};
intpos=0;
FILE*fp;
fp=fopen("in.txt","r");
ch0=fgetc(fp);
while(ch0!
=EOF)
{
//if(ch0!
='\t'){src+=ch0;}
src+=ch0;
ch0=fgetc(fp);
}
src+='#';
cout<ch=src[pos++];
ste="";
for(intj=0;j<47;j++){cout<cout<<"词法分析:
\n";
while(ch!
='#')
{
charstr[20];
if(ch!
='\n')
{
if(isDigit(ch))
{//判断常数
inti=0;
while(isDigit(ch)||ch=='.')
{
str[i++]=ch;
//i++;
ch=src[pos++];
}
str[i]='\0';
ste=ste+"|"+"22";
cout<continue;
}
elseif(isLetter(ch))
{//判断字符
inti=0,j;
while(isLetter(ch)||isDigit(ch))
{
str[i++]=ch;
//i++;
ch=src[pos++];
}
str[i]='\0';
for(j=0;j<21;j++){//判断是否关键字
intt=strcmp(str,ktt[j]);
if(t==0){
stringstreamss;
ste+="|";
ss<ss>>ste;
break;
}
}
if(j==21){ste=ste+"|"+"21";}
//cout<<"";
cout<continue;
}
elseif(isP(ch)){///判断是否运算符
inti=0,j;
str[i++]=ch;
str[i]='\0';
for(j=34;j<38;j++){
intt=strcmp(str,ktt[j]);
if(t==0){
stringstreamss;
ste+="|";
ss<ss>>ste;
break;
}
}
cout<ch=src[pos++];
continue;
}
elseif(isJ(ch))//判断是否界符
{
inti=0,j;
while(isJ(ch))
{
str[i++]=ch;
ch=src[pos++];
}
str[i]='\0';
for(j=23;j<47;j++){
intt=strcmp(str,ktt[j]);
if(t==0){
stringstreamss;
ste+="|";
ss<ss>>ste;
break;
}
}
cout<continue;
}
elseif(isBlank(ch))
{
cout<ch=src[pos++];
continue;
}
}
else{
cout<ste="";
}
ch=src[pos++];
}
return0;
}
四.给定文件中的内容:
自己输入就行
五.运行结果:
实验二递归向下分析
一.实验要求:
用C语言设计、编制、调试一个典型的语法分析
程序,用于实现下列语法的分析
G[S]:
E→eBaA
A→a|bAcB
B→dEd|aC
C→e|dC
二.实验目的:
通过对G[S]问法的分析实现,加深对语法分析
的理解,进一步掌握常用的语法分析方法。
三.实验源程序代码:
#include
charinputstream[50];
inttemp=0;
intright;
voide();
voida();
voidb();
voidc();
voidmain()
{
intright=1;
charstag;
while
(1){
if(stag=='y')break;
cout<<"请输入你要分析的字符串,以#结束(^为空字符):
"<cin>>inputstream;
e();
if(inputstream[temp]=='#'&&right==1)
cout<<"分析成功"<else
cout<<"分析失败"<cout<<"是否结束:
yorn:
";
cin>>stag;
}
}
voide()
{
if(inputstream[temp]=='e')
{
cout<<"E->eBaA"<temp++;
b();
if(inputstream[temp]=='a')
{
cout<<"E->eBaA"<temp++;
a();
}
elseright=1;
}
elseright=0;
}
voida()
{
if(inputstream[temp]=='a')
{
cout<<"A->a"<temp++;
}
elseif(inputstream[temp]=='b')
{
cout<<"A->bAcB"<temp++;
a();
if(inputstream[temp]=='c')
{
cout<<"A->bAcB"<temp++;
b();
}
elseright=1;
}
elseright=0;
}
voidb()
{
if(inputstream[temp]=='d')
{
cout<<"B->dEd"<temp++;
e();
if(inputstream[temp]=='d')
{
cout<<"B->dEd"<temp++;
}
elseright=1;
}
elseif(inputstream[temp]=='a')
{
cout<<"B->aC"<temp++;
c();
}
elseright=0;
}
voidc()
{
if(inputstream[temp]=='e')
{
cout<<"C->e"<temp++;
}
elseif(inputstream[temp]=='d')
{
cout<<"C->dC"<temp++;
c();
}
elseright=0;
}
四.运行结果:
实验三LL
(1)文法分析
一.实验要求:
用C语言编写程序,用于实现对输入字符串
中内容进行LL
(1)文法分析。
二.实验目的:
通过编写程序实现对输入字符串中内容进行
语法分析,加深对语法分析的理解,并将其掌握。
三.实验源程序代码:
#include
#include
#include
#include
charA[20];
charB[20];
charv1[20]={'i','+','*','(',')','#'};
charv2[20]={'E','G','T','S','F'};
intj=0,b=0,top=0,l;
typedefstructtype{
charorigin;
chararray[5];
intlength;
}type;
typee,t,g,gl,s,sl,f,fl;
typeC[10][10];
voidprint(){
inta;
for(a=0;aprintf("%c",A[a]);
printf("\t\t");
}
voidprint1(){
intj;
for(j=0;j
printf("");
for(j=b;j<=1;j++)
printf("%c",B[j]);
printf("\t\t\t");
}
voidmain(){
intm,n,k=0,flag=0,finish=0;
charch,x;
typecha;
e.origin='E';
strcpy(e.array,"TG");
e.length=2;
t.origin='T';
strcpy(t.array,"FS");
t.length=2;
g.origin='G';
strcpy(g.array,"+TG");
g.length=3;
gl.origin='G';
gl.array[0]='';
g.length=1;
s.origin='S';
strcpy(s.array,"*FS");
s.length=3;
sl.origin='S';
sl.array[0]='';
sl.length=1;
f.origin='F';
strcpy(f.array,"(E)");
f.length=3;
fl.origin='F';
fl.array[0]='i';
fl.length=1;
for(m=0;m<=4;m++)
for(n=0;n<=5;n++)
C[m][n].origin='N';
C[0][0]=e;C[0][3]=e;
C[1][1]=g;C[1][4]=gl;C[1][5]=gl;
C[2][0]=t;C[2][3]=t;
C[3][1]=sl;C[3][2]=s;C[3][4]=C[3][5]=sl;
C[4][0]=fl;C[4][3]=f;
printf("提示:
本程序只能对由'i','+','*','(',')'构成的以'#'结束的字符串进行分析\n");
printf("请输入要分析的字符串:
");
do{
scanf("%c",&ch);
if((ch!
='i')&&(ch!
='+')&&(ch!
='*')&&(ch!
='(')&&(ch!
=')')&&(ch!
='#'))
{
printf("输入中有非法的字符\n");
exit
(1);
}
B[j]=ch;
j++;
}while(ch!
='#');
l=j;
ch=B[0];
A[top]='#';A[++top]='E';
printf("步骤\t\t分析栈\t\t剩余字符\t\t所用产生式\n");
do
{
x=A[top--];
printf("%d",k++);
printf("\t\t");
for(j=0;j<=5;j++)
if(x==v1[j])
{
flag=1;
break;
}
if(flag==1)
{
if(x=='#')
{
finish=1;
printf("acc!
\n");
getchar();
getchar();//?
?
?
?
exit
(1);
}
if(x==ch)
{
print();
print1();
printf("%c匹配\n",ch);
ch=B[++b];
flag=0;
}
else{
print();
print1();
printf("%c出错\n",ch);
exit
(1);
}
}
else{
for(j=0;j<=4;j++)
if(x==v2[j])
{
m=j;
break;
}
for(j=0;j<=5;j++)
if(ch==v1[j])
{
n=j;
break;
}
cha=C[m][n];
if(cha.origin!
='N')
{
print();
print1();
printf("%c->",cha.origin);
for(j=0;jprintf("%c",cha.array[j]);
printf("\n");
for(j=(cha.length-1);j>=0;j--)
A[++top]=cha.array[j];
if(A[top]=='')
top--;
}
else
{
print();
print1();
printf("%c出错\n",x);
exit
(1);
}
}
}while(finish==0);
}
四.实验结果
实验四逆波兰式
一.实验要求:
用C语言编写程序,用于实现对输入表达式
求值。
二.实验目的:
通过编写程序实现对输入表达式进行
求值得出结果,加深对逆波兰求解表达式过程理解,并将其掌握。
三.实验源程序代码:
#include
#include
#definemax100
charex[max];//存储后缀表达式
voidtrans(){//将算术表达式转化为后缀表达式
charstr[max];//存储原算术表达式的值
charstack[max];//作为栈使用
charch;
intsum,i,j,t,top=0;
printf("**********************************\n");
printf("*输入一个求值表达式,以#号结束。
*\n");
printf("**********************************\n");
printf("算术表达式:
");
i=0;//获取输入表达式,以#号结束
do{
i++;
scanf("%c",&str[i]);
}while(str[i]!
='#'&&i!
=max);
sum=i;
t=1;i=1;
ch=str[i];i++;
while(ch!
='#'){
switch(ch){
case'(':
top++;stack[top]=ch;
break;
case')':
while(stack[top]!
='('){
ex[t]=stack[top];top--;t++;
}
top--;
break;
case'+':
case'-':
while(top!
=0&&stack[top]!
='('){
ex[t]=stack[top];top--;t++;
}
top++;stack[top]=ch;
break;
case'*':
case'/':
while(stack[top]=='*'||stack[top]=='/'){
ex[t]=stack[top];top--;t++;
}
top++;stack[top]=ch;
break;
case'':
break;
default:
while(ch>='0'&&ch<='9'){
ex[t]=ch;t++;
ch=str[i];i++;
}
i--;
ex[t]='#';t++;
}
ch=str[i];i++;
}
while(top!
=0){
ex[t]=stack[top];t++;top--;
}
ex[t]='#';
printf("\n\t原来的表达式:
");
for(j=1;jprintf("%c",str[j]);
printf("\n\t后缀表达式:
",ex);
for(j=1;jprintf("%c",ex[j]);
}
voidcompvalue(){//计算后缀表达式的值
floatstack[max],d;
charch;
intt=1,top=0;
ch=ex[t];t++;
while(ch!
='#'){
switch(ch){
case'+':
stack[top-1]=stack[top-1]+stack[top];
top--;
break;
case'-':
stack[top-1]=stack[top-1]-stack[top];
top--;
break;
case'*':
stack[top-1]=stack[top-1]*stack[top];
top--;
break;
case'/':
if(stack[top]!
=0)
stack[top-1]=stack[top-1]/stack[top];
else{
printf("\n\t除零错误!
\n");
//exit(0);
}
top--;
break;
default:
d=0;
while(ch>='0'&&ch<='9'){
d=10*d+ch-'0';//字符到数字的转化
ch=ex[t];t++;
}
top++;
stack[top]=d;
}
ch=ex[t];t++;
}
printf("\n\t计算结果:
%g\n",stack[top]);
}
voidmain(){
while
(1)
{
trans();
compvalue();
}
}
四.实验结果
其中#号表示间隔符号,没有实际意义。
实验总结: