实验三语义分析报告-_第1页
实验三语义分析报告-_第2页
实验三语义分析报告-_第3页
实验三语义分析报告-_第4页
实验三语义分析报告-_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、编译原理实验报告实验名称:分析调试语义分析程序实验类型:验证型指导教师:专业班级:姓 名:学 号: 实验地点:实验成绩: 日期: 2016 年 6 月 3 日 实验三 分析调试语义分析程序一、实验目的通过分析调试TEST语言的语义分析和中间代码生成程序,加深对语法制导翻译思想的理解,掌握将语法分析所识别的语法范畴变换为中间代码的语义翻译方法。2、 实验知识1.语法制导基本思想语法制导就是对文法中的每个产生式都附加一个语义动作或语义子程序,且在语法分析过程中,每当需要使用一个产生式进行推导或归约时,语法分析程序除执行相应的语法分析动作外,还要执行相应的语义动作或调用相应的语义子程序。基本思想是,

2、根据翻译的需要设置文法符号的属性,以描述语法结构的语义。例如,一个变量的属性有类型,层次,存储地址等。表达式的属性有类型,值等。属性值的计算和产生式相联系。随着语法分析的进行,执行属性值的计算,完成语义分析和翻译的任务。2. 翻译方案设计1)设计原理:在实验二的基础上为文法符号引进一组属性及相应求值规则和动作,得到属性翻译文法,并引进一个符号表(包括变量名,变量数据是否有效,变量地址,变量的具体数据,数据类型等),在进行语法分析的同时,结合符号表完成语义分析与检测,同时根据属性翻译文法的属性及相关动作得到中间代码(抽象机式汇编指令),最后通过模拟的抽象机运行出结果。2)设计方法:(为动作标志,

3、为继承属性,为综合属性)结合课本语法制导相关内容对文法增加属性和动作如下:以下列出有修改的属性翻译文法: <declaration_stat>vartablep,datap,codep int IDnname-defn,t;其中动作符号的含义如下 name-defn,t:插入符号表; <if_stat>if (<expr>)BRFlabel1<statement>BRlabel2 SETlabellabel1| if (<expr>) BRFlabel1<statement >BRlabel2 SETlabellabel1

4、else < statement > SETlabellabel2其中动作符号的含义如下 BRFlabel1 :输出 BRF label1; BRlabel2:输出 BR label2; SETlabellabel1:设置标号label1; SETlabellabel2:设置标号label2;<while_stat>whileSETlabellabel1(<expression>) BRFlabel2 <statement >BRlabel1 SETlabellabel2其中动作符号的含义如下SETlabellabel1:设置标号label1;B

5、RFlabel2 :输出 BRF label2;BRlabel1:输出 BR label1;SETlabellabel2:设置标号label2;<for_stat>for (<expression>POP;SETlabellabel1< expression >BRFlabel2BRlabel3;SETlabellabel4 < expression >POPBRlabel1) SETlabellabel3 < statement >BRlabel4SETlabellabel2其中动作符号的含义如下SETlabellabel1:设置标

6、号label1; BRFlabel2 :输出 BRF label2; BRlabel3:输出 BR label3;SETlabellabel4:设置标号label4;BRlabel1:输出 BR label1;SETlabellabel3:设置标号label3;BRlabel4:输出 BR label4;SETlabellabel2:设置标号label2; <write_stat>write <expression>OUT;其中动作符号的含义如下 OUT:输出 OUT <read_stat>read IDn LOOKnd INSTOdPOP;其中动作符号的含

7、义如下LOOKnd:查符号表n,给出变量地址d; 没有,变量没定义;IN:输出IN;STOd:输出指令代码STO d;POP:将栈顶元素出栈<expression>IDnLOOKndASSIGN=<bool_expr>STOdPOP |<bool_expr>其中动作符号的含义如下LOOKnd:查符号表n,给出变量地址d; 没有,变量没定义;ASSIGN:记住当前文件位置;STOd:输出指令代码STO d; <bool_expr><additive_expr>|< additive_expr >><additiv

8、e_expr>GT|< additive_expr ><<additive_expr>LES|< additive_expr >>=<additive_expr >GE|< additive_expr ><=< additive_expr >LE|< additive_expr >=< additive_expr >EQ|< additive_expr >!=< additive_expr >NOTEQ其中动作符号的含义如下GT:次栈顶与栈顶作大于比较

