北邮编译原理语义分析文档和程序.docx

上传人:b****8 文档编号:9090867 上传时间:2023-02-03 格式:DOCX 页数:15 大小:74.95KB
下载 相关 举报
北邮编译原理语义分析文档和程序.docx_第1页
第1页 / 共15页
北邮编译原理语义分析文档和程序.docx_第2页
第2页 / 共15页
北邮编译原理语义分析文档和程序.docx_第3页
第3页 / 共15页
北邮编译原理语义分析文档和程序.docx_第4页
第4页 / 共15页
北邮编译原理语义分析文档和程序.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

北邮编译原理语义分析文档和程序.docx

《北邮编译原理语义分析文档和程序.docx》由会员分享,可在线阅读,更多相关《北邮编译原理语义分析文档和程序.docx(15页珍藏版)》请在冰豆网上搜索。

北邮编译原理语义分析文档和程序.docx

北邮编译原理语义分析文档和程序

实验报告

班级:

2011211314

姓名:

oneseven

学号:

一.题目:

语义分析程序的设计与实现。

二.实验内容:

编写语义分析程序,实现对算术表达式的类型检查和求值。

要求所分析算术表达式由如下的文法产生。

E->E+T|E-T|T

T->T*F|T/F|F

F->num.num|(E)|num

三.实验要求:

用自底向上的语法制导翻译技术实现对表达式的分析和翻译。

(1)写出满足要求的语法制导定义或翻译方案。

(2)编写分析程序,实现对表达式的类型进行检查和求值,并输出:

1.分析过程中所有产生式。

2.识别出的表达式的类型。

3.识别出的表达式的值。

(3)实验方法:

可以选用以下两种方法之一。

1.自己编写分析程序。

2.利用YACC自动生成工具。

四.实验分析:

1.步骤:

(1)根据题目所给出的文法构造相应的拓广文法,并求出该文法各非终结符的FIRST、FOLLOW集合;

(2)构造拓广文法的项目集规范族,并构造出识别所有前缀的DFA;

(3)构造文法的LR分析表;

(4)由此构造LR分析程序。

(5)写出满足要求的翻译方案。

(6)实现对表达式的类型进行检查和求值,并输出。

2.实现方法:

1.输入缓冲区为一个字符型数组,读入输入的算术表达式并保存在此,以’$’结束;

2.定义两个二维整形数组,goto和action,其值大于零代表移进操作,小于零代表规约操作,引进的状态或规约用到的产生式又绝对值表示。

等于零代表出现错误。

等于特殊值-10代表acc.状态。

3.处理输入表达式中代表id和num的子串,分别将它们转化为'i'和'n'进行分析;

4.根据分析表,相应进行语法分析,移近或规约,按算法4.3的步骤完成过程。

5.由于要求进行类型检查和求值,所以可以定义两个综合属性,一个记录值一个记录类型,存放在结构中,一并传入传出。

输出的产生式可以作为虚拟综合属性,在产生式的最后打印出来。

将类型检查和求值归于一次扫描,把类型和值赋给相应的表达式。

由于只具有综合属性,故可以用S属性的自底向上翻译实现,利用LR分析程序来实现,只需扩充分析站和改造分析程序。

本次实验是基于语法分析方法3,因此相关的代码和文档类似于上次实验。

3.翻译方案:

E->E’+T{E.val=E’.val+T.val}

{if(E’.type==real||T.type==real)E.type=real;elseE.type=integer;}

E->E’-T{E.val=E’.val-T.val}

{if(E’.type==real||T.type==real)E.type=real;elseE.type=integer;}

E->T{E.val=T.val}{E.type=T.type}

T->T’*F{T.val=T’.val*F.val}

{if(T’.type==real||F.type==real)T.type=real;elseT.type=integer;}

T->T’/F{T.val=T’.val/F.val}

{if(T’.type==real||F.type==real)T.type=real;elseT.type=integer;}

T->F{T.val=F.val}{T.type=F.type}

F->num.num{F.val=num.num.val}{F.type=real}

F->(E){F.val=E.val}{F.type=E.type}

