logo资料库

IF-ELSE条件语句的翻译程序设计(LL(1)法、输出三地址表示).doc

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
学 号: 0120810340605 课 程 设 计 IF-ELSE 条件语句的翻译程 题 目 序设计(LL(1)法、输出三 地址表示) 学 院 计算机科学与技术学院 专 业 计算机科学与技术 班 级 姓 名 指导教师 0806 周雪 郭羽成 2010 年 1 月 6 日
课程设计任务书 学生姓名: 周 雪 专业班级: 计算机 0806 班 指导教师: 郭 羽 成 工作单位:计算机科学与技术学院 题目: IF-ELSE 条件语句的翻译程序设计(LL(1)法、输出三地址表 示) 初始条件: 理论:学完编译课程,掌握一种计算机高级语言的使用。 实践:计算机实验室提供计算机及软件环境。如果自己有计算机可以在其上进 行设计。 要求完成的主要任务: (包括课程设计工作量及其技术要求,以及说明书撰写等具体 要求) (1) 写出符合给定的语法分析方法的文法及属性文法。 (2) 完成题目要求的中间代码三地址表示的描述。 (3) 写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。 (4) 编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。 (5) 设计报告格式按附件要求书写。课程设计报告书正文的内容应包括: 1 系统描述(问题域描述); 2 文法及属性文法的描述; 3 语法分析方法描述及语法分析表设计; 4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计; 5 编译系统的概要设计; 6 详细的算法描述(流程图或伪代码); 7 软件的测试方法和测试结果; 8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等); 9 参考文献(按公开发表的规范书写)。 时间安排: 设计安排一周:周 1、周 2:完成系统分析及设计。 周 3、周 4:完成程序调试及测试。 周 5:撰写课程设计报告。 设计验收安排:设计周的星期五第 1 节课开始到实验室进行上机验收。 设计报告书收取时间:设计周的次周星期一上午 10 点。 指导教师签名: 2010 年 11 月 23 日 系主任(或责任教师)签名: 2010 年 11 月 23 日
1 问题描述 要求用 LL(1)自顶向下分析方法及三地址中间代码,对 IF-THEN-ELSE 条件语句完成 编译各阶段过程,包括词法、语法、语义等分析。 2 问题分析及编译系统的概要设计 编译过程一般分为六个阶段的过程,可以由六个模块完成,它们称为词法分析程 序、语法分析程序、语义分析程序、中间代码生成程序、代码优化程序、目标代码生成 程序,此外,一个完整编译程序还必须包括“表格管理程序”和“出错处理程序”。 这次实验涉及到词法分析、语法分析、语义分析及表格管理和出错管理。其中, 词法分析至少要能识别关键字“if”、“then”和“else”,标识符(即自定义变量),数 字,和运算符等等;语法分析要分析程序结构的合法性,即是否为文法的句子;语义分 析要能够语法制导翻译出中间代码(三地址)并将其输出;表格管理是指符号表;出错 处理是指在语法分析时,所有非文法句子的错误类型处理. 3 文法及属性文法的定义 3.1 文法: 文法是用于描述语言的语法结构的形式规则(即语法规则)。这些规则必须是准确 的、易于理解的以及有相当强的描述能力。由这种规则所产生的程序语言应有利于句子 分析和翻译,而且,最好能通过这些规则自动产生有效的语法分析程序. IF-ELSE 条件语句的文法如下所示: 0.A->EB 1.B->+EB|-EB|ε 2.E->FT 3.T->*FT|/FT|ε 4.F->i|(E) 或者能够更简洁一点: 0.S->if A THEN B ELSE C 1.A->m rop n 2.B->x=m arop n
3.C->x=n arop m 4.rop->=|<|> 5.arop->+|-|*|/ 3.2 属性文法: 属性文法是在上下文无关文法的基础上,为每个文法符号(终结符或者非终结符) 配备若干相关的“值”(与文法符号相关的属性)。 在一个属性文法中,对应于每个产生式 A→a 都有一套与之相关联的语义规则, 每规则的形式为:b:=f(c1,c2,…,ck)其中 f 是一个函数,而且或者①b 是 A 的一个 综合属性并且 c1,c2,…,ck 是产生式右边文法符号的属性或者②非终结符既可有综合 属性也可有继属性,文法开始符号的所有继承属性作为属性计算前的初始值。 属性文法为: 0.S->if A THEN B ELSE C { S.chain:=merge(A.chain,B.chain, C.chain)} 1.A->m rop n { A.true:=nextstat; A.false=nextstat+1; backpatch(A.chain,nextstat); emit(“if p” rop “q goto —”) emit(“goto —”) ; } 2.B->x=m arop n { backpatch(B.chain,nextstat); emit(“ x:= m” arop “n”); emit(“goto —”); } 3.C->x=n arop m { backpatch(C.chain,nextstat); emit(“ x:= n” arop “m”); emit(“goto —”); } 4.rop -> = { emit(“ = ”); } 5. rop -> <{ emit(“ < ”); } 6. rop -> >{ emit(“ > ”); } 7. arop -> +{ emit(“ + ”); } 8. arop-> - { emit(“ - ”); } 9.arop-> *{ emit(“ * ”); } 10.arop-> /{ emit(“ / ”); }
4 词法分析 首 先 应 该 创 建 一 个 枚 举 类 型 的 变 量 来 存 放 一 些 关 键 字 , enum keyword{$right_paren,$left_paren,$mul,$div,$add,$sub,$fenhao,$equal,$IF,$THEN,$EL SE,$greater,$less,$id,$num,$end}; 再创建一个结构体,用来存放词法分析的结果,共有两个域,一个关键字域,表 明他是什么类型,以及它自身的内容。 这个词法分析程序比较简单,因为本身的程序就局限在 if-else 语句,所以保留 字的类型我就只写了 if、then 和 else 三个;碰到数字开头的除了关键字就是标识 符;碰到数字开头的就是数字;碰到界限符和操作符(因为引入的类型也很少), 所以也很容易区别。 在词法分析结束之后,就应该把分析的结果输出来。输出的格式是【(单词,类 型编号) 类型名】 源程序文件 字符的分离 单词的判断 查找相应的表 单词的类型的判断 调 用 不 同 类 型 的 单 词 处 理函数进行单词的处理 产生类型码 将中间单词和其类型码存入数组
处理完毕 词法分析程序如下: bool lexcal() { int k=0; char buf[16]; char ch; while(1) { ins>>ch; if(ins.fail()) break; while(ch==' ') ins>>ch;} { if(ch=='I') { { } { ins>>buf; if(strcmp(buf,"F")==0) tokentable[total_len++].type=$IF; } else if(ch=='T') ins>>buf; if(strcmp(buf,"HEN")==0) tokentable[total_len++].type=$THEN; else if(ch=='E') ins>>buf; if(strcmp(buf,"LSE")==0) tokentable[total_len++].type=$ELSE; } else if(ch=='>') { } else if(ch=='<') { } tokentable[total_len++].type=$greater; tokentable[total_len++].type=$less;
else if(ch=='=') { { tokentable[total_len++].type=$equal; } else if((ch>='A'&& ch<='Z' )|| (ch>='a' && ch<='z')) { tokentable[total_len].type=$id; tokentable[total_len++].ch=ch; } else if(ch>='0' && ch<='9') tokentable[total_len].type=$num; tokentable[total_len++].ch =ch; } else switch (ch) { case '+' : tokentable[total_len].type=$add; tokentable[total_len++].ch =ch; break; case '-' : case '/' : tokentable[total_len].type=$sub; tokentable[total_len++].ch =ch; break; tokentable[total_len].type=$div; tokentable[total_len++].ch =ch; break; case '*' : tokentable[total_len].type=$mul; tokentable[total_len++].ch =ch; break; case ';' : case '(' : case ')' : tokentable[total_len].type=$fenhao; tokentable[total_len++].ch =ch; break; tokentable[total_len].type=$left_paren; tokentable[total_len++].ch =ch; break; tokentable[total_len].type=$right_paren; tokentable[total_len++].ch =ch; break;
default:cout<<"!"<'Z'){ if(X==a){ sp--; front++;
分享到:
收藏