《編譯原理-LR分析法(附源碼).doc》由會(huì)員分享,可在線閱讀,更多相關(guān)《編譯原理-LR分析法(附源碼).doc(4頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
LR分析 實(shí)驗(yàn)報(bào)告
一、實(shí)驗(yàn)項(xiàng)目名稱
LR分析
二、實(shí)驗(yàn)?zāi)康?
掌握用 LR 分析法對(duì)表達(dá)式文法進(jìn)行自底向上語(yǔ)法分析的算法,加深對(duì) LR 分析法的
三、實(shí)驗(yàn)環(huán)境
Windows 10
Microsoft Visual Studio 2015
四、實(shí)驗(yàn)內(nèi)容
本次實(shí)驗(yàn)的 SLR(1)文法為表達(dá)式拓廣文法:
(0) S’→E
(1) E→E+T
(2) E→T
(3) T→T*F
(4) T→F
(5) F→(E)
(6) F→i
改進(jìn)后的 SLR(1)分析表如教材 142 頁(yè)圖 7.8。
編寫識(shí)別表達(dá)式拓廣文法的合法句子的 SLR(1)分析程序,對(duì)輸入的任意符號(hào)串,給 出分析過(guò)程及分析結(jié)果。分析過(guò)程要求輸出步驟、狀態(tài)棧、符號(hào)棧、輸入串和語(yǔ)法動(dòng)作。 如果該符號(hào)串不是表達(dá)式文法的合法句子,要給出盡量詳細(xì)的錯(cuò)誤提示。
五、實(shí)驗(yàn)步驟
將改進(jìn)后的 SLR(1)分析表存到一個(gè)數(shù)組中,本次實(shí)驗(yàn)的文法是寫在程序中的,不可改變,這種方法降低了實(shí)驗(yàn)代碼的難度。
六、源程序清單、測(cè)試數(shù)據(jù)、結(jié)果
#define _CRT_SECURE_NO_WARNINGS
#include
#include
char*action[12][6] = { /*ACTION*/
"S5#",NULL,NULL,"S4#",NULL,NULL,
NULL,"S6#",NULL,NULL,NULL,"acc",
NULL,"r2#","S7#",NULL,"r2#","r2#",
NULL,"r4#","r4#",NULL,"r4#","r4#",
"S5#",NULL,NULL,"S4#",NULL,NULL,
NULL,"r6#","r6#",NULL,"r6#","r6#",
"S5#",NULL,NULL,"S4#",NULL,NULL,
"S5#",NULL,NULL,"S4#",NULL,NULL,
NULL,"S6#",NULL,NULL,"S11#",NULL,
NULL,"r1#","S7#",NULL,"r1#","r1#",
NULL,"r3#","r3#",NULL,"r3#","r3#",
NULL,"r5#","r5#",NULL,"r5#","r5#", };
int goto1[12][3] = {/*GOTO*/
1,2,3,
0,0,0,
0,0,0,
0,0,0,
8,2,3,
0,0,0,
0,9,3,
0,0,10,
0,0,0,
0,0,0,
0,0,0,
0,0,0 };
char vt[6] = { i,+,(,),*,# };/*存放終結(jié)符*/
char vn[3] = { E,T,F, };/*存放非終結(jié)符*/
char *LR[7] = { "S->E#","E->E+T#","E->T#","T->T*F#","T->F#","F->(E)","F->i" };/*存放產(chǎn)生式*/
int a[10];
char b[10], c[10], c1;
int top1, top2, top3, top, m, n;
void lr() {
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("----------------請(qǐng)輸入表達(dá)式(以#結(jié)尾)--------------\n");
do {
scanf("%c", &c1);
c[top3] = c1;
top3 = top3 + 1;
} while (c1 != #);
printf("步驟\t狀態(tài)棧\t\t符號(hào)棧\t\t輸入串\t\tACTION\tGOTO\n");
do {
y = z; m = 0; n = 0; /*y,z指向狀態(tài)棧棧頂*/
g = top; j = 0; k = 0;
x = c[top];
count++;
printf("%d\t", count);
while (m <= top1) {/*輸出狀態(tài)棧*/
printf("%d", a[m]);
m = m + 1;
}
printf("\t\t");
while (n <= top2) {/*輸出符號(hào)棧*/
printf("%c", b[n]); n = n + 1;
}
printf("\t\t");
while (g <= top3) {/*輸出輸入串*/
printf("%c", c[g]);
g = g + 1;
}
printf("\t\t");
while (x != vt[j] && j <= 6)j++;
if (j == 6 && x != vt[j])
{
printf("error\n");
return;
}
if (action[y][j] == NULL) {
printf("error\n");
return;
}
else
strcpy(copy, action[y][j]);
if (copy[0] == S)
{/*處理移進(jìn)*/
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]);
while (copy1[0] != vn[k])k++;
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");
printf("%d\n", p);
}
}while (action[y][j] != "acc");
printf("acc\n");
getchar();
}
七、實(shí)驗(yàn)小結(jié)和思考
實(shí)現(xiàn)LR(1)文法很困難,我是直接將文法寫在程序中直接輸出分析表,而讓程序?qū)崿F(xiàn)對(duì)輸入符號(hào)串的分析,在編程過(guò)程中也遇到了很多困難,如對(duì)某些終結(jié)符的動(dòng)作或是規(guī)約函數(shù)的實(shí)現(xiàn),最后通過(guò)上網(wǎng)查找參考資料,都得到了解決。
鏈接地址:http://www.hcyjhs8.com/p-6665296.html