F->num{F.val=num.val}{F.type=integer}

3.计算过程:

文法对应的拓广文法为:

(0)E’->E

(1)E->E+T

(2)E->E-T

(3)E->T(4)T->T*F(5)T->T/F

(6)T->F(7)F->num.num(8)F->(E)

(9)F->num

求的各个非终结符的FIRST、FOLLOW集合为:

E

T

F

FIRST

(,num

(,num

(,num

FOLLOW

$,),+,-

$,),+,-,*,/

$,),+,-,*,/

4.SLR

(1)分析表为:

状态

+

-

*

/

.

Num

$

E

T

F

0

S5

S4

1

2

3

1

S6

S7

acc

2

R3

R3

S8

S9

R3

R3

3

R6

R6

R6

R6

R6

R6

4

R9

R9

R9

R9

R9

S10

R9

5

S5

S4

11

2

3

6

S5

S4

12

3

7

S5

S4

13

3

8

S5

S4

14

9

S5

S4

15

10

S16

11

S6

S7

S17

12

R1

R1

S9

S10

R1

R1

13

R2

R2

S9

S10

R2

R2

14

R4

R4

R4

R4

R4

R4

15

R5

R5

R5

R5

R5

R5

16

R7

R7

R7

R7

R7

R7

17

R8

R8

R8r

R8

R8

R8

5.主程序说明:

voidGet_str(void)//获取待分析输入表达式

intJudge_num(charch)//判断字符是否为构成num的数字

intGet_ternum(charch)//返回终结符在终结符表中的下标

intGet_unternum(charch)//返回非终结符在非终结符表中的下标

intJudge_ter(charch)//判断字符是否为终结符

intJudge_unter(charch)//判断字符是否为非终结符

voidfanyi(intchioce)//翻译方案

voidAnalyse_output(void)//使用LR语法预测分析表分析输入的表达式并输出分析结果

五.代码。

#include

#include

#include

usingnamespacestd;

charterminal[9]={'+','-','*','/','(',')','.','n','$'};//终结符表

charunterminal[3]={'E','T','F'};//非终结符表

chargrammar[10][10]={//输出产生式

"SE","EE+T","EE-T","ET","TT*F",

"TT/F","TF","Fn.n","F(E)","Fn"

};

intGoto[18][3]={//LR()语法预测分析表

1,2,3,0,0,0,0,0,0,0,0,0,

0,0,0,11,2,3,0,12,3,0,13,3,

0,0,14,0,0,15,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0

};

intAction[18][9]={

0,0,0,0,5,0,0,4,0,

6,7,0,0,0,0,0,0,-10,

-3,-3,8,9,0,-3,0,0,-3,

-6,-6,-6,-6,0,-6,0,0,-6,

-9,-9,-9,-9,0,-9,10,0,-9,

0,0,0,0,5,0,0,4,0,

0,0,0,0,5,0,0,4,0,

0,0,0,0,5,0,0,4,0,

0,0,0,0,5,0,0,4,0,

0,0,0,0,5,0,0,4,0,

0,0,0,0,0,0,0,16,0,

6,7,0,0,0,17,0,0,0,

-1,-1,8,9,0,-1,0,0,-1,

-2,-2,8,9,0,-2,0,0,-2,

-4,-4,-4,-4,0,-4,0,0,-4,

-5,-5,-5,-5,0,-5,0,0,-5,

-7,-7,-7,-7,0,-7,0,0,-7,

-8,-8,-8,-8,0,-8,0,0,-8,

};

charstr[40];//待分析的输入表达式

floatvalue[40];//产生式的值

inttop=0,state[40],type[40];//状态,栈顶,产生式的类型

voidGet_str(void)//获取待分析输入表达式

