编译原理 实验二Word下载.docx
《编译原理 实验二Word下载.docx》由会员分享,可在线阅读,更多相关《编译原理 实验二Word下载.docx(15页珍藏版)》请在冰点文库上搜索。
![编译原理 实验二Word下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/9/9e00995f-f2ad-4514-a093-3686e39aa8cf/9e00995f-f2ad-4514-a093-3686e39aa8cf1.gif)
1.了解单词(内部编码)符号串中的短语句型结构形成规律。
2.理解和掌握语法分析过程中语法分析思想(LL,LR)的智能算法化方法。
二.实验环境
Windowsxp计算机一台,装有c++程序
三、实验内容与步骤
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#
四、实验过程与分析
(一)设计思想
(1)定义部分:
定义常量、变量、数据结构。
(2)初始化:
设立LL
(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);
(3)控制部分:
从键盘输入一个表达式符号串;
(4)利用LL
(1)分析算法进行表达式处理:
根据LL
(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。
(二)分析的流程图
实验分析:
#include<
stdio.h>
stdlib.h>
intvnNum,grammarNum,vtNum=6;
intorder;
intcount=1;
charGrammar[20][10],BlankTerminate[20][2];
charFirst[5][4]={'
S'
'
('
i'
\0'
'
E'
+'
$'
T'
M'
*'
F'
};
charFollow[5][6]={'
)'
#'
charSelect[8][4]={'
intIndiBlanket[6][7];
charVT[10]={'
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]='
;
break;
}
\n'
i++;
j=0;
continue;
-'
tp=fp;
fscanf(tp,"
nextChar);
if(nextChar=='
>
'
{
fp=tp;
continue;
}
|'
Grammar[i+1][0]=Grammar[i][0];
i++;
j=1;
Grammar[i][j]=singleChar;
j++;
}
//printf("
输入的文法:
\n"
for(intk=0;
k<
=i;
k++)
j=0;
while(Grammar[k][j]!
='
if(j==1)
//printf("
->
"
//printf("
Grammar[k][j]);
j++;
%d\n"
i);
fclose(fp);
returni;
}
intFill(chargi,charsij,intgrammarOrder)
inti,j;
for(i=0;
i<
vnNum;
i++)
if(First[i][0]==gi)break;
j=0;
while(VT[j]!
if(VT[j]==sij)break;
IndiBlanket[i][j]=grammarOrder;
return0;
intIndicate()
for(j=0;
j<
vtNum;
j++)
IndiBlanket[i][j]=-1;
=grammarNum;
while(Select[i][j]!
Fill(Grammar[i][0],Select[i][j],i);
printf("
预测分析表如下:
printf("
%3d"
IndiBlanket[i][j]);
printf("
intTerminate_$(intgrammarNum)
intj=0;
intcount;
for(inti=0;
BlankTerminate[i][1]='
0'
BlankTerminate[0][0]=Grammar[0][0];
if(Grammar[0][1]=='
BlankTerminate[0][1]='
1'
count=1;
for(i=1;
count;
if(Grammar[i][0]==BlankTerminate[j][0])
if(Grammar[i][1]=='
{
BlankTerminate[j][1]='
break;
}
if(j==count)
BlankTerminate[count][0]=Grammar[i][0];
if(Grammar[i][1]=='
BlankTerminate[count][1]='
count++;
count--;
$的终结符表:
/*
j;
%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++;
returnS;
intPrint(charAnalStr[],inti,intsign)
intstartpos=i;
%d\t"
count);
count++;
char*p=S.base;
while(p!
=S.top+2)
*p);
p++;
\t"
while(AnalStr[i]!
AnalStr[i]);
\t\t"
if(sign==0)
intj=0;
while(Grammar[order][j]!
Grammar[order][j]);
if(j==0)printf("
if(sign==1)
%c匹配\n"
AnalStr[startpos]);
intPush(chartopChar,charcurChar,intsign,intii,charAnalStr[])
if(First[i][0]==topChar)break;
if(VT[j]==curChar)break;
order=IndiBlanket[i][j];
Print(AnalStr,ii,sign);
j=1;
while(Grammar[order][j]!
{j++;
j--;
while(j!
=0)
if(Grammar[order][j]!
S.top++;
*S.top=Grammar[order][j];
j--;
intAnalysis()
{
inti=0;
intsign=0;
intcount=1;
charcurChar;
InitStack();
charAnalStr[10]={'
输入产生式:
scanf("
%s"
AnalStr);
步骤\t分析栈\t剩余输入串\t产生式\n"
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++;
else
printf("
AnalysisERROR!
return0;
if(topChar=='
break;
return0;
else
Push(topChar,curChar,sign,i,AnalStr);
预测分析成功!
intmain()
{inti,m;
grammarNum=ScanGrammar();
vnNum=Terminate_$(grammarNum);
Select集:
m=0;
while(Select[i][m]!
{//printf("
%c"
Select[i][m]);
m++;
//printf("
Indicate();
Analysis();
实验结果:
五、实验总结
经过本次的实验,使我真正的了解语法分析器的实现过程,让我更加深刻的语法分析器的实现原理,虽然在本次试验中遇到了各种各样的困难和错误,但在同学的帮助下还是把错误改正过来了,是的语法分析器能够正确的识别相应的语法和表达式。