9、;LES:次栈顶与栈顶作小于比较;GE:次栈顶与栈顶作大于等于比较;LE:次栈顶与栈顶作小于等于比较;EQ:次栈顶与栈顶作等于比较;NOTEQ:次栈顶与栈顶作不等于比较;B+<term>BADD | -<term>BSUB | <additive_A>+<term><additive_A>ADD | -<term><additive_A>SUB | 其中动作符号的含义如下ADD:操作数相加;SUB:操作数相减;C*<factor>CMULT | /<factor>CDIV | <t

10、erm_A>*<factor><term_A>MULT | /<factor><term_A>DIV | 其中动作符号的含义如下MULT:操作数相乘;DIV:操作数相除; < factor >(< expression >)| IDnLOOKndLOADd |NUMiLOADIi其中动作符号的含义如下LOOKnd:查符号表n,给出变量地址d; 没有,变量没定义;LOADd:将地址d的变量入栈;LOADIi:将常量i入栈;3)设计结果:1) <program><declaration_list>

11、<statement_list>2)<declaration_list><declaration_stat> <declaration_list>| 3) <declaration_stat>vartablep,datap,codep int IDnname-defn,t;4) <statement_list><statement><statement_list>| 5) <statement> <if_stat>|<while_stat>|<for_sta

12、t>|<read_stat> |<write_stat>|< compound_stat > |<expression_stat>6) <if_stat>if (<expr>)BRFlabel1<statement>BRlabel2 SETlabellabel1| if (<expr>) BRFlabel1<statement >BRlabel2 SETlabellabel1else < statement > SETlabellabel27) <while_st

13、at>whileSETlabellabel1(<expression>)BRFlabel2 <statement >BRlabel1 SETlabellabel28) <for_stat>for (<expression>SETlabellabel1< expression >BRFlabel2BRlabel3;SETlabellabel4 < expression >BRlabel1) SETlabellabel3 < statement >BRlabel29) <write_stat>wr

14、ite <expression>OUT;10) <read_stat>read IDn LOOKnd INSTOdPOP;11)<compound_stat><statement_list>12)<expression_stat>< expression >POP;|;13) <expression>IDnLOOKndASSIGN=<bool_expr>STOdPOP |<bool_expr>14) <bool_expr><additive_expr><bo

15、ol_A>15) <bool_A>><additive_expr>GT|<<additive_expr>LES|>=<additive_expr >GE|<=< additive_expr >LE|=< additive_expr >EQ|!=< additive_expr >NOTEQ | 16) < additive_expr><term><additive_A>17) <additive_A>+<term><a

16、dditive_A>ADD | -<term><additive_A>SUB | 18) < term ><factor><term_A>19) <term_A>*<factor><term_A>MULT | /<factor><term_A>DIV | 20) < factor >(< expression >)| IDnLOOKndLOADd |NUMiLOADIi三、实验过程首先,理解书上的代码和观看相关的知识的PPT,深入理解属性反应文法

17、的作用,据此在我之前实验写好的语法分析基础上进行修改,写出语义分析代码。在语义分析里增加“不可引用未赋初值变量”的规则,在init()、showVarTable()、checkInitValue()中增加了相关操作。然后,结合栈式抽象机及其汇编指令相关命令的操作含义,模拟写出TEST语言的抽象机模型用以运行文法生成的中间代码。最后,写出执行中间代码的虚拟机程序。最后,编写TEST语言程序进行代码实例测试,调试观察运行过程及结果,并调试修改程序BUG。代码完成后,测试、完善。/定义符号表结构,添加未赋初值记录structchar name8;int address;int notInit;/未赋

18、初值vartablemaxvartablep;/改符号表最多容纳maxvartablep个记录/在插入符号表动作name-defn, t的程序中给notInit赋值为0,vartablevartablep.notInit =0;/在该函数给中判断notInit的值是否为0和查询表中是否有变量名,若查询表中有该变量名,且notInit为0时,将该变量的notInit赋值为1,表示已经判断已经赋值void init(char *name)/在该函数中首先判定变量是否声明,再判定notInit的值是否为0,若变量是声明了且notInit为0时,则判定变量未赋初值。void checkInitValu

19、e(char *name)4、 实验结果1) 测试数据及结果(初始程序)2) 修改后的测试数据:(给sum和product赋初值)运行结果如下3) 中间代码如下: 五、讨论与分析1、通过实验对课程知识点的理解实验后知识梳理与总结:通过TEST属性文法的翻译设计,了解了语法制导的基本过程及方法,明白了属性文法的基本推导与构造原理,了解了不同属性之间的传递关系,动作的执行流程,也了解了栈式抽象机及其汇编指令的执行原理,了解了TEST语言抽象机的原理。语法制导:语法制导就是对文法中的每个产生式都附加一个语义动作或语义子程序,且在语法分析过程中,每当需要使用一个产生式进行推导或归约时,语法分析程序除执

