语法分析器实验报告.docx
《语法分析器实验报告.docx》由会员分享,可在线阅读,更多相关《语法分析器实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
语法分析器实验报告
曲阜师范大学实验报告
No.2010416596
计算机系2010年级软件工程一班组日期2012-11-12
姓名王战海学号**********
课程编译原理成绩教师签章陈矗
实验名称:
语法分析实验
一、实验目的:
1、通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系;
2、了解语法分析的功能,掌握语法分析程序设计的原理和构造方法;
3、训练掌握开发应用程序的基本方法。
二、实验内容:
1、根据某一文法编制调试LL
(1)分析程序,以便对任意输入的符号串进行分析;
2、构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序;
3、分析法的功能是利用LL
(1)控制程序根据显示栈栈顶内容、向前看符号以及LL
(1)分析表,对输入符号串自上而下的分析过程。
三、实验要求:
1、编程时注意编程风格:
空行的使用、注释的使用、缩进的使用等。
2、如果遇到错误的表达式,应输出错误提示信息。
3、对下列文法,用LL
(1)分析法对任意输入的符号串进行分析:
(1)S->TE
(2)E->+TE|$
(3)T->FM
(4)M->*FM|$
(5)F->(E)|i#
四、实验环境:
WindowsXP
Eclipse,J2SE1.6
五、实验分析:
(一)设计思想
(1)定义部分:
定义常量、变量、数据结构。
(2)初始化:
设立LL
(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);
(3)控制部分:
从键盘输入一个表达式符号串;
(4)利用LL
(1)分析算法进行表达式处理:
根据LL
(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。
(二)分析的流程图
(三)算法设计
#include
#include
intvnNum,grammarNum,vtNum=6;
intorder;
intcount=1;
charGrammar[20][10],BlankTerminate[20][2];
charFirst[5][4]={'S','(','i','\0',
'E','+','$','\0',
'T','(','i','\0',
'M','*','$','\0',
'F','(','i','\0'};
charFollow[5][6]={'S',')','#','\0','\0','\0',
'E',')','#','\0','\0','\0',
'T','+',')','#','\0','\0',
'M','+',')','#','\0','\0',
'F','*','+',')','#','\0'};
charSelect[8][4]={'(','i','\0','\0',
'+','\0','\0','\0',
')','#','\0','\0',
'(','i','\0','\0',
'*','\0','\0','\0',
'+',')','#','\0',
'(','\0','\0','\0',
'i','\0','\0','\0'};
intIndiBlanket[6][7];
charVT[10]={'i','+','*','(',')','#'};
typedefstruct{
char*base;
char*top;
intstacksize;
}AnalStack;
AnalStackS;
intScanGrammar()
{
FILE*fp=fopen("文法.txt","r");
FILE*tp;
charsingleChar,nextChar;
inti=0,j=0;
while(!
feof(fp))
{
fscanf(fp,"%c",&singleChar);
if(singleChar=='#')
{
Grammar[i][j]='\0';
break;
}
if(singleChar=='\n')
{
Grammar[i][j]='\0';
i++;
j=0;
continue;
}
if(singleChar=='-')
{
tp=fp;
fscanf(tp,"%c",&nextChar);
if(nextChar=='>')
{
fp=tp;
continue;
}
}
if(singleChar=='|')
{
Grammar[i+1][0]=Grammar[i][0];
Grammar[i][j]='\0';
i++;
j=1;
continue;
}
Grammar[i][j]=singleChar;
j++;
}
//printf("输入的文法:
\n");
for(intk=0;k<=i;k++)
{
j=0;
while(Grammar[k][j]!
='\0')
{
if(j==1)
{
//printf("->");
}
//printf("%c",Grammar[k][j]);
j++;
}
//printf("\n");
}
//printf("%d\n",i);
fclose(fp);
returni;
}
intFill(chargi,charsij,intgrammarOrder)
{
inti,j;
for(i=0;i{
if(First[i][0]==gi)break;
}
j=0;
while(VT[j]!
='\0')
{
if(VT[j]==sij)break;
j++;
}
IndiBlanket[i][j]=grammarOrder;
return0;
}
intIndicate()
{
inti,j;
for(i=0;i{
for(j=0;j{
IndiBlanket[i][j]=-1;
}
}
for(i=0;i<=grammarNum;i++)
{
j=0;
while(Select[i][j]!
='\0')
{
Fill(Grammar[i][0],Select[i][j],i);
j++;
}
}
printf("预测分析表如下:
\n");
for(i=0;i{
for(j=0;j{
printf("%3d",IndiBlanket[i][j]);
}
printf("\n");
}
return0;
}
intTerminate_$(intgrammarNum)
{
intj=0;
intcount;
for(inti=0;i<=grammarNum;i++)
{
BlankTerminate[i][1]='0';
}
BlankTerminate[0][0]=Grammar[0][0];
if(Grammar[0][1]=='$')
{
BlankTerminate[0][1]='1';
}
count=1;
for(i=1;i<=grammarNum;i++)
{
for(j=0;j{
if(Grammar[i][0]==BlankTerminate[j][0])
{
if(Grammar[i][1]=='$')
{
BlankTerminate[j][1]='1';
break;
}
}
}
if(j==count)
{
BlankTerminate[count][0]=Grammar[i][0];
if(Grammar[i][1]=='$')
{
BlankTerminate[count][1]='1';
}
count++;
}
}
count--;
//printf("$的终结符表:
\n");
/*
for(i=0;i{
printf("%c:
%c\n",BlankTerminate[i][0],BlankTerminate[i][1]);
}
*/
returncount;
}
AnalStackInitStack()
{
S.base=(char*)malloc(100*sizeof(char));
if(!
S.base)exit
(1);
S.top=S.base;
S.stacksize=100;
*S.top='#';
S.top++;
*S.top='S';
returnS;
}
intPrint(charAnalStr[],inti,intsign)
{
intstartpos=i;
printf("%d\t",count);
count++;
char*p=S.base;
while(p!
=S.top+2)
{
printf("%c",*p);
p++;
}
printf("\t");
while(AnalStr[i]!
='\0')
{
printf("%c",AnalStr[i]);
i++;
}
printf("\t\t");
if(sign==0)
{
intj=0;
while(Grammar[order][j]!
='\0')
{
printf("%c",Grammar[order][j]);
if(j==0)printf("->");
j++;
}
printf("\n");
}
if(sign==1)
{
printf("%c匹配\n",AnalStr[startpos]);
}
return0;
}
intPush(chartopChar,charcurChar,intsign,intii,charAnalStr[])
{
inti,j;
for(i=0;i{
if(First[i][0]==topChar)break;
}
j=0;
while(VT[j]!
='\0')
{
if(VT[j]==curChar)break;
j++;
}
order=IndiBlanket[i][j];
Print(AnalStr,ii,sign);
j=1;
while(Grammar[order][j]!
='\0')
{j++;}
j--;
while(j!
=0)
{
if(Grammar[order][j]!
='$')
{
S.top++;
*S.top=Grammar[order][j];
}
j--;
}
return0;
}
intAnalysis()
{
inti=0;
intsign=0;
intcount=1;
charcurChar;
InitStack();
charAnalStr[10]={'\0'};
printf("输入产生式:
\n");
scanf("%s",&AnalStr);
printf("步骤\t分析栈\t剩余输入串\t产生式\n");
while(AnalStr[i]!
='\0')
{
sign=0;
curChar=AnalStr[i];
char*p=S.top;
chartopChar=*p;
S.top--;
if(topChar<'A'||topChar>'Z')
{
if(topChar==curChar)
{
sign=1;
Print(AnalStr,i,sign);
i++;
continue;
}
else
{
printf("AnalysisERROR!
\n");
return0;
}
}
if(topChar=='#')
{
if(topChar==curChar)
{
Print(AnalStr,i,sign);
break;
}
else
{
return0;
}
}
else
{
Push(topChar,curChar,sign,i,AnalStr);
}
}
printf("预测分析成功!
\n");
return0;
}
intmain()
{inti,m;
grammarNum=ScanGrammar();
vnNum=Terminate_$(grammarNum);
//printf("Select集:
\n");
for(i=0;i<=grammarNum;i++)
{
m=0;
while(Select[i][m]!
='\0')
{//printf("%c",Select[i][m]);
m++;
}
//printf("\n");
}
Indicate();
Analysis();
return0;
}
六、运行结果
七、实验结论:
经过本次的实验,使我真正的了解语法分析器的实现过程,让我更加深刻的语法分析器的实现原理,虽然在本次试验中遇到了各种各样的困难和错误,但在同学的帮助下还是把错误改正过来了,是的语法分析器能够正确的识别相应的语法和表达式。