一、實驗目的
構造LR(1)分析程序,利用它進行語法分析,判斷給出的符號串是否為該文法識別的句子,了解LR(K)分析方法是嚴格的從左向右掃描,和自底向上的語法分析方法
二、實驗題目:
1、對下列文法,用LR(1)分析法對任意輸入的符號串進行分析:
(0)E->S
(1)S->BB
(2)B->aB
(3)B->b
2、LR(1)分析表為:
狀態 |
ACTION |
GOTO |
||||
a |
b |
# |
S |
B |
|
|
S0 |
S3 |
S4 |
|
1 |
2 |
|
S1 |
|
|
acc |
|
|
|
S2 |
S6 |
S7 |
|
|
5 |
|
S3 |
S3 |
S4 |
|
|
8 |
|
S4 |
r3 |
r3 |
|
|
|
|
S5 |
|
|
r1 |
|
|
|
S6 |
S6 |
S7 |
|
|
9 |
|
S7 |
|
|
r3 |
|
|
|
S8 |
r2 |
r2 |
|
|
|
|
S9 |
|
|
r2 |
|
|
(1)若輸入baba#,則輸出為:
步驟 狀態棧 符號棧 輸入串 ACTION GOTO
1 0 # baba# S4
2 04 #b aba# r3 2
3 02 #B aba# S6
4 026 #Ba ba# S7
5 0267 #Bab a# error
(2)若輸入bb#,則輸出為:
步驟 狀態棧 符號棧 輸入串 ACTION GOTO
1 0 # bb# S4
2 04 #b b# r3 2
3 02 #B b# S7
4 027 #Bb # r3 5
5 025 #BB # r1 1
6 01 #S # acc
四、參考程序代碼
#include<stdio.h>
#include<string.h>
char *action[10][3]= {"S3#","S4#",NULL,
NULL,NULL,"acc",
"S6#","S7#",NULL,
"S3#","S4#",NULL,
"r3#","r3#",NULL,
NULL,NULL,"r1#",
"S6#","S7#",NULL,
NULL,NULL,"r3#",
"r2#","r2#",NULL,
NULL,NULL,"r2#"
};
/* GOTO表*/
int goto1[10][2]= {1,2,
0,0,
0,5,
0,8,
0,0,
0,0,
0,9,
0,0,
0,0,
0,0
};
char vt[3]= {'a','b','#'}; /*存放終結符*/
char vn[2]= {'S','B'}; /*存放非終結符*/
char *LR[4]= {"E->S#","S->BB#","B->aB#","B->b#"}; /*存放產生式*/
int a[10];
char b[10],c[10],c1;
int top1,top2,top3,top,m,n;
int main()
{
int g,h,i,j,k,l,p,y,z,count;
char x,copy[10],copy1[10];
top1=0;
top2=0;
top3=0;
top=0;
a[0]=0;
y=a[0];
b[0]='#';
count=0;
z=0;
printf("請輸入表達式\n");
/*輸出狀態棧、輸出符號棧、輸出輸入串*/
do
{
scanf("%c",&c1);
c[top3]=c1;
top3=top3+1;
}
while(c1!='#');
printf("步驟\t狀態棧\t\t符號棧\t\t輸入串\t\tACTION\tGOTO\n");
do
{
y=z;
m=0;
n=0; /*y,z指向狀態棧棧頂*/
g=top;
j=0;
k=0;
x=c[top];
count++;
printf("%d\t",count);
while(m<=top1) /*輸出狀態棧*/
{
printf("%d",a[m]);
m=m+1;
}
printf("\t\t");
while(n<=top2) /*輸出符號棧*/
{
printf("%c",b[n]);
n=n+1;
}
printf("\t\t");
while(g<=top3) /*輸出輸入串*/
{
printf("%c",c[g]);
g=g+1;
}
printf("\t\t");
/*查動作表*/
if(x=='a')j=0;
if(x=='b')j=1;
if(x=='#')j=2;
if(action[y][j]==NULL)
{
printf("error\n");
getchar();
getchar();
return 0;
}
else
strcpy(copy,action[y][j]);
/*處理移進*/
if(copy[0]=='S')
{
z=copy[1]-'0';
top1=top1+1;
top2=top2+1;
a[top1]=z;
b[top2]=x;
top=top+1;
i=0;
while(copy[i]!='#')
{
printf("%c",copy[i]);
i++;
}
printf("\n");
}
/*處理歸約*/
if(copy[0]=='r')
{
i=0;
while(copy[i]!='#')
{
printf("%c",copy[i]);
i++;
}
h=copy[1]-'0';
strcpy(copy1,LR[h]);
if(copy1[0]=='S')k=0;
if(copy1[0]=='B')k=1;
l=strlen(LR[h])-4;
top1=top1-l+1;
top2=top2-l+1;
y=a[top1-1];
p=goto1[y][k];
a[top1]=p;
b[top2]=copy1[0];
z=p;
printf("\t\t");
printf("%d\n",p);
}
}
while(action[y][j]!="acc");
printf("acc\n");
getchar();
getchar();
return 0;
}