20、行相应的语法分析动作外,还要执行相应的语义动作或调用相应的语义子程序。每个语义子程序都指明了相应产生式中各个符号的具体含义,并规定了使用该产生式进行分析时所应采取的语义动作(如传送或处理信息、查填符号表、计算值、产生中间代码等等)。这种分析模式既把语法分析与语义处理分开,又令其平行地进行,从而在同一遍扫描中同时完成语法分析和语义处理两项工作。语法制导的属性翻译:以语法分析为基础,伴随语法分析的各步骤,执行相应的语义动作;具体方法如下: 1将文法符号所代表的语言成分的意思,用属于该文法符号的属性表示; 2用语义规则(语义规则的执行就是语义动作)规定产生式所代表的语言成分之间的关系(即属性之间的关

21、系),即用语义规则实现属性计算。 3.语义动作(语义规则的执行): 在语法分析的适当时刻(如推导或归约)执行附在对应产生式上的语义规则,以实现对语言结构语义的处理,如计算、查填符号表、生成中间代码、发布出错信息等。2、 回答实验指导书的实验思考提出的问题。(1)语义及代码生成程序中的符号表管理方案存在什么问题?提出改进方案。答:按照原来书上的代码,符号表用的是数组栈,空间上容易造成浪费或溢出,可以使用map数组。但是我没有实现使用map数组。此外,原来的代码还没有检查是否赋初值,对引用了未赋初值的变量也检测不出来,为此我在符号表结构中增加了一个int类型的变量notInit来标记变量是否赋初值

22、。(2)给出<declaration_stat>产生式所添加的动作含义。答:<declaration_stat>vartablep,datap,codep int IDnname-defn,t;其中动作符号的含义如下:name-defn,t:插入符号表;(3)给出<factor>产生式中所添加的动作含义。答: < factor >(< expression >)| IDnLOOKndLOADd |NUMiLOADIi其中动作符号的含义如下LOOKnd:查符号表n,给出变量地址d; 没有,变量没定义;LOADd:将地址d的变量入栈;LO

23、ADIi:将常量i入栈;(4)在抽象机模拟程序中是如何统计指令总数的?画出流程图并做说明答:由于抽象机使用的是书上后面的代码进行修改的,使用的用while循环来执行每条指令,用i来统计指令总数,将每一条指令与code进行比较,若两者相同则执行相应的操作。执行操作后i的次数加一,从而统计出指令总数。流程图如下:开始i<codecount结束codei=LOAD| LOADIi+codei中内容入栈栈顶指针+1codei=STOi+栈顶内容存入data中codei=POP栈顶指针-1codei=ADD|SUB|MULT|DIV次栈顶与栈顶出栈并相加|相减|相乘|相除栈顶指针-1codei=B

24、Ri+i=codeicodei=BRFi+i=codei栈顶=0codei=EQ|NOTEQ|GT|LES|GE|LE|AND|OR次栈顶作=|!=|>|<|>=|<=|&&|栈顶的结果代替栈顶下面的元素栈顶指针-1codei=NOT将栈顶的逻辑值相反codei=IN输入数据放入栈顶栈顶指针+1codei=OUT栈顶出栈,输出结果栈顶指针-1codei=STOP(5)如果要检查变量在参与运算时是否有值,应当如何处理?给出详细的解决方案答:在符号表结构中增加了一个int类型的变量notInit来标记变量是否赋初值,当变量声明的时候给标记赋值为0,当表达式为

25、其赋初值时(如for_stat()和read_stat()),就将其变为1,在checkInitValue(char *name)函数中检测用到的变量对应的属性,如果notInit是0则报错,变量未赋值。6、 附录:关键代码(给出适当注释,可读性高)TESTparse:/定义符号表结构structchar name8;int address;int notInit;/未赋初值vartablemaxvartablep;/改符号表最多容纳maxvartablep个记录/插入符号表动作name-defn, t的程序如下:void name_def(char *name) int i,es=0;if

26、(vartablep >= maxvartablep)printf("符号表溢出n");exit(0);for(i=vartablep-1;i=0;i-)/查符号表 if (strcmp(,name)=0)deal_Error("变量重复定义",wordLine);break;strcpy(,name);vartablevartablep.address=datap;vartablevartablep.notInit =0;datap+;/分配一个单元,数据区指针加1varta

