编译原理课程设计SLR(1)文法与算符优先文法程序实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

题目 SLR(1)文法与算符优先文法程序实现
专业、班级
学号姓名
主要内容
构造SLR(1)分析表,并用程序实现
S->Sb|bAa
A->aSc|aSb|a
算符优先文法处理算术表达式
基本要求
构造SLR(1)分析表,并用程序实现,测试某表达式是否该文法的句子。

根据算符优先分析法并用程序实现,将表达式进行语法分析,判断一个表达式是否正确。

主要参考资料:
[1] 吕映芝,张素琴等.编译原理.清华大学出版社,1998
[2] 胡伦俊,徐兰芳,骆婷. 编译原理(第2版).电子工业出版社,2002
[3] 严蔚敏,吴伟民. 数据结构(C语言版). 清华大学出版社,1997
本科
编译原理课程设计总结报告
设计题目:SLR(1)文法与算符优先文法程序实现学生姓名:
系别:
专业:计算机科学与技术
班级:08级2班
学号:
指导教师:
2011年6月24日
目录
一、设计题目 (1)
二、运行环境 (1)
三、算法设计思想 (1)
1、LR算法思想 (1)
2、算符优先算法思想 (2)
四、算法流程图 (3)
1、SLR(1)流程图 (3)
2、算符优先流程图 (4)
五、算法设计分析 (5)
1、SLR(1)分析设计 (5)
2、算符优先文法分析与设计 (7)
六、运行结果分析 (8)
1、SLR(1)运行结果 (8)
2、算符优先运行结果 (8)
七、收获及体会 (10)
附录:程序清单 (11)
一、设计题目
SLR(1)文法与算符优先文法程序实现
二、运行环境
操作系统:Microsoft Windows XP
可视化环境:Microsoft Visual C++6.0
三、算法设计思想
1、LR算法思想
LR分析方法在规范规约的过程中,一方面记住已移进和规约出的整个符号串,即记住“历史”,另一方面根据所用的产生式推测未来可能碰到的输入符号,即对未来进行“展望”。

当一串貌似句柄的符号串呈现于分析栈的顶端时,我们希望能够根据记载的“历史”和“展望”以及“现实”的输入符号等三个方面的材料,来确定栈顶的符号串是否构成相对某一产生式的句柄。

LR分析器实质上是一个带先进后出存储器(栈)的确定有限状态自动机,每一步工作是由栈顶状态和现行输入符号所唯一决定的。

LR分析器的核心部分是一张分析表。

这张分析表包括两个部分,一是“动作”(ACTION)表,另一是“状态转换”(GOTO)表。

他们都是二维数组。

ACTION(s,a)规定了当状态s面临输入符号a时应采取什么动作。

GOTO (s,X)规定了状态s面对文法符号X(终结符或非终结符)时下一状态是什么。

显然,GOTO(s,X)定义了一个以文法符号为字母表的DFA。

每项ACTION(s,a)所规定的动作不外是下述四种可能之一:
(1)移进:把(s,a)的下一个状态s’= GOTO(s,X)和输入符号a 推进栈,下一输入符号变成现行输入符号。

(2)规约:指用某一产生式A→β进行规约。

假若β的长度为r,规约的动作是A,去除栈顶的r个项,使状态Sm-r 变成栈顶状态,然后把(Sm-r,A)的下一状态s’= GOTO(Sm-r,A)和文法符号A推进栈。

规约动作不改变现行输入符号。

执行规约动作意味着β(=Xm-r+1…Xm)已呈现
于栈顶而且是一个相对于A 的句柄。

(3)接受 :宣布分析成功,停止分析器的工作。

(4)报错 :发现源程序含有错误,调用出错处理程序。

2、 算符优先算法思想
算符优先分析方法是根据算符之间的优先关系而设计的一种自下而上的分析方法。

算符优先分析的基本思想是只规定算符之间的优先关系,也就是只考虑终结符之间的优先关系。

算符优先分析过程是自下而上的归约过程,所谓的算符优先分析就是定义算符之间(确切地说,终结符之间)的某种优先关系,借助于这种优先关系寻找“可归约串”和进行归约。

