LR1分析法.docx

上传人:b****6 文档编号:8671621 上传时间:2023-02-01 格式:DOCX 页数:15 大小:278.68KB
下载 相关 举报
LR1分析法.docx_第1页
第1页 / 共15页
LR1分析法.docx_第2页
第2页 / 共15页
LR1分析法.docx_第3页
第3页 / 共15页
LR1分析法.docx_第4页
第4页 / 共15页
LR1分析法.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

LR1分析法.docx

《LR1分析法.docx》由会员分享,可在线阅读,更多相关《LR1分析法.docx(15页珍藏版)》请在冰豆网上搜索。

LR1分析法.docx

LR1分析法

 

课程:

编译原理

 

实验报告

 

专业

班级

姓名

学号

指导教师

学年学期

 

实验2.3LR

(1)分析法

1.实验目的

1.构造LR

(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子.

2.实验平台

Windows+VC+Win32Console

范例程序:

“4-LR1.c”

3.实验过程和指导

1.调试范例程序

范例程序目前还不能对所有输入串进行正确的分析.

输出格式如下:

步骤

状态栈

符号栈

输入串

Action

Goto

(1)请输出完整的分析过程。

即详细输出每一步骤状态栈和符号栈的变化情况.

(2)请输出最终的分析结果,即输入串“合法”或“非法”.

2.对一个新的文法实现LR

(1)分析。

4.程序代码

第一种文法

#include

#include

char*action[10][3]={"S3#","S4#",NULL,/*ACTION表*/

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#"};

intgoto1[10][2]={1,2,/*QOTO表*/

0,0,

0,5,

0,8,

0,0,

0,0,

0,9,

0,0,

0,0,

0,0};

charvt[3]={'a','b','#'};/*存放非终结符*/

charvn[2]={'S','B'};/*存放终结符*/

char*LR[4]={"E->S#","S->BB#","B->aB#","B->b#"};/*存放产生式*/

inta[10];

charb[10],c[10],c1;

inttop1,top2,top3,top,m,n;

voidmain(){

intg,h,i,j,k,l,p,y,z,count;

charx,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");

while(x!

=vt[j]&&j<=2)j++;

if(j==2&&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'){/*处理移进*/

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();

}

测试一

(1)测试bb#

(2)测试abb#

(3)测试abbb#

第二种文发

#include

#include

usingnamespacestd;

stacksymbol;

stackstate;

charsen[50];

charsym[12][6]={//符号表

{'s','e','e','s','e','e'},

{'e','s','e','e','e','a'},

{'r','r','s','r','r','r'},

{'r','r','r','r','r','r'},

{'s','e','e','s','e','e'},

{'r','r','r','r','r','r'},

{'s','e','e','s','e','e'},

{'s','e','e','s','e','e'},

{'e','s','e','e','s','e'},

{'r','r','s','r','r','r'},

{'r','r','r','r','r','r'},

{'r','r','r','r','r','r'}

};

charsnum[12][6]={//数字表

{5,1,1,4,2,1},

{3,6,5,3,2,0},

{2,2,7,2,2,2},

{4,4,4,4,4,4},

{5,1,1,4,2,1},

{6,6,6,6,6,6},

{5,1,1,4,2,1},

{5,1,1,4,2,1},

{3,6,5,3,11,4},

{1,1,7,1,1,1},

{3,3,3,3,3,3},

{5,5,5,5,5,5}

};

intgo2[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}

};

voidaction(inti,char*&a,char&how,int&num,char&A,int&b)//action函数[i,a]

{

intj;

switch(*a)

{

case'i':

j=0;break;

case'+':

j=1;break;

case'*':

j=2;break;

case'(':

j=3;break;

case')':

j=4;break;

case'#':

j=5;break;

default:

j=-1;break;

}

if(j!

=-1)

{

how=sym[i][j];

num=snum[i][j];

if(how=='r')

{

switch(num)

{

case1:

A='E',b=3;

cout<<"按E->E+T规约"<

break;

case2:

A='E',b=1;

cout<<"按E->T规约"<

break;

case3:

A='T',b=3;

cout<<"按T->T*F规约"<

break;

case4:

A='T',b=1;

cout<<"按T->F规约"<

break;

case5:

A='F',b=3;

cout<<"按F->(E)规约"<

break;

case6:

A='F',b=1;

cout<<"按F->id规约"<

break;

default:

break;

}

}

}

}

intgo(intt,charA)//goto[t,A]

{

switch(A)

{

case'E':

returngo2[t][0];break;

case'T':

returngo2[t][1];break;

case'F':

returngo2[t][2];break;

}

}

voiderror(inti,intj,char*&a)//error处理函数

{

cout<<"error"<

switch(j)

{

case1:

//期望输入id或左括号,但是碰到+,*,或$,就假设已经输入id了,转到状态5

state.push(5);

symbol.push('i');//必须有这个,如果假设输入id的话,符号栈里必须有....

cout<<"缺少运算对象id"<

break;

case2:

//从输入中删除右括号

a++;

cout<<"不配对的右括号"<

break;

case3:

//期望碰到+,但是输入id或左括号,假设已经输入算符+,转到状态6

state.push(6);

symbol.push('+');

cout<<"缺少运算符"<

break;

case4:

//缺少右括号,假设已经输入右括号,转到状态11

state.push(11);

symbol.push(')');

cout<<"缺少右括号"<

break;

case5:

a++;

cout<<"*号无效,应该输入+号!

"<

case6:

a++;

}

}

intmain()

{

ints;

char*a;

charhow;

intnum;

intb;

charA;

while

(1)

{

cin>>sen;

a=sen;

state.push(0);//先输入0状态

while(*a!

='\0')

{

b=0;num=0;how='\0';A='\0';

s=state.top();

action(s,a,how,num,A,b);

if(how=='s')//移进

{

cout<<"移进"<

symbol.push(*a);

state.push(num);

//if(*a=='i')

//a++;//在这里忽略i后面的d

a++;

}

elseif(how=='r')//规约

{

for(inti=0;i

{

if(!

state.empty())

state.pop();

if(!

symbol.empty())

symbol.pop();

}

intt=state.top();

symbol.push(A);

state.push(go(t,A));

}

elseif(how=='a')//接受

break;

else

{

error(s,num,a);//错误处理

}

}

cout<<"成功接受"<

}

return0;

}

文法二说明

1.使用如下文法:

EE+T|T

TT*F|F

F(E)|id

2.对于任意给定的输入串(词法记号流)进行语法分析,采用LR分析器来完成。

手工构造LR分析表,利用移进-归约分析算法,输出对应的动作部分。

如:

输入:

id*+id/(id+id)#

输出:

移进

按F->id归约

移进

error

3.有一定的错误处理功能。

即对错误能提示,并且能在一定程度上忽略尽量少的记号来进行接下来的分析。

例如:

从状态0开始的记号流为:

bm

将b移进之后,栈里的情况应该为:

0b2

此时查表发现action[2,m]=error

输出打印:

error

把A和状态1相继压入栈,用户指针后移到FOLLOW(A)对应的元素继续分析。

测试一

(1)测试i+(i*i)#

(2)测试i+i#

(3)测试i+#

5.实验心得

经过这个实验的练习,通过对程序的分析,让我进一步了解LR

(1)算法的思想以及它的进一步程序实现,让我对它的了解从简单的理论上升到程序实现的级别,有理论上升到实际,让我更清楚它的用途。

6.实验体会及思考

在对实验的分析的时候,也遇到很多的问题,刚开始根本想不到用程序怎么实现这么繁杂的LR

(1)文法,后来看了程序才知道,才转过来弯,通过对这个程序的分析与揣摩,让自己对这方面文法的实现有了一定的头绪,对以后的的一些文法的程序实现会有很大的帮助,通过练习我也感到理论仅留在理论是远远不行的,用通过一定方式实现才有实用价值。

学会了,合理利用网络资源!

7.文法中的缺陷

首先,文法一,只是利用例子文法,没有加入自己思想,文法二没有实现减法,和除法。

并且文法没有按照文法一那样输出,表现效果不如文法一好。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1