编译原理LL1文法源代码实验三Word下载.docx
- 文档编号:21985510
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:37
- 大小:223.21KB
编译原理LL1文法源代码实验三Word下载.docx
《编译原理LL1文法源代码实验三Word下载.docx》由会员分享,可在线阅读,更多相关《编译原理LL1文法源代码实验三Word下载.docx(37页珍藏版)》请在冰豆网上搜索。
当X∈VN时选相应产生式的右部β去替换X。
此时X出栈,β逆序入栈。
匹配:
当X∈VT时它与a进行匹配,其结果可能成功,也可能失败,如果成功则符号栈中将X退栈并将输入流指针向前移动一位,否则报错。
接受:
当格局为(#,空#)时报告分析成功。
报错:
出错后,停止分析。
并给出相应的错误提示信息。
2、实验内容
根据某一文法编制调试LL
(1)分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对预测分析LL
(1)分析法的理解。
对下列文法,用LL
(1)分析法对任意输入的符号串进行分析:
(1)E->
TG
(2)G->
+TG
(3)G->
ε
(4)T->
FS
(5)S->
*FS
(6)S->
(7)F->
(E)
(8)F->
i
程序输入一以#结束的符号串(包括+*()i#),如:
i+i*i#。
三、实验过程及步骤
1.总体思路分析及流程图
给定一个正规文法G,在LL
(1)预测分析中,必须先求出First集和Follow集,构造预测分析表。
求出预测分析表之后,再输入一个字符串,依据LL1分析表单步输出字符串的分析过程。
功能模块分解图
(1)主程序流程图
(2)核心算法流程图
1.计算非终结符的First集的算法及流程:
First集合的构造算法:
(1)若X∈VT,则First(X)={X}。
(2)若X∈VN,且有产生式X→a……,则把a加入到First(X)中;
若X→ε也是一条产生式,则把ε也加到First(X)中。
(3)若X→Y……是一个产生式且Y∈VN,则把First(Y)中的所有非ε-元素都加到First(X)中;
若X→Y1Y2…Yk是一个产生式,Y1,…,Yi-1都是非终结符,而且,对于任何j,1≤j≤i-1,First(Yj)都含有ε(即Y1…Yi-1*ε),则把First(Yj)中的所有非ε-元素都加到First(X)中;
特别是,若所有的First(Yj)均含有ε,j=1,2,…,k,则把ε加到First(X)中。
连续使用上面的规则,直至每个集合First不再增大为止。
2.计算非终结符的Follow集:
Follow集合的具体构造算法如下:
(1)对于文法的开始符号S,置#于Follow(S)中;
(2)若A→αBβ是一个产生式,则把First(β)|{ε}加至Follow(B)中;
(3)若A→αB是一个产生式,或A→αBβ是一个产生式而βε(即ε∈First(β)),则把Follow(A)加至Follow(B)中。
连续使用上面的规则,直至每个集合Follow不再增大为止。
3.预测分析控制程序的算法流程
LL
(1)文法(源代码)
#include"
stdio.h"
stdlib.h"
#defineMaxRuleNum8
#defineMaxVnNum5
#defineMaxVtNum5
#defineMaxStackDepth20
#defineMaxPLength20
#defineMaxStLength50
structpRNode/*产生式右部结构*/
{
intrCursor;
structpRNode*next;
};
structpNode
intlCursor;
intrLength;
/*右部长度*/
structpRNode*rHead;
/*右部结点头指针*/
charVn[MaxVnNum+1];
/*非终结符集*/
intvnNum;
charVt[MaxVtNum+1];
/*终结符集*/
intvtNum;
structpNodeP[MaxRuleNum];
intPNum;
charbuffer[MaxPLength+1];
charch;
charst[MaxStLength];
/*要分析的符号串*/
structcollectNode
intnVt;
structcollectNode*next;
structcollectNode*first[MaxVnNum+1];
/*first集*/
structcollectNode*follow[MaxVnNum+1];
/*follow集*/
intanalyseTable[MaxVnNum+1][MaxVtNum+1+1];
intanalyseStack[MaxStackDepth+1];
/*分析栈*/
inttopAnalyse;
/*分析栈顶*/
voidInit();
/*初始化*/
intIndexCh(charch);
voidInputVt();
/*输入终结符*/
voidInputVn();
/*输入非终结符*/
voidShowChArray(char*collect,intnum);
/*输出Vn或Vt的内容*/
voidInputP();
/*产生式输入*/
boolCheckP(char*st);
/*判断产生式正确性*/
voidFirst(intU);
voidAddFirst(intU,intnCh);
/*加入first集*/
boolHaveEmpty(intnVn);
voidFollow(intV);
/*计算follow集*/
voidAddFollow(intV,intnCh,intkind);
voidShowCollect(structcollectNode**collect);
/*输出first或follow集*/
voidFirstFollow();
/*计算first和follow*/
voidCreateAT();
/*构造预测分析表*/
voidShowAT();
/*输出分析表*/
voidIdentify(char*st);
voidInitStack();
voidShowStack();
voidPop();
voidPush(intr);
voidmain(void)
chartodo,ch;
Init();
InputVn();
InputVt();
InputP();
getchar();
FirstFollow();
printf("
所得first集为:
"
);
ShowCollect(first);
所得follow集为:
ShowCollect(follow);
CreateAT();
ShowAT();
todo='
y'
;
while('
==todo)
{
\n是否继续进行句型分析?
(y/n):
todo=getchar();
!
=todo&
&
'
n'
=todo)
\n(y/n)?
"
}
if('
inti;
InitStack();
请输入符号串(以#结束):
ch=getchar();
i=0;
#'
=ch&
i<
MaxStLength)
\n'
=ch)
st[i++]=ch;
==ch&
st[i]=ch;
Identify(st);
else
输入出错!
\n"
}
voidInit()
inti,j;
vnNum=0;
vtNum=0;
PNum=0;
for(i=0;
=MaxVnNum;
i++)
Vn[i]='
\0'
=MaxVtNum;
Vt[i]='
MaxRuleNum;
P[i].lCursor=NULL;
P[i].rHead=NULL;
P[i].rLength=0;
=MaxPLength;
buffer[i]='
MaxVnNum;
first[i]=NULL;
follow[i]=NULL;
for(j=0;
j<
=MaxVnNum+1;
j++)
analyseTable[i][j]=-1;
intIndexCh(charch)
intn;
n=0;
/*isVn?
*/
while(ch!
=Vn[n]&
=Vn[n])
n++;
return100+n;
/*isVt?
=Vt[n]&
=Vt[n])
returnn;
return-1;
voidShowChArray(char*collect)
intk=0;
=collect[k])
%c"
collect[k++]);
voidInputVn()
intinErr=1;
intn,k;
charch;
while(inErr)
\n请输入所有的非终结符,注意:
请将开始符放在第一位,并以#号结束:
ch='
/*初始化数组*/
while(n<
MaxVnNum)
Vn[n++]='
while(('
=ch)&
(n<
MaxVnNum))
-1==IndexCh(ch))
Vn[n++]=ch;
vnNum++;
Vn[n]='
/*以“#”标志结束用于判断长度是否合法*/
k=n;
if('
=(ch=getchar()))
;
\n符号数目超过限制!
inErr=1;
continue;
/*正确性确认,正确则,执行下下面,否则重新输入*/
Vn[k]='
ShowChArray(Vn);
输入正确确认?
(y/n):
scanf("
%c"
&
ch);
==ch)
录入错误重新输入!
else
inErr=0;
/*输入终结符*/
voidInputVt()
\n请输入所有的终结符,注意:
以#号结束:
MaxVtNum)
Vt[n++]='
MaxVtNum))
Vt[n++]=ch;
vtNum++;
Vt[n]='
Vt[k]='
ShowChArray(Vt);
voidInputP()
inti=0,n,num;
请输入文法产生式的个数:
%d"
num);
PNum=num;
/*消除回车符*/
\n请输入文法的%d个产生式,并以回车分隔每个产生式:
num);
while(i<
num)
第%d个:
i);
/*初始化*/
for(n=0;
n<
MaxPLength;
n++)
buffer[n]='
/*输入产生式串*/
=(ch=getchar())&
MaxPLength)
buffer[n++]=ch;
if(CheckP(buffer))
pRNode*pt,*qt;
P[i].lCursor=IndexCh(buffer[0]);
pt=(pRNode*)malloc(sizeof(pRNode));
pt->
rCursor=IndexCh(buffer[3]);
next=NULL;
P[i].rHead=pt;
n=4;
=buffer[n])
qt=(pRNode*)malloc(sizeof(pRNode));
qt->
rCursor=IndexCh(buffer[n]);
next=qt;
pt=qt;
P[i].rLength=n-3;
i++;
输入符号含非法在成分,请重新输入!
boolCheckP(char*st)
if(100>
IndexCh(st[0]))
returnfalse;
-'
=st[1])
>
'
=st[2])
for(n=3;
=st[n];
n++)
if(-1==IndexCh(st[n]))
returntrue;
voidFirst(intU)
PNum;
if(P[i].lCursor==U)
structpRNode*pt;
pt=P[i].rHead;
j=0;
while(j<
P[i].rLength)
rCursor)
AddFirst(U,pt->
rCursor);
break;
if(NULL==first[pt->
rCursor-100])
First(pt->
}
if(!
HaveEmpty(pt->
rCursor))
pt=pt->
next;
j++;
if(j>
=P[i].rLength)/*当产生式右部都能推出空时*/
AddFirst(U,-1);
/*加入first集*/
voidAddFirst(intU,intnCh)
structcollectNode*pt,*qt;
intch;
/*用于处理Vn*/
pt=NULL;
qt=NULL;
if(nCh<
100)
pt=first[U-100];
while(NULL!
=pt)
if(pt->
nVt==nCh)
qt=pt;
if(NULL==pt)
pt=(structcollectNode*)malloc(sizeof(structcollectNode));
nVt=nCh;
if(NULL==first[U-100])
first[U-100]=pt;
next=pt;
/*qt指向first集的最后一个元素*/
pt=first[nCh-100];
ch=pt->
nVt;
if(-1!
AddFirst(U,ch);
boolHaveEmpty(intnVn)
if(nVn<
100)
structcollectNode*pt;
pt=first[nVn-100];
if(-1==pt->
nVt)
voidFollow(intV)
structpRNode*pt;
if(100==V)/*当为初始符时*/
AddFollow(V,-1,0);
while(NU
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 LL1 文法 源代码 实验