27、blep+;/查询符号表返回地址void lookup(char *name,int *paddress)int i;for(i=0;i<vartablep;i+)if (strcmp(,name)=0)*paddress=vartablei.address;exit(0);deal_Error("变量未声明!", wordLine);/<declaration_stat>vartablep,datap,codep int IDnname-defn,t;void declaration_stat()if (strcmp(&quo

28、t;int", wordType) = 0)fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;if (strcmp("ID", wordType) = 0)fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;name_def(wordValue);if (strcmp("", wordType) = 0)fscanf(fp, "

29、%s %s %d", wordType, wordValue, &wordLine);wordAll+;else deal_Error("声明语句缺少;", wordLine - 1);else deal_Error("声明语句ID错误", wordLine);else deal_Error("声明语句缺少int", wordLine);/*if (<expression>)BRFlabel1 <statement > BRlabel2 SETlabellabel1 else < sta

30、tement > SETlabellabel2*/void if_stat()int es = 0, label1, label2;if (strcmp("if", wordType) = 0)fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;if (strcmp("(", wordType) = 0)/读到if表达式的左括号fscanf(fp, "%s %s %d", wordType, wordValue, &w

31、ordLine);wordAll+;expression();if (strcmp(")", wordType) = 0)/读到if表达式的右括号label1 = labelp+;/用label1记住条件为假时要转向的标号fprintf(fout, " BRF LABEL%dn", label1);/输出假转移指令fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;statement();label2 = labelp+;/用label2记住要转向的标

32、号fprintf(fout, " BR LABEL%dn", label2);/输出无条件转移指令fprintf(fout, "LABEL%d:n", label1);/设置label1记住的标号if (strcmp("else", wordType) = 0)/读到if语句中的else部分fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;statement();else deal_Error("缺少)", w

33、ordLine);else deal_Error("if语句缺少(", wordLine);else deal_Error("if语句错误", wordLine);fprintf(fout, "LABEL%d:n", label2);/设置label2记住的标号/<for_stat>:= for(<expr>,<expr>,<expr>)<statement>/*<for_stat>:=for (<expression>SETlabellabel1&l

34、t; expression >BRFlabel2BRlabel3;SETlabellabel4 < expression >BRlabel1) SETlabellabel3 <语句 >BRlabel4SETlabellabel2 */void for_stat()int label1,label2,label3,label4; if (strcmp("for", wordType) = 0)fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;

35、if (strcmp("(", wordType) = 0)/读入for语句左括号fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;expression();/for语句表达式1 判断fprintf(fout, " POPn");if (strcmp("", wordType) = 0)/读入for语句的第一个条件表达式后面的 ""label1 = labelp+;fprintf(fout, "LAB

36、EL%d:n", label1);/设置label1标号fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;expression();/for语句条件表达式 2label2 = labelp+;fprintf(fout, " BRF LABEL%dn", label2);/输出假条件转移指令label3 = labelp+;fprintf(fout, " BR LABEL%dn", label3);/输出无条件转移指令if (strcmp(&

37、quot;", wordType) = 0)/读入for语句的第 二 个条件表达式后面的 ""label4 = labelp+;fprintf(fout, "LABEL%d:n", label4);/设置label4标号fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;expression();/for语句条件表达式 3fprintf(fout, " POPn");/fprintf(fout, " BR LAB

38、EL%dn", label1);/输出无条件转移指令if (strcmp(")", wordType) = 0)/for语句读入右括号fprintf(fout, "LABEL%d:n", label3);/设置label3标号fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;statement();fprintf(fout, " BR LABEL%dn", label4);/输出无条件转移指令fprintf(fout,

39、"LABEL%d:n", label2);/设置label2标号else deal_Error("for语句缺少)", wordLine);else deal_Error("for语句缺少;", wordLine);else deal_Error("for语句缺少;", wordLine);else deal_Error("for语句缺少(", wordLine);else deal_Error("for语句错误", wordLine);/< factor >(&

40、lt; expression >)| IDnLOOKndLOADd |NUMiLOADIivoid factor()if (strcmp("(", wordType) = 0)fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine);wordAll+;expression();if (strcmp(")", wordType) = 0)fscanf(fp, "%s %s %d", wordType, wordValue, &wordLine)

41、;wordAll+;else deal_Error("factor缺少)", wordLine);else if (strcmp("ID", wordType) = 0 | strcmp("NUM", wordType) = 0)int address;lookup(wordValue, &address);/查符号表,获取变量地址checkInitValue(wordValue);fprintf(fout, " LOAD %dn", address);fscanf(fp, "%s %s %d", wordType, wordValue, &a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论