北邮编译原理语义分析文档和程序.docx
- 文档编号:9090867
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:15
- 大小:74.95KB
北邮编译原理语义分析文档和程序.docx
《北邮编译原理语义分析文档和程序.docx》由会员分享,可在线阅读,更多相关《北邮编译原理语义分析文档和程序.docx(15页珍藏版)》请在冰豆网上搜索。
北邮编译原理语义分析文档和程序
实验报告
班级:
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.运行失败:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 邮编 原理 语义 分析 文档 程序
![提示](https://static.bdocx.com/images/bang_tan.gif)