{

intlen;

printf("请输入待分析的表达式:

");

scanf("%s",&str);

for(len=0;str[len]!

='\0';len++);

str[len]='$';

str[len+1]='\0';

len++;

state[top]=0;

}

intJudge_num(charch)//判断字符是否为构成num的数字

{

if(ch>='0'&&ch<='9')

return1;

else

return0;

}

intGet_ternum(charch)//返回终结符在终结符表中的下标

{

inti;

for(i=0;i<9;i++)

if(ch==terminal[i])

returni;

return-1;

}

intGet_unternum(charch)//返回非终结符在非终结符表中的下标

{

inti;

for(i=0;i<3;i++)

if(ch==unterminal[i])

returni;

return-1;

}

intJudge_ter(charch)//判断字符是否为终结符

{

if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='.'||ch=='n'||ch=='$')

return1;

else

return0;

}

intJudge_unter(charch)//判断字符是否为非终结符

{

if(ch=='E'||ch=='P'||ch=='T')

return1;

else

return0;

}

voidfanyi(intchioce)//翻译方案

{

inti;

floatj;

switch(chioce){

case1:

value[top-2]=value[top-2]+value[top];

if(type[top]==2||type[top-2]==2)

type[top-2]=2;

else

type[top-2]=1;

break;

case2:

value[top-2]=value[top-2]-value[top];

if(type[top]==2||type[top-2]==2)

type[top-2]=2;

else

type[top-2]=1;

break;

case3:

value[top]=value[top];

type[top]=type[top];

break;

case4:

value[top-2]=value[top-2]*value[top];

if(type[top]==2||type[top-2]==2)

type[top-2]=2;

else

type[top-2]=1;

break;

case5:

if(type[top]==2||type[top-2]==2||(int)value[top-2]%(int)value[top]!

=0)

type[top-2]=2;

else

type[top-2]=1;

value[top-2]=value[top-2]/value[top];

break;

case6:

value[top]=value[top];

type[top]=type[top];

break;

case7:

j=value[top];

for(i=0;j>=1;i++)

j=j/10;

value[top-2]=value[top-2]+value[top]*pow(0.1,i);

type[top-2]=2;

break;

case8:

value[top-2]=value[top-1];

type[top-2]=type[top-1];

break;

case9:

value[top]=value[top];

type[top]=1;

break;

default:

break;

}

}

voidAnalyse_output(void)//使用LR()语法预测分析表分析输入的表达式并输出分析结果

{

inti,j,m;

intS,step=0,ip=0,length=0;

chara;

cout<<"分析过程产生式:

\n";

do

{

S=state[top];//获取栈顶符号

a=str[ip];//获取输入串中将要进行分析的符号

if(a=='+'||a=='-'||a=='*'||a=='/'||a=='('||a==')'||a=='.'||a=='$')

length=1;

else

{

j=ip;

length=0;

i=0;

while(Judge_num(a))

{

i=i*10+a-'0';

length++;

j++;

a=str[j];

}

a='n';

}

m=Get_ternum(a);

if(Action[S][m]>0)//移进

{

top++;

if(a=='n')

value[top]=i;

state[top]=Action[S][m];

ip+=length;

}

elseif(Action[S][m]<0&&Action[S][m]!

=-10)//规约

{

i=0-Action[S][m];

fanyi(i);

for(j=1;grammar[i][j]!

='\0';j++)

top--;

m=state[top];

j=Get_unternum(grammar[i][0]);

top++;

state[top]=Goto[m][j];

step++;

cout<<"("<

for(j=1;grammar[i][j]!

='\0';j++)//输出产生式

{

if(grammar[i][j]=='n')

cout<<"num";

else

cout<

}

cout<<"\tvalue:

"<

cout<<"\t\ttype:

";

if(type[top]==1)

cout<<"integer\n";

else

cout<<"real\n";

}

elseif(Action[S][m]==-10)

{

cout<<"表达式的值:

"<

cout<<"\n表达式的类型:

";

if(type[top]==1)

cout<<"integer\n";

else

cout<<"real\n";

return;

}

else

{

cout<<"发生错误!

\t\n";

return;

}

}while

(1);

}

intmain()

{

Get_str();

Analyse_output();

system("pause");

return0;

}

六.测试数据:

1.运行成功:

2.运行失败:

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

当前位置:首页 > 高等教育 > 农学

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

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