实验三语义分析报告Word格式文档下载.docx
- 文档编号:17434633
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:17
- 大小:73.46KB
实验三语义分析报告Word格式文档下载.docx
《实验三语义分析报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《实验三语义分析报告Word格式文档下载.docx(17页珍藏版)》请在冰豆网上搜索。
②<
if_stat>
→if(<
expr>
)@BRF↑label1<
statement>
@BR↑label2@SETlabel↓label1|if(<
)@BRF↑label1<
statement>
@BR↑label2@SETlabel↓label1else<
statement>
@SETlabel↓label2
@BRF↑label1:
输出BRFlabel1;
@BR↑label2:
输出BRlabel2;
@SETlabel↓label1:
设置标号label1;
@SETlabel↓label2:
设置标号label2;
③<
while_stat>
→while@SETlabel↑label1(<
expression>
)@BRF↑label2<
@BR↓label1@SETlabel↓label2
@SETlabel↑label1:
@BRF↑label2:
输出BRFlabel2;
@BR↓label1:
输出BRlabel1;
@SETlabel↓label2:
④<
for_stat>
→for(<
@POP;
@SETlabel↑label1<
expression>
@BRF↑label2@BR↑label3;
@SETlabel↑label4<
@POP@BR↓label1)@SETlabel↓label3<
@BR↓label4@SETlabel↓label2
@SETlabel↓label1:
@BRF↑label2:
@BR↑label3:
输出BRlabel3;
@SETlabel↓label4:
设置标号label4;
@BR↑label1:
@SETlabel↓label3:
设置标号label3;
@BR↑label4:
输出BRlabel4;
⑤<
write_stat>
→write<
@OUT;
@OUT:
输出OUT
⑥<
read_stat>
→readID↑nLOOK↓n↑d@IN@STO↓d@POP;
@LOOK↓n↑d:
查符号表n,给出变量地址d;
没有,变量没定义;
@IN:
输出IN;
@STO↓d:
输出指令代码STOd;
@POP:
将栈顶元素出栈
⑦<
→ID↑n@LOOK↓n↑d@ASSIGN=<
bool_expr>
@STO↓d@POP|<
@ASSIGN:
记住当前文件位置;
⑧<
→<
additive_expr>
|<
additive_expr>
>
<
@GT
@LES
=<
additive_expr>
@GE
@LE
==<
@EQ
!
@NOTEQ
@GT:
次栈顶与栈顶作大于比较;
@LES:
次栈顶与栈顶作小于比较;
@GE:
次栈顶与栈顶作大于等于比较;
@LE:
次栈顶与栈顶作小于等于比较;
@EQ:
次栈顶与栈顶作等于比较;
@NOTEQ:
次栈顶与栈顶作不等于比较;
B→+<
term>
B@ADD|-<
B@SUB|ε
⑨<
additive_A>
→+<
@ADD|-<
@SUB|ε
@ADD:
操作数相加;
@SUB:
操作数相减;
C→*<
factor>
C@MULT|/<
C@DIV|ε
⑩<
term_A>
→*<
@MULT|/<
@DIV|ε
@MULT:
操作数相乘;
@DIV:
操作数相除;
⑪<
factor>
→(<
)|ID↑n@LOOK↓n↑d@LOAD↓d|NUM↑i@LOADI↓i
@LOOK↓n↑d:
@LOAD↓d:
将地址d的变量入栈;
@LOADI↓i:
将常量i入栈;
3)设计结果:
1)<
program>
→{<
declaration_list>
statement_list>
}
2)<
<
|ε
3)<
4)<
5)<
→<
|<
compound_stat>
expression_stat>
6)<
7)<
→while@SETlabellabel1(<
)@BRF↑label2<
8)<
;
@BR↓label1)@SETlabel↓label3<
@BR↓label2
9)<
10)<
11)<
compound_stat>
12)<
|;
13)<
14)<
bool_A>
15)<
→>
@GT|<
@LES|>
@LE|==<
@EQ|!
@NOTEQ|ε
16)<
additive_expr>
17)<
18)<
term>
19)<
20)<
三、实验过程
首先,理解书上的代码和观看相关的知识的PPT,深入理解属性反应文法的作用,据此在我之前实验写好的语法分析基础上进行修改,写出语义分析代码。
在语义分析里增加“不可引用未赋初值变量”的规则,在init()、showVarTable()、checkInitValue()中增加了相关操作。
然后,结合栈式抽象机及其汇编指令相关命令的操作含义,模拟写出TEST语言的抽象机模型用以运行文法生成的中间代码。
最后,写出执行中间代码的虚拟机程序。
最后,编写TEST语言程序进行代码实例测试,调试观察运行过程及结果,并调试修改程序BUG。
代码完成后,测试、完善。
//定义符号表结构,添加未赋初值记录
struct{
charname[8];
intaddress;
intnotInit;
//未赋初值
}vartable[maxvartablep];
//改符号表最多容纳maxvartablep个记录
//在插入符号表动作@name-def↓n,t的程序中给notInit赋值为0,
vartable[vartablep].notInit=0;
//在该函数给中判断notInit的值是否为0和查询表中是否有变量名,若查询表中有该变量名,且notInit为0时,将该变量的notInit赋值为1,表示已经判断已经赋值
voidinit(char*name)
//在该函数中首先判定变量是否声明,再判定notInit的值是否为0,若变量是声明了且notInit为0时,则判定变量未赋初值。
voidcheckInitValue(char*name)
4、实验结果
1)测试数据及结果(初始程序)
2)修改后的测试数据:
(给sum和product赋初值)运行结果如下
3)中间代码如下:
五、讨论与分析
1、通过实验对课程知识点的理解
实验后知识梳理与总结:
通过TEST属性文法的翻译设计,了解了语法制导的基本过程及方法,明白了属性文法的基本推导与构造原理,了解了不同属性之间的传递关系,动作的执行流程,也了解了栈式抽象机及其汇编指令的执行原理,了解了TEST语言抽象机的原理。
语法制导:
每个语义子程序都指明了相应产生式中各个符号的具体含义,并规定了使用该产生式进行分析时所应采取的语义动作(如传送或处理信息、查填符号表、计算值、产生中间代码等等)。
这种分析模式既把语法分析与语义处理分开,又令其平行地进行,从而在同一遍扫描中同时完成语法分析和语义处理两项工作。
语法制导的属性翻译:
以语法分析为基础,伴随语法分析的各步骤,执行相应的语义动作;
具体方法如下:
1.将文法符号所代表的语言成分的意思,用属于该文法符号的属性表示;
2.用语义规则(语义规则的执行就是语义动作)规定产生式所代表的语言成分之间的关系(即属性之间的关系),即用语义规则实现属性计算。
3.语义动作(语义规则的执行):
在语法分析的适当时刻(如推导或归约)执行附在对应产生式上的语义规则,以实现对语言结构语义的处理,如计算、查填符号表、生成中间代码、发布出错信息等。
2、回答实验指导书的实验思考提出的问题。
(1)语义及代码生成程序中的符号表管理方案存在什么问题?
提出改进方案。
答:
按照原来书上的代码,符号表用的是数组栈,空间上容易造成浪费或溢出,可以使用map数组。
但是我没有实现使用map数组。
此外,原来的代码还没有检查是否赋初值,对引用了未赋初值的变量也检测不出来,为此我在符号表结构中增加了一个int类型的变量notInit来标记变量是否赋初值。
(2)给出<
产生式所添加的动作含义。
其中动作符号的含义如下:
@name-def↓n,t:
(3)给出<
产生式中所添加的动作含义。
(4)在抽象机模拟程序中是如何统计指令总数的?
画出流程图并做说明
由于抽象机使用的是书上后面的代码进行修改的,使用的用while循环来执行每条指令,用i来统计指令总数,将每一条指令与code进行比较,若两者相同则执行相应的操作。
执行操作后i的次数加一,从而统计出指令总数。
流程图如下:
(5)如果要检查变量在参与运算时是否有值,应当如何处理?
给出详细的解决方案
在符号表结构中增加了一个int类型的变量notInit来标记变量是否赋初值,当变量声明的时候给标记赋值为0,当表达式为其赋初值时(如for_stat()和read_stat()),就将其变为1,在checkInitValue(char*name)函数中检测用到的变量对应的属性,如果notInit是0则报错,变量未赋值。
6、附录:
关键代码(给出适当注释,可读性高)
7、TESTparse:
//定义符号表结构
//插入符号表动作@name-def↓n,t的程序如下:
voidname_def(char*name)
{
inti,es=0;
if(vartablep>
=maxvartablep)
{
printf("
符号表溢出\n"
);
exit(0);
}
for(i=vartablep-1;
i==0;
i--)//查符号表
{
if(strcmp(vartable[i].name,name)==0)
{
deal_Error("
变量重复定义"
wordLine);
break;
}
strcpy(vartable[vartablep].name,name);
vartable[vartablep].address=datap;
vartable[vartablep].notInit=0;
datap++;
//分配一个单元,数据区指针加1
vartablep++;
//查询符号表返回地址
voidlookup(char*name,int*paddress)
{
inti;
for(i=0;
i<
vartablep;
i++)
*paddress=vartable[i].address;
exit(0);
deal_Error("
变量未声明!
"
wordLine);
//<
voiddeclaration_stat()
if(strcmp("
int"
wordType)==0)
fscanf(fp,"
%s%s%d"
wordType,wordValue,&
wordLine);
wordAll++;
if(strcmp("
ID"
fscanf(fp,"
wordAll++;
name_def(wordValue);
if(strcmp("
{
fscanf(fp,"
wordAll++;
}
elsedeal_Error("
声明语句缺少;
wordLine-1);
elsedeal_Error("
声明语句ID错误"
elsedeal_Error("
声明语句缺少int"
/*
if(<
)@BRF↑label1<
@BR↑label2@SETlabel↓label1
[else<
]@SETlabel↓label2*/
voidif_stat(){
intes=0,label1,label2;
if"
("
wordType)==0)//读到if表达式的左括号
expression();
)"
wordType)==0)//读到if表达式的右括号
label1=labelp++;
//用label1记住条件为假时要转向的标号
fprintf(fout,"
BRFLABEL%d\n"
label1);
//输出假转移指令
statement();
label2=labelp++;
//用label2记住要转向的标号
BRLABEL%d\n"
label2);
//输出无条件转移指令
LABEL%d:
\n"
//设置label1记住的标号
if(strcmp("
else"
wordType)==0)//读到if语句中的else部分
{
fscanf(fp,"
wordAll++;
statement();
}
缺少)"
if语句缺少("
if语句错误"
fprintf(fout,"
//设置label2记住的标号
:
=for(<
<
)<
=for(<
@BR↓label1)
@SETlabel↓label3<
语句>
@BR↓label4@SETlabel↓label2
*/
voidfor_stat()
intlabel1,label2,label3,label4;
for"
wordT
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 语义 分析 报告