该文法必须满足以下条件:文法它的任一产生式的右部都不含两个相继(并列)的非终结符,即不含如下产生式右部:…QR …;
首先求出该文法的优先关系表,在程序中用2维数组表示,-1表示小于或者等于,大于为1,其它为0表示错误。

在输入一串字符串以后进行按照文法一步一步的进行规约,我所进行的是直接规约到文法的符号而不是规约到N 。

数据结构使用的是链表,用一个STRUCT 来表示一个元素,其中包含符号和下一个符号的指针。

算符优先分析法的关键是比较两个相继出现的终结符号的优先级而决定应采取的动作。

要完成算符间的优先级比较,就要先定义各种可能出相继出现的运算符的优先级,并将其表示成矩阵形式,在分析过程中通过查询矩阵元素而得算符间的优先关系。

输出

图 2 LR 分析器的模型
四、算法流程图
1、SLR(1)流程图
2、算符优先流程图
五、算法设计分析
1、S LR(1)分析设计
(1)将文法:G[S]:S->Sb|bAa A->aSc|aSb|a拓广增加文法:(0) M->S
(1) S->Sb (2) S-> bAa (3) A->aSc (4) A-> aSb (5) A-> a
(2)构造拓广文法G'的LR(0)项目集族,初始化项目G’
C=closure ({[S'→·S ]})
repeat
for 对C的每个项目集I和每个文法符号X,
if goto (I, X)非空且不在C中
then把goto (I, X)加入C中
until 没有更多的项目可以加入C
冲突分析与解决
首先检测所有的LR(0)项目集,当发现有移进—规约或规约—规约冲突时,判断其FOLLOW集是否为空,若为空,说明是SLR(1)文法,若不是,则说明不是SLR(1)文法。

计算FIRST、FOLLOW和unllable(可为空)的算法。

将所有的FIRST和FLLOW初始为空集合,将所有的unllable初始为false。

for 每一个终结符Z
FIRST[Z]←[Z]
repeat
for 每个产生式X—>Y1Y2…………Yk
for 每个i从1到k,每个j从i+1到k,
if所有的Y i都是可为空的
Then nullable[X]←true
if Y1Y2……Yi—1都是可为空的
Then FIRST[X]← FIRST[X] U FIRST[Y i]
if Yi+1……Yk都是可为空的
Then FOLLOW[Yi]← FLLOW[Yi] U FOLLOW[X]
if Yi+1……Yj-1都是可为空的
Then FOLLOW[Yi]← FOLLOW[Yi] U FIRST[Yj]
Until FIRST、FOLLOW和unllable在此轮迭代中没有改变
判断解决:
if FOLLOW[Yi] n FIRST[Yi]=空
该文法是SLR(1)文法
else
该文法不是SLR(1)文法。

(3)构造该文法的项目规范族及转换函数
文法G[S]LR(0)项目集及转换函
分析这些项目集,可知在项目集I1、I5中存在“移进-归约”冲突,在I9中存在“归约-归约”冲突,因此该文法不是LR(0)文法。

考虑含有冲突的项目集,能否用SLR(1)方法来解决。

对于I1={ S’ -> •S,S -> •Sb },由于FOLLOW(S’)∩{b}=Φ,I1中的存在“移进-归约”冲突可以用SLR(1)方法来解决。

对于I5={ A->a•,S ->•bAa },由于FOLLOW(A)∩{b}={a}∩{b}=Φ,I5中的存在“移进-归约”冲突可以用SLR(1)方法来解决。

对于I9={ A ->aS b•,S -> Sb• },由于FOLLOW(A)∩{b}={a}∩{b,c,#}=Φ,I9中的存在“归约-归约”冲突可以用SLR(1)方法来解决。

该文法是SLR(1)文法,相应的文法分析
(4)构造G[S]的SLR(1)分析表
G[S]的SLR(1)分析表
2、算符优先文法分析与设计
(1)对给定文法:E->E-T E->T T->T/F T->F F->(E) F->i进行拓广有:(0) W->#E# (1)E->E-T (2)E->T (3)T->T/F (4)T->F (5) F->(E) (6)F->i
六、运行结果分析
1、S LR(1)运行结果 SLR(1)分析表生成
对句子baab#进行分析
2、算符优先运行结果 对输入的文法进行拓广
生成各个非终结符的FIRSTVT集合LASTVT集
自动生成所给文法的关系矩阵
对句子(i-i)/i进行分析
对句子(i-i 进行分析
七、收获及体会
本课程设计任务是对两种语法分析技术的实现:SLR(1)类文法和算符优先文法。

实现对SLR(1)类文法和算符优先文法的判断及其相应分析表的构造,能够完成对所给的句子进行分析,判断它是否是该文法的句子。

其中算符优先程序可以自动对所输入的文法进行扩展,并生成算符优先关系表和各个非终结符的FIRSTVT 集和L ASTVT集。

同时能对所给的句子进行分析,打印输出各个分析栈的状态。

SLR(1)程序可以对输入的句子进行分析,并打印输出各个分析栈的状态。

在整个程序设计过程中,实现各个部分功能都需要利用到程序设计语言的知识和大量编程技巧,也利用到了大量的编译原理,自动生成算符优先矩阵是最困难的,其次是自动生成FIRSTVT集和
L ASTVT集也是比较棘手的,代码量比较大。

而由于在SLR(1)程序中分析表不是自动生成的,所以整个程序的难易度比算符优先小了许多,代码量也是比较少的。

本次编译原理课程设计虽然只经过了短短的一周时间,但是在这期间我学到了许多,提高了自己的综合分析问题、解决问题的能力,在此过程中懂得如何将书本的理论知识应用到实践中去,加深了对语法分析特别是算符优先和LR分析法思想理解理论知识的理解,与此同时也巩固了我C 语言编程的基本能力,对指针、链表、结构体的操作更加熟练,最重要的是本次编译实验加深了我对《编译原理》这门课程的理解。

从代码的编写、修改到文档的编写,自己都付出了很大的努力。

但是,由于所学知识不够全面,课程设计在很多方面还有待完善:在算符优先分析过程中编写的程序原意是可以对任意文法进行分析,但是在测试时却发现该程序不能对任意文法进行分析,而只能对确定的一类文法进行分析,问题之所在还没有能够找出来;在SLR(1)类文法部分,分析表不是通过程序自动生成的,也没有实现对是否是SLR(1)文法进行判断。

我相信在以后的学习过程中,会掌握更多知识,力求做到更好。

本次课程设计的完成离不开老师的悉心指导和帮助,同时在本次课程设计过程中也得到了同学们的帮助和支持,他们在整个过程中给我提出了许多宝贵的意见和建议,再此向各位老师和同学表示感谢!在老师和同学们的帮助下,我查阅了大量的资料,完成了本次课程设计。

最后,在做课程设计的过程中,同学之间那种团结互助,老师那种优良的工作的工作作风值得我们学习,希望在以后的学习和工作中也要不断的发扬这种精神。

附录:程序清单
一、SLR(1)程序实现
#define NVT 4
#define NVN 2
#define NLR 6
char ACTION[10][NVT]={ /*ACTION表*/ NULL,"s2",NULL,NULL,
NULL,"s3",NULL,"acc",
"s5",NULL,NULL,NULL,
NULL,"r1","r1","r1",
"s6",NULL,NULL,NULL, "r5","s2",NULL,NULL,
NULL,"r2","r2","r2",
NULL,"s9","s8",NULL,
"r3",NULL,NULL,NULL,
"r4","r1","r1","r1"};
int GOTO[10][NVN]={ 1,0, 0,0, 0,4, 0,0, 0,0, 7,0, 0,0, 0,0, 0,0, 0,0};
char Ter[NVT]={'a','b','c','#'};
char ImTer[NVN]={'S','A'};
char Rule[NLR]=
{"M->S","S->Sb","S->bAa","A->aSc","A->aS b","A->a"}; /*存放产生式*/
int State[10];//状态栈
char Symbol[10],Input[10],ch;
void Print_LR(){
int v,c;
printf("1>SLR(1)分析表:\n");
printf(" ACTION \t\t GOTO\n"); for(v=0;v<70;v++) printf("-");
printf("\t\t");
printf(" 状态a\t b\tc \t# \tS A\n"); for(v=0;v<70;v++)printf("-");
printf("\t\t");
for(v=0;v<10;v++){
printf("%5d",v);
for(c=0;c<4;c++){
if(ACTION[v][c]==NULL)
ACTION[v][c]=" ";
printf(" %8s",ACTION[v][c]);}
printf("\t ");
for(c=0;c<2;c++){
if(GOTO[v][c]==0)
printf(" ");
else printf("%4d",GOTO[v][c]);}
printf("\n");}
for(v=0;v<70;v++)
printf("-");
printf("\t\t");
for(v=0;v<70;v++)
printf("-");
printf("\t\t"); }
void main(){
int StateTop=0; //状态栈栈顶
int SymbolTop=0; //符号栈栈顶
int InputTop=0; //目前输入串的位置int InputIndex=0; //输入栈栈顶int i,j,k,y,z,StepCount=0,index;
char x,copy[4],copy1[10];
State[0]=0;y=State[0];
Symbol[0]='#';z=0;Print_LR();
printf("\n2>请输入表达式(以#结束):"); do{
scanf("%c",&ch);
nput[InputTop]=ch;
InputTop++;}while(ch!='#');
printf("\n");
for(int v=0;v<70;v++)printf("-");
printf("\n");
printf("步骤\t状态栈\t\t符号栈\t\t输入串\t\tACTION GOTO\n");
do{y=z; index=0;
j=0;k=0;x=Input[InputIndex];StepCount++; printf("%3d\t",StepCount);while(index<=St ateTop) /*输出状态栈*/{
printf("%d",State[index]);index++;}
printf("\t\t");index=0;
while(index<=SymbolTop) /*输出符号栈{ printf("%c",Symbol[index]);index++;} printf("\t\t");
index=InputIndex;
while(index<=InputTop) /*输出输入串*{ printf("%c",Input[index]);index++;}
printf("\t\t");
while(x!=Ter[j]&&j<NVT) j++;
if(j==NVT&&x!=Ter[j]){
printf("\n输入字符串不是由终结符组成\n");return;}
if(ACTION[y][j]==NULL){
printf("Error: Action IS NULL!\n");
return;}
else strcpy(copy,ACTION[y][j]);
if(copy[0]=='s') /*处理移进*/
{ if(copy[2]!='\0')
z=(copy[1]-'0')*10+copy[2]-'0';
Else z=copy[1]-'0';
StateTop++; SymbolTop++;
State[StateTop]=z;
Symbol[SymbolTop]=x;
InputIndex++; i=0;
while(copy[i]!='\0')
{ printf("%c",copy[i]);
i++; }
printf("\n");}
if(copy[0]=='r') /*处理归约*/{
i=0;
while(copy[i]!='\0')
{ printf("%c",copy[i]);i++;
}
strcpy(copy1,Rule[copy[1]-'0']);
while(copy1[0]!=ImTer[k]) k++; StateTop=StateTop-(strlen(Rule[copy[1]-'0'] )-4);
SymbolTop=SymbolTop-(strlen(Rule[copy[1 ]-'0'])-4);
y=State[StateTop-1];
State[StateTop]=GOTO[y][k];
Symbol[SymbolTop]=copy1[0];
z=GOTO[y][k];printf("\t");
printf("%4d\n",GOTO[y][k]);}
}while(ACTION[y][j]!="acc");
printf("acc\n");
for(int f=0;f<70;f++) printf("-");
二、算符优先程序实现
typedef struct{
char NT;
char T;
int flag;
}array;
typedef struct{
char E;
char e;
}charLode;
typedef struct{
charLode *base;
int top;
}charstack;
array F[20]; char str[50][50];
char Firstvt[50][50];
char Lastvt[50][50]; int Fnum;
int Tnum; int NTnum;
int lec; int FF=1; char r[20];
int Fsignal[30][30];
int FLAG=0; char Tsig1[1][30]; char Tsig2[30][1];
void Initstack(charstack *s) {
s->base=(charLode
*)malloc(30*sizeof(charLode));
s->top=-1;
}
void Push(charstack *s,charLode w) { s->top++;
s->base[s->top].E=w.E;
s->base[s->top].e=w.e;
}
void Pop(charstack *s,charLode *w){ w->E=s->base[s->top].E;
w->e=s->base[s->top].e;
s->top--;}
int IsEmpty(charstack s) {
if(s.top==-1) return 1;
else return 0;
}
int ISTerminator(char ch) {
if(ch>='A'&&ch<='Z') return 1;
else return 0;
}
int YN_Operator_Grammar(int n) {
int j=3,flag=1,i;
for(i=0;i<=n;i++)
while(str[i][j]!='\0'){
char a=str[i][j];
char b=str[i][j+1]; if(ISTerminator(a)&&ISTerminator(b) ){
flag=0;break;
}else j++;
} return flag;
}
void
IS_Operator_priority_grammar(int n){
int i;
for(i=0;i<=n;i++)
if(str[i][3]=='~'||YN_Operator_Gram mar(n)==0||FLAG==1){
printf("文法G不是算符优先文法!\n");
FF=0;break;
}
if(i>n)
printf("G是算符优先文法!\n");}
int search1(char r[],int Tnum,char a) int i;
for(i=0;i<Tnum;i++)
if(r[i]==a) break;
if(i==Tnum) return 0;
else return 1;
}
void createF(int n) {
int k=0,i=1; char c; int j; char t[10]; t[0]=str[0][0];
while(i<=n){
if(t[k]!=str[i][0]){
k++; t[k]=str[i][0]; i++;
}
Else i++;
}
Tnum=0;
for(i=0;i<=n;i++){
j=3;
while(str[i][j]!='\0'){
c=str[i][j];
if(ISTerminator(c)==0){
if(!search1(r,Tnum,c))
r[Tnum]=c;
Tnum++;}
j++;
}
}
Fnum=0;
for(i=0;i<k;i++)
for(j=0;j<Tnum-1;j++){
F[Fnum].NT=t[i]; F[Fnum].T=r[j]; F[Fnum].flag=0; Fnum++;
}
}
void search(charLode w) {
int i;
for(i=0;i<Fnum;i++)
if(F[i].NT==w.E&&F[i].T==w.e) {
F[i].flag=1;break;
}
}
void FirstVT(int n) {
charstack sta;charLode ww; charLode w; int i=0,k;
char a,b; Initstack(&sta);
while(i<=n){
k=3;w.E=str[i][0];
a=str[i][k];b=str[i][k+1];
if(!ISTerminator(a)){
w.e=a;Push(&sta,w);
search(w);
i++;
}
else if(ISTerminator(a)&&b!='\0'
&&!ISTerminator(b)){
w.e=b; Push(&sta,w);
search(w); i++;
}
Else i++;
}
while(!IsEmpty(sta)){
Pop(&sta,&ww);
for(i=0;i<=n;i++){
w.E=str[i][0];
if(str[i][3]==ww.E&&str[i][4]=='\0'){ w.e=ww.e;Push(&sta,w);
search(w);break;
}
else if(str[i][3]==ww.E&&w.E!=ww.E{ w.e=ww.e;Push(&sta,w);
search(w);break;
}
}
}
NTnum=0;k=1;i=1;
while(i<Fnum){
if(F[i-1].flag==1){
Firstvt[NTnum][0]=F[i-1].NT; Firstvt[NTnum][k]=F[i-1].T;
}
while(F[i].flag==0&&i<Fnum)
i++;
if(F[i].flag==1){
if(F[i].NT==Firstvt[NTnum][0])
k++;
else{ Firstvt[NTnum][k+1]='\0';
NTnum++;
k=1;
}
i++;
}} }
void LastVT(int n){
charstack sta;
charLode w; charLode e;
char a,b; int k,i;
for(i=0;i<Fnum;i++)
F[i].flag=0; i=0;
Initstack(&sta);
while(i<=n){
int k=strlen(str[i]);
w.E=str[i][0];
a=str[i][k-1];
b=str[i][k-2];
if(!ISTerminator(a)) {
w.e=a;Push(&sta,w);//进栈search(w); i++;
}
else
if(ISTerminator(a)&&!ISTerminator(b )){
w.e=b; Push(&sta,w);search(w);
i++;
}
else i++;
}
while(!IsEmpty(sta)){
Pop(&sta,&e);
for(i=0;i<=n;i++){
w.E=str[i][0];
if(str[i][3]==e.E&&str[i][4]=='\0'){ w.e=e.e;Push(&sta,w);
search(w);
} } }
k=1; i=1; lec=0;
while(i<Fnum)
{if(F[i-1].flag==1){
Lastvt[lec][0]=F[i-1].NT;
Lastvt[lec][k]=F[i-1].T;
}
while(F[i].flag==0&&i<Fnum)
i++;
if(F[i].flag==1){
if(F[i].NT==Firstvt[lec][0])
k++;
else{
Lastvt[lec][k+1]='\0';
lec++;k=1;
} i++;
}
}
}
void create_Priority_List(int n){
int i,j; int I,mm,pp,J;
for(j=1;j<=Tnum;j++)
Tsig1[0][j]=r[j-1];
for(i=1;i<=Tnum;i++)
Tsig2[i][0]=r[i-1];
for(i=1;i<=Tnum;i++)
for(j=1;j<=Tnum;j++) Fsignal[i][j]=0;
I=0,J=3;
while(I<=n) {
if(str[I][J+1]=='\0'){
I++; J=3;}
else {while(str[I][J+1]!='\0'){
char aa=str[I][J];char bb=str[I][J+1]; if(!ISTerminator(aa)&&
!ISTerminator(bb)){
for(i=1;i<=Tnum;i++) if(Tsig2[i][0]==aa) break; for(j=1;j<=Tnum;j++)
if(Tsig1[0][j]==bb)
break;
if(Fsignal[i][j]==0)
Fsignal[i][j]=1;
else {
FLAG=1;I=n+1;
}
J++;
}
if(!ISTerminator(aa)&&ISTerminator( bb)&&str[I][J+2]!='\0'&&!ISTerminat or(str[I][J+2])){
for(i=1;i<=Tnum;i++)
if(Tsig2[i][0]==aa)
break;
for(j=1;j<=Tnum;j++)
if(Tsig1[0][j]==str[I][J+2])
break;
if(Fsignal[i][j]==0)
Fsignal[i][j]=1;
else{
FLAG=1; I=n+1;
}}
if(!ISTerminator(aa)&&ISTerminator( bb)) {
for(i=1;i<=Tnum;i++)
if(aa==Tsig2[i][0]) break; for(j=0;j<=NTnum;j++)
if(bb==Firstvt[j][0]) break; for(mm=1;Firstvt[j][mm]!='\0';mm++ ){
for(pp=1;pp<=Tnum;pp++)
if(Tsig1[0][pp]==Firstvt[j][mm]) break;
if(Fsignal[i][pp]==0)
Fsignal[i][pp]=2;
else {
FLAG=1;I=n+1;
}
} J++;
}
if(ISTerminator(aa)&&!ISTerminator( bb)){
for(i=1;i<=Tnum;i++)
if(Tsig1[0][i]==bb) break; for(j=0;j<=lec;j++)
if(aa==Lastvt[j][0]) break; for(mm=1;Lastvt[j][mm]!='\0';mm++ ){
for(pp=1;pp<=Tnum;pp++)
if(Tsig2[pp][0]==Lastvt[j][mm]) break;
if(Fsignal[pp][i]==0)
Fsignal[pp][i]=3;
else { FLAG=1; I=n+1;
}
}J++;
} } } } }
int Priority_Type(char s,char a{
int i=1,j=1;
while(Tsig2[i][0]!=s) i++;
while(Tsig1[0][j]!=a) j++; if(Fsignal[i][j]==3) return 3;
elseif(Fsignal[i][j]==2) return 2; elseif(Fsignal[i][j]==1) return 1;
else return 0;
}
void print(char s[],char STR[][20],int q,int u,int ii,int k) {
int i; printf("%4d\t\t",u);
for(i=0;i<=k;i++) printf("%c",s[i]);
printf("\t\t"); for(i=q;i<=ii;i++)
printf("%c",STR[0][i]);printf("\t\t"); }
void process(char STR[][20],int ii) { int k=0,q=0,u=0,b,i,j;
char s[40],a;
printf(" 步骤\t\t字符栈\t\t输入串\t\t动作\n");
s[k]='#'; print(s,STR,q,u,ii,k); printf("\n"); k++; u++;
s[k]=STR[0][q]; q++;
print(s,STR,q,u,ii,k);
printf("移进\n");
while(q<=ii){ a=STR[0][q];
if(!ISTerminator(s[k]))j=k;
else j=k-1;
b=Priority_Type (s[j],a);
if(b==3){char Q=s[j];
loop: while(ISTerminator(s[j-1]))
j--;
if(Priority_Type (s[j-1],Q)==2) {for(i=j;i<k;i++) s[i]='\0';
k=j;s[k]='N';u++;
rint(s,STR,q,u,ii,k);}
else { Q=s[--j];
goto loop;
}printf("归约\n");
}
else if(b==2||b==1) {
k++; s[k]=a; u++;
q++; print(s,STR,q,u,ii,k); if(s[0]=='#'&&s[1]=='N'&&s[2]=='#') printf("移进\n");
else printf("接受\n");
} else{
printf("error\n");break;
}}
编译原理课程设计
18 / 21
if(s[0]=='#'&&s[1]=='N'&&s[2]=='#') printf("归约成功\n");
else printf("归约失败\n");} void main() { int n,i,j; printf("1>请输入你要定义的文
法G 的产生式的个数n:");
cin>>n; printf("请输入 %d 个文法产
生式:\n",n);
for(i=0;i<n;i++) { gets(str[i]);j=strlen(str[i]); str[i][j]='\0'; } str[i][0]='W'; str[i][1]='-'; str[i][2]='>'; str[i][3]='#'; str[i][4]=str[0][0]; str[i][5]='#'; printf("扩展后的产生式:\n");
str[i][6]='\0'; for(i=0;i<=n;i++) cout<<str[i]<<endl; if(YN_Operator_Grammar(n)==0)
cout<<" G 不是算符文法!"<<endl; if(YN_Operator_Grammar(n)==1) { printf("文法G 是算符文法!\n");
createF(n); FirstVT(n); LastVT(n); create_Priority_List(n); } if (FLAG==0) { cout<<"3> FIRSTVT 集如下:\n";
for(i=0;i<=NTnum;i++){ cout<<"\tFirstVT("<<Firstvt[i][0]<<")={"; for(int l=1;Firstvt[i][l+1]!='\0';l++) cout<<Firstvt[i][l]<<",";
cout<<Firstvt[i][l]<<"}"<<endl;
} }
cout<<"\tFirstVT(W)={#}"<<endl; cout<<"4>各非终结符的LASTVT 集如下:\n";
for(i=0;i<=lec;i++) {
cout<<"\tLastVT("<<Firstvt[i][0]<<")
={"; for(int l=1;Lastvt[i][l+1]!='\0';l++) cout<<Lastvt[i][l]<<",";
cout<<Lastvt[i][l]<<"}"<<endl; } cout<<"\tLastVT(W)={#}"<<endl; cout<<"5>文法G 的优先关系矩阵如下:"<<endl; for(i=1;i<Tnum;i++) { cout<<" ";
cout<<Tsig1[0][i]; }
cout<<endl;
for(i=1;i<Tnum;i++){ cout<<Tsig2[i][0]<<" "; for(j=1;j<Tnum;j++) {
if(Fsignal[i][j]==0) cout<<" "; else if(Fsignal[i][j]==1)cout<<"="; else if(Fsignal[i][j]==2)cout<<"<"; else if(Fsignal[i][j]==3)cout<<">";
cout<<" "; }cout<<endl; } IS_Operator_priority_grammar(n); if(FF==1) {char STR[1][20]; cout<<"6>输入字符串:"<<endl; gets(STR[0]); int ii=strlen(STR[0]);
STR[0][ii]='#' ; cout<<"规约的过程:"<<endl; process(STR,ii);
} }。

相关文档
最新文档