编译原理课程设计——算术表达式、for、while语句转换为四元式
写出如下语句的四元式序列

写出如下语句的四元式序列1.引言1.1 概述在编程语言中,为了对程序进行分析和执行,我们需要将程序转换成计算机能够理解和执行的形式。
而四元式序列就是一种常用的表示方式之一。
四元式序列是由四个元素组成的元组,分别是操作符、操作数1、操作数2和结果。
它可以将复杂的程序语句拆分成更简单的操作,方便计算机进行处理。
在撰写四元式序列时,我们需要根据具体的语句来确定操作符、操作数1、操作数2和结果。
以以下语句为例:pythonx = y + z我们可以将这个语句转换成如下的四元式序列:1. (+, y, z, t1)2. (=, t1, "", x)在这个序列中,第一行的操作符是加号,操作数1和操作数2分别是变量y和z,结果是临时变量t1。
第二行的操作符是赋值号,操作数1是临时变量t1,操作数2为空,结果是变量x。
这样,通过四元式序列的表示,我们可以更清晰地描述程序的执行过程,方便后续的语义分析和执行。
总的来说,四元式序列在程序分析和执行中具有重要的作用,它可以将复杂的程序语句转换成更简单的操作,方便计算机进行处理。
在实际的编程中,我们可以根据具体的语句来编写相应的四元式序列,以达到更高效、更准确地执行程序的目的。
1.2文章结构文章1.2 文章结构文章结构是指文章整体的组织形式,包括各个部分之间的关系和排列顺序。
一个合理的文章结构能够使读者更好地理解文章的主题和内容,提高文章的可读性和逻辑性。
在本文中,我们将主要围绕三个部分展开,分别是引言、正文和结论。
引言部分作为文章的开端,其主要功能是引起读者的兴趣,明确文章的主题和目的。
在引言部分中,我们将对本文的概述进行介绍,简要说明文章的主要内容和结构,并阐述文章撰写的目的。
通过清晰明了地阐述引言部分的内容,能够让读者对后续的内容有一个整体的认识和预期,为接下来的阅读打下基础。
正文部分是文章的核心,也是作者表达观点和论证思路的主要部分。
在正文部分中,我们将围绕两个要点展开,分别是要点一和要点二。
以语句的四元式中间代码及其语法制导生成为例分析语法制导生成方法。

郑州轻工业学院课程设计说明书题目:WHILE语句的四元式结构及其语法制导生成过程姓名:院(系):计算机与通信工程学院专业班级:计算机科学与技术10-1学号:指导教师:马吉明成绩:时间:2013年6月17 日至2013 年 6 月21日郑州轻工业学院课程设计任务书题目WHILE语句的四元式结构及其语法制导生成过程专业、班级计算机科学与技术10-1学号姓名主要内容以语句的四元式中间代码及其语法制导生成为例分析语法制导生成方法。
给出FOR或WHILE语句的四元式结构及其语法制导生成过程。
基本要求通过设计、编制、调试一个WHILE循环语句的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。
用语法制导完成语义分析,并将形成的中间代码以四元式的形式输出。
主要参考资料等:《程序设计语言编译原理》陈火旺编著国防工业出版社《编译原理》吕映芝张素琴蒋维杜编著清华大学出版社完成期限:2013 年6 月21日指导教师签名:课程负责人签名:年月日目录1 设计内容及要求 (4)2系统描述 (4)3 文法及属性文法的描述 (4)3.1 文法的描述 (4)3.2 属性文法的描述 (4)4 语法分析方法描述及语法分析表设计 (5)4.1 语法分析表设计 (5)4.1.1 文法的DFA (5)4.1.2 LR(0)分析表 (7)4.2 LR(0)分析方法描述说明 (7)5 中间代码形式的描述及中间代码序列的结构设计 (8)6 编译系统的概要设计 (9)7 心的体会 (11)1 设计内容及要求设计一个语法制导翻译器,将WHILE语句翻译成四元式。
要求:先确定一个定义WHILE语句的文法,为其设计一个语法分析程序,为每条产生式配备一个语义子程序,按照一遍扫描的语法制导翻译方法,实现翻译程序。
对用户输入的任意一个正确的WHILE 语句,程序将其转换成四元式输出(可按一定格式输出到指定文件中)。
(完整word版)WHILE循环语句的翻译程序设计(递归下降法,输出四元式)

学号:0121210340314课内实践报告课程名称编译原理设计题目WHILE循环语句的翻译程序设计(递归下降法,输出四元式)学院计算机科学与技术专业班级计算机1203班姓名闵丹枫指导教师林泓2014年12月8日课程设计任务书学生姓名:闵丹枫专业班级: 计算机1203班指导教师:林泓工作单位:计算机科学与技术学院题目:WHILE循环语句的翻译程序设计(递归下降法、输出四元式)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用.实践:计算机实验室提供计算机及软件环境。
如果自己有计算机可以在其上进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。
(2)完成题目要求的中间代码四元式的描述.(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序.(5)设计报告格式按附件要求书写。
课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。
时间安排:设计安排一周:周1、周2:完成系统分析及设计.周3、周4:完成程序调试及测试。
周5:撰写课程设计报告.设计验收安排:设计周的星期五第1节课开始到实验室进行上机验收。
设计报告书收取时间:设计周的次周星期一上午10点。
指导教师签名: 2014年9月1日系主任(或责任教师)签名:2014年月日WHILE循环语句的翻译程序设计(递归下降法、输出四元式)一.系统描述1.1问题描述设计一个WHILE〈布尔表达式〉DO〈赋值语句〉循环语句的词法﹑语法及语义分析程序,语法分析选择递归下降法,采用用语法制导翻译输出中间代码四元式。
《编译原理》课程设计说明书_DO_WHILE循环语句的翻译程序设计(LR方法、输出三地址表示)

DO-WHILE循环语句的翻译程序设计(LR方法、输出三地址表示)1.系统描述1.1设计目的通过设计、编制、调试一个DO-WHILE循环语句的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。
1.2设计内容及步骤对循环语句:DO〈赋值语句〉WHILE 〈表达式〉按给定的题目写出符合自身语法分析方法要求的文法和属性文法描述。
(1)按给定的题目给出语法分析方法的思想及分析表设计。
(2)按给定的题目给出中间代码序列的结构设计。
(3)完成相应的词法分析、语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
2文法的描述本程序所用的文法如下:G[S]:(1)S->do{E;}while(B) {if B.true goto B.true else goto B.false;}(2)B->I1 rop I2 {B.type=bool;B.val=I1.val rop I2.val;}(3)E->I1=I2 op I3 {I1.val=I2.val op I3.val;}(4)I->id {I.val=id.val;}注意:rop is < or >,op is +,-,*,/, id is any number or identifier由上可知,非终结符B表示布尔表达式,E表示赋值表达式3.语法分析方法描述及语法分析表设计3.1语法分析方法描述本实验采用LR分析方法对DO-WHILE语句进行语法分析。
LR分析法是一种能根据当前分析栈中的符号串(通常以状态表示)和向右顺序查看输入串的K个(K>=0)符号就能惟一的确定分析器的动作是移进还是归约和用哪个产生式归约,因而也就能惟一的确定句柄。
LR分析法的归约过程是规范推导的逆过程,所以LR分析过程是一种规范过程。
一个LR分析器由3个部分组成:总控程序,也可以称为驱动程序。
编译原理课后习题答案

第一章1.典型的编译程序在逻辑功能上由哪几部分组成答:编译程序主要由以下几个部分组成:词法分析、语法分析、语义分析、中间代码生成、中间代码优化、目标代码生成、错误处理、表格管理。
2. 实现编译程序的主要方法有哪些答:主要有:转换法、移植法、自展法、自动生成法。
3. 将用户使用高级语言编写的程序翻译为可直接执行的机器语言程序有哪几种主要的方式答:编译法、解释法。
4. 编译方式和解释方式的根本区别是什么答:编译方式:是将源程序经编译得到可执行文件后,就可脱离源程序和编译程序单独执行,所以编译方式的效率高,执行速度快;解释方式:在执行时,必须源程序和解释程序同时参与才能运行,其不产生可执行程序文件,效率低,执行速度慢。
、第二章1.乔姆斯基文法体系中将文法分为哪几类文法的分类同程序设计语言的设计与实现关系如何答:1)0型文法、1型文法、2型文法、3型文法。
2)2. 写一个文法,使其语言是偶整数的集合,每个偶整数不以0为前导。
答:Z SME | B{S1|2|3|4|5|6|7|8|9M | D | MDD0|SB2|4|6|8E0|B3. 设文法G为:N D|NDD 0|1|2|3|4|5|6|7|8|9请给出句子123、301和75431的最右推导和最左推导。
答:N ND N3ND3N23D23123%N ND NDD DDD1DD12D123N ND N1ND1N01D01301N ND NDD DDD3DD30D301N ND N1ND1N31ND31N431ND431N5431D543175431N ND NDD NDDD NDDDD DDDDD7DDDD75DDD754DD7543D75431 4. 证明文法S iSeS|iS| i是二义性文法。
答:对于句型iiSeS存在两个不同的最左推导:S iSeS iiSesS iS iiSeS所以该文法是二义性文法。
…5. 给出描述下面语言的上下文无关文法。
编译原理试题及答案(期末复习版)

<编译原理>历年试题及答案一.(每项选择2分,共20分)选择题1.将编译程序分成若干个“遍”是为了_b__。
a.提高程序的执行效率b.使程序的结构更加清晰c.利用有限的机器内存并提高机器的执行效率d.利用有限的机器内存但降低了机器的执行效率2.构造编译程序应掌握__d__。
a.源程序b.目标语言c.编译方法d.以上三项都是3.变量应当c_。
a.持有左值b.持有右值c.既持有左值又持有右值d.既不持有左值也不持有右值4.编译程序绝大多数时间花在_d___上。
a.出错处理b.词法分析c.目标代码生成d.管理表格5.词法分析器的输出结果是_c___。
a.单词的种别编码b.单词在符号表中的位置c.单词的种别编码和自身值d.单词自身值6.正规式MI和M2等价是指__c__。
a.MI和M2的状态数相等b.Ml和M2的有向弧条数相等。
C.M1和M2所识别的语言集相等 d.Ml和M2状态数和有向弧条数相等7.中间代码生成时所依据的是—c。
a.语法规则b.词法规则c.语义规则d.等价变换规则8.后缀式ab+cd+/可用表达式__b_来表示。
a.a+b/c+d b.(a+b)/(c+d)c.a+b/(c+d)d.a+b+c/d9.程序所需的数据空间在程序运行前就可确定,称为____c__管理技术。
a.动态存储b.栈式存储c.静态存储d.堆式存储10.堆式动态分配申请和释放存储空间遵守___d_____原则。
a.先请先放b.先请后放c.后请先放d.任意二(每小题10分,共80分)简答题1.画出编译程序的总体结构图,简述各部分的主要功能。
2.已知文法G[E]:E→ET+|T T→TF*|F F→F^|a试证:FF^^*是文法的句型,指出该句型的短语、简单短语和句柄.3.为正规式(a|b)*a(a|b)构造一个确定的有限自动机。
4.设文法G(S):S→(L)|a S|aL→L,S|S(1)消除左递归和回溯;(2)计算每个非终结符的FIRST和FOLLOW;(3)构造预测分析表。
《编译原理》课程设计说明书_DO_WHILE循环语句的翻译程序设计(LR方法、输出三地址表示)

DO-WHILE循环语句的翻译程序设计(LR方法、输出三地址表示)1.系统描述1.1设计目的通过设计、编制、调试一个DO-WHILE循环语句的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。
1.2设计内容及步骤对循环语句:DO〈赋值语句〉WHILE 〈表达式〉按给定的题目写出符合自身语法分析方法要求的文法和属性文法描述。
(1)按给定的题目给出语法分析方法的思想及分析表设计。
(2)按给定的题目给出中间代码序列的结构设计。
(3)完成相应的词法分析、语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
2文法的描述本程序所用的文法如下:G[S]:(1)S->do{E;}while(B) {if B.true goto B.true else goto B.false;}(2)B->I1 rop I2 {B.type=bool;B.val=I1.val rop I2.val;}(3)E->I1=I2 op I3 {I1.val=I2.val op I3.val;}(4)I->id {I.val=id.val;}注意:rop is < or >,op is +,-,*,/, id is any number or identifier由上可知,非终结符B表示布尔表达式,E表示赋值表达式3.语法分析方法描述及语法分析表设计3.1语法分析方法描述本实验采用LR分析方法对DO-WHILE语句进行语法分析。
LR分析法是一种能根据当前分析栈中的符号串(通常以状态表示)和向右顺序查看输入串的K个(K>=0)符号就能惟一的确定分析器的动作是移进还是归约和用哪个产生式归约,因而也就能惟一的确定句柄。
LR分析法的归约过程是规范推导的逆过程,所以LR分析过程是一种规范过程。
一个LR分析器由3个部分组成:总控程序,也可以称为驱动程序。
编译原理题库——简答题

G(S):A→2∣4∣6∣8∣D
B→A∣0
C→CB∣A
D→1∣3∣5∣7∣9
S→CD∣D
8解:
(1)最左推导为:
E => E+T => T+T => F+T => i+T => i+T*F => i+F*F => i+i*F => i+i*i
E => T => T*F => F*F => i*F => i*(E) => i*(E+ T) => i*(T+ T)
即有(L(A)∪L(B))*=L((A*B*))* ③
111 (j,_,_,108)
112 (j,_,_,100)
113
5答:证明:
由文法G[S]:S→aSb|Sb|b,对句子aabbbb对应的两棵语法树为:
因此,文法G[S]为二义文法。
编译原理B
1.什么是句子? 什么是语言 ?
2. 写一文法,使其语言是偶正整数的集合,要求:
(1)允许0打头;
(2) 不允许0打头。
P:
S->PD|D
P->NP|N
D->0|2|4|6|8
N->0|1|2|3|4|5|6|7|8|9
(2)G[S]=({S,P,R,D,N,Q },{0,1,2,…,9},P,S)
P:
S->PD|P0|D
P->NR|N
R->QR|Q
D->2|4|6|8
N->1|2|3|4|5|6|7|8|9
Q->0|1|2|3|4|5|6|7|8|9
编译原理试题及答案(期末复习版)

<编译原理>历年试题及答案一.(每项选择2分,共20分)选择题1.将编译程序分成若干个“遍”是为了_b__。
a.提高程序的执行效率b.使程序的结构更加清晰c.利用有限的机器内存并提高机器的执行效率d.利用有限的机器内存但降低了机器的执行效率2.构造编译程序应掌握__d__。
a.源程序b.目标语言c.编译方法d.以上三项都是3.变量应当c_。
a.持有左值b.持有右值c.既持有左值又持有右值d.既不持有左值也不持有右值4.编译程序绝大多数时间花在_d___上。
a.出错处理b.词法分析c.目标代码生成d.管理表格5.词法分析器的输出结果是_c___。
a.单词的种别编码b.单词在符号表中的位置c.单词的种别编码和自身值d.单词自身值6.正规式MI和M2等价是指__c__。
a.MI和M2的状态数相等b.Ml和M2的有向弧条数相等。
C.M1和M2所识别的语言集相等 d.Ml和M2状态数和有向弧条数相等7.中间代码生成时所依据的是—c。
a.语法规则b.词法规则c.语义规则d.等价变换规则8.后缀式ab+cd+/可用表达式__b_来表示。
a.a+b/c+d b.(a+b)/(c+d)c.a+b/(c+d)d.a+b+c/d9.程序所需的数据空间在程序运行前就可确定,称为____c__管理技术。
a.动态存储b.栈式存储c.静态存储d.堆式存储10.堆式动态分配申请和释放存储空间遵守___d_____原则。
a.先请先放b.先请后放c.后请先放d.任意二(每小题10分,共80分)简答题1.画出编译程序的总体结构图,简述各部分的主要功能。
2.已知文法G[E]:E→ET+|T T→TF*|F F→F^|a试证:FF^^*是文法的句型,指出该句型的短语、简单短语和句柄.3.为正规式(a|b)*a(a|b)构造一个确定的有限自动机。
4.设文法G(S):S→(L)|a S|aL→L,S|S(1)消除左递归和回溯;(2)计算每个非终结符的FIRST和FOLLOW;(3)构造预测分析表。
编译原理E课内实践报告:WHILE循环语句的翻译程序设计与实现,递归下降法,输出四元式

文法及属性文法的描述 ............................................................................................... 2 2.1 2.2 文法描述 ............................................................................................................. 2 属性文法描述 ..................................................................................................... 3
2.2 属性文法描述
形式上讲,属性文法是一个三元组 :A=(G,V,F), 其中: ➢ G:是一个上下文无关文法; ➢ V:有穷的属性集,每个属性与文法的一个终结符或非终结符相连 ,这些属性代表与 文法符号相关信息; ➢ F:关于属性的属性断言或一组属性的计算规则(称为语义规则) 。 断言或语义规则 与一个产生式相联,只引用该产生式左端或右端的终结符或非终结符相联的属性。 属性文法中的属性分成两类:继承属性和综合属性。 ➢ 综合属性(synthesized attribute) :如果 b 是 A 的属性,c1 , c2 , …, ck 是产生式右 部文法符号的属性或 A 的其它属性,则称 b 是文法符号 A 的综合属性。 ➢ 继承属性(inherited attribute):如果 b 是产生式右部某个文法符号 X 的属性,并且 c1,c2,…,ck 是 A 或产生式右部文法符号的属性, 则称 b 是文法符号 X 的继承属性。
3
c语言循环实现计算机的四则运算

一、概述计算机是现代社会不可或缺的工具,而计算机的运算能力是其重要的功能之一。
C语言作为一种通用的高级语言,具有广泛应用的特点,在计算机编程中也扮演着重要的角色。
本文将介绍如何利用C语言的循环结构,实现计算机的四则运算功能,以及对应的代码实现。
二、C语言循环结构C语言提供了多种循环结构,包括for循环、while循环和do...while循环。
这些循环结构可以帮助程序实现重复执行某段代码的功能,非常适合用于实现四则运算中的重复计算过程。
1. for循环for循环是C语言中最常用的一种循环结构,其语法形式为:```cfor (初始化表达式; 判断表达式; 更新表达式){循环体;}```其中初始化表达式用于初始化循环变量,判断表达式用于判断循环是否继续执行,更新表达式用于更新循环变量的值。
利用for循环结构,可以方便地实现对变量进行增减的操作,从而实现四则运算中的加减乘除功能。
2. while循环while循环是C语言中另一种常见的循环结构,其语法形式为:```cwhile (判断表达式){循环体;}```while循环会在每次执行循环体之前判断条件表达式的真假,只有在条件为真时才会执行循环体,因此适用于实现需要满足特定条件才能进行计算的四则运算。
3. do...while循环do...while循环是C语言中的另一种循环结构,其语法形式为:```cdo{循环体;} while (判断表达式);```do...while循环先执行一次循环体,然后再判断是否继续执行循环体,因此适用于需要至少执行一次计算过程的四则运算。
三、C语言实现四则运算利用上述介绍的C语言循环结构,可以方便地实现计算机的四则运算。
下面将分别介绍如何利用循环结构实现加法、减法、乘法和除法运算,并给出相应的代码实现。
1. 加法运算加法运算是最基本的四则运算之一,其实现可以利用C语言的循环结构来实现。
下面是利用for循环实现加法运算的示例代码:```c#include <stdio.h>int m本人n(){int a = 3;int b = 5;int sum = 0;for (int i = 0; i < b; i++){sum++;}printf("d + d = d\n", a, b, sum);return 0;}```在这段代码中,利用for循环结构对变量sum进行了累加操作,从而实现了加法运算。
算术表达式转四元式

算术表达式转四元式在计算机科学中,算术表达式是一种用来描述数学运算的语法结构。
它由数字、运算符和括号等符号组成,通过运算符的优先级和结合性规则计算出一个数值结果。
而四元式是一种用来表示程序执行过程的中间代码结构,它将算术表达式中的计算过程转化为一系列简洁的操作指令,方便计算机进行程序执行。
算术表达式的转换过程可以分为两个步骤:首先将中缀表达式转换为后缀表达式,然后再根据后缀表达式构造出四元式序列。
中缀表达式转后缀表达式中缀表达式是指运算符位于两个操作数之间的表达式。
例如,3 + 4 * 5就是一个中缀表达式。
但是,为了方便计算机进行计算,我们需要将中缀表达式转换为后缀表达式。
后缀表达式是指运算符位于两个操作数之后的表达式,也称为逆波兰表达式。
例如,3 4 5 * +就是一个后缀表达式。
为了将中缀表达式转换为后缀表达式,我们可以使用栈来实现。
具体步骤如下:1. 遍历中缀表达式中的每个元素,如果是数字,直接输出;如果是左括号,将其入栈;如果是右括号,将栈顶元素弹出并输出,直到遇到左括号。
2. 如果是运算符,判断其与栈顶运算符的优先级,如果栈顶运算符优先级高于或等于当前运算符,则将栈顶运算符弹出并输出,然后重复上述步骤,直到遇到优先级低于当前运算符的运算符,将其压入栈中。
3. 如果遍历完整个中缀表达式,但栈中仍有运算符,将其依次弹出并输出。
例如,将中缀表达式3 + 4 * 5转换为后缀表达式的过程如下:1. 遇到数字3,直接输出;2. 遇到运算符+,将其入栈;3. 遇到数字4,直接输出;4. 遇到运算符*,将其入栈;5. 遇到数字5,直接输出;6. 遍历完整个中缀表达式,将栈中剩余的运算符依次弹出并输出,得到后缀表达式3 4 5 * +。
后缀表达式转四元式将后缀表达式转换为四元式序列的过程也可以使用栈来实现。
具体步骤如下:1. 遍历后缀表达式中的每个元素,如果是操作数,将其压入栈中;2. 如果是运算符,从栈中弹出两个操作数,并生成一个新的四元式,将其存储在序列中,并将结果入栈;3. 如果遍历完整个后缀表达式,栈中仅剩一个元素,即为计算结果。
DO-WHILE循环语句的翻译程序设计(简单优先法、输出四元式)

(二)DO-WHILE循环语句的翻译程序设计(简单优先法、输出四元式)一、1.简单优先法的基本思想根据优先关系的定义,将简单优先文法中各文法符号之间的这种关系用一个矩阵表示,称作简单优先矩阵。
PDA读入一个单词后,比较栈顶符号和该单词的优先级,若栈顶符号优先级低于该单词,继续读入;若栈顶符号优先级高于或等于读入符号,则找句柄进行归约,找不到句柄就继续读入。
直到最后栈内只剩下开始符号,输入串读到“#”为止。
此时识别正确。
可分点描述如下:(1)、对句型中相邻的文法符号规定优先关系,以寻找句型中的句柄;(2)、规定句柄内各相邻符号之间具有相同的优先级;(3)、规定句柄两端符号优先级要比位于句柄之外而又和句柄相邻的符号的优先级高,以先归约句柄;(4)、对于文法中所有符号,只要它们可能在某个句型中相邻,就要为它们规定相应的优先关系,若某两个符号永远不可能相邻,则它们之间就无关系.2.简单优先矩阵用于表示文法符号之间的简单优先关系的矩阵。
3.简单优先法的优缺点优点:技术简单,当做简单优先矩阵是要求较短。
缺点:适用范围小,分析表尺寸太大。
二、源代码实现:#include<iostream>#define MAX 35#include<list>#include<string>#include<fstream>using namespace std;#define TABLE_LEN 8#define STR_LEN 256int zhlen;char sTable[TABLE_LEN+1] = {"+-*/()i#"};//顺序索引int ShipTable[TABLE_LEN][TABLE_LEN] = //优先表{{ 1, 1,-1,-1,-1, 1,-1, 1},{ 1, 1,-1,-1,-1, 1,-1, 1},{ 1, 1, 1, 1,-1, 1,-1, 1},{ 1, 1, 1, 1,-1, 1,-1, 1},{-1,-1,-1,-1,-1, 0,-1,-2},{ 1, 1, 1, 1,-2, 1,-2, 1},{ 1, 1, 1, 1,-2, 1,-2, 1},{-1,-1,-1,-1,-1,-2,-1, 0}};char X,a;char VN[11]={'K','L','P','S','E','G','T','R','F','Q','\0'};char VT[15]={'i','=','<','>','+','-','*','/','(',')','d','w',';','#','\0'};charp[18][6]={"dLwS\0","SP\0",";SP\0","\0","iQE\0","TG\0","+TG\0","-TG\0","\0","FR\0","*FR\0","/FR\0","\0","(E)\0","i\0","=\0","<\0",">\0"};char stack[MAX];char queue[MAX];int sp,front;intM[10][14]={ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1},{1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,2,-1},{4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},{5,-1,-1,-1,-1,-1,-1,-1,5,-1,-1,-1,-1,-1},{-1,-1,-1,-1,6,7,-1,-1,-1,-1,-1,8,8, 8},{9,-1,-1,-1,-1,-1,-1,-1,9,-1,-1,-1,-1,-1},{-1,-1,-1,-1,12,12,10,11,-1,-1,-1,12,12,12},{14,-1,-1,-1,-1,-1,-1,-1,13,-1,-1,-1,-1,-1},{-1,15,16,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},};int f=0; int count=0;int c=0;char arr_i[MAX];char var[MAX]; //表格管理int td[MAX]; int t=0;int opd=-1;int opr=-1;int id=0;int d=0;char arr[MAX][4];//存放待输出的四元式//char keyword[2][7]={"do\0","while\0"};bool IsCharInStr(char c,char s[]){for(int i=0;s[i]!='\0';i++){if(s[i]==c)return true;}return false;}int GetIndex(char s[],char c){for(int i=0;s[i]!='\0';i++){if(c==s[i])return i;}return -1;}//string GetSubString(char s[],int from,int to){string st;for(int i=from;i<to;i++){st+=s[i];}return st;}/*******************************************翻译赋值表达式********************************************/void translatefuzhi(char *sInput){//栈结构的初始化char Stack[STR_LEN]={0};int index = 0;int top = 1;Stack[0] = '#';list<char> rPolish;list<string> Num;int begin=0;while(sInput[begin]!='='){if(IsCharInStr(sInput[begin],sTable)){cout<<"Equal expression is illegal!"<<endl;return ;}begin++;}Num.push_back(GetSubString(sInput,0,begin));int now = begin+1;int before = begin;rPolish.push_back('i');while(sInput[now]!='\0'){if(IsCharInStr(sInput[now],sTable)){char temp[3]={0};if(now-before>1){temp[0] = 'i';temp[1] = sInput[now];Num.push_back(GetSubString(sInput,before+1,now));}else{temp[0] = sInput[now];}int i=0;while(temp[i]!=0){int left = GetIndex(sTable,Stack[index]);int right = GetIndex(sTable,temp[i]);switch(ShipTable[left][right]){case -1://移入Stack[top++] = temp[i];index = top-1;i++;break;case 0://脱括号if(Stack[index]=='('){Stack[top++] = ')';Stack[index] = 'E';top = index+1;index--;}else//规约{if(top!=2){return;}rPolish.push_back('=');list<char>::iterator iter;list<string>::iterator siter=Num.begin();string fuzhi[256];int d=0,m;for(iter=rPolish.begin();iter!=rPolish.end();iter++){if(*iter=='i'){fuzhi[d++]=*siter;siter++;}else{fuzhi[d++]=*iter;}}m=d;string op1,op2;int flag,xiabiao=0;for(d=0;d<m;d++)cout<<"("<<fuzhi[d]<<","<<op1<<","<<op2<<","<<"T"<<xiabiao<<")"<<endl;fuzhi[d] = "T";fuzhi[d]+=(xiabiao+'0');xiabiao++;}//cout<<fuzhi[d];}return;}i++;break;case 1://归约if(Stack[index]=='i'){rPolish.push_back('i');Stack[index] = 'E';index--;}else{rPolish.push_back(Stack[index]);Stack[index-1] = 'E';top = index;index-=2;}break;default:return;}}before=now;}now++;}}int len(char str[]){int i=0;while(str[i]!='\0')i++;return i;}int index(char ch,char str[]){int i=0;while(str[i]!='\0'){if(ch!=str[i])i++;else break;}if(str[i]=='\0')return -1;return i;}void err(int n){if(n==1)cout<<"字符不匹配"<<endl;else if(n==2)cout<<"字符没有出现在产生式中"<<endl;else if(n==3)cout<<"没有找到合适的¨选产式"<<endl;else cout<<"该句子是文法语言的句子"<<endl;}void print(){cout<<"(";if(count<10)cout<<'0';cout<<count<<")";int i;for(i=0;i<=sp;i++)cout<<stack[i];for(;i<=20;i++)cout<<" ";for(i=0;i<front;i++)cout<<" ";for(;queue[i]!='#';i++)cout<<queue[i];cout<<queue[i];for(;i<=20;i++)cout<<" ";}void semantic(){if(VT[opr]=='='){arr[d][0]='=';arr[d][1]=arr_i[opd];arr[d][2]=id;arr[d][3] ='--';id++;}elseif(opr==-2){arr[d][0]='=';arr[d][1]=id-1;arr[d][2]=arr_i[opd];arr[d][3]='--';} else {arr[d][0]=VT[opr];arr[d][1]=arr_i[opd];arr[d][2]=id;if(VT[opr]!='<'&&VT[opr]!='>')arr[d][3]=id-1;else arr[d][3]=id+1;id++;} d++;}void syntax(){//语法分析int n;count++;print();X=stack[sp];a=queue[front];if(X=='#'&&a=='#')f=4;if(X<'A'||X>'Z'){if(X==a){sp--;front++;if(a!='i'){if(a!='d'&&a!='w'&&a!=';'&&a!='#'){opr=index(a,VT);semantic();}else if(a==';'||a=='w'||a=='#'){opr=-2;semantic();}cout<<'\t'<<'\''<<a<<"'匹配"<<endl;}else {opd=c;cout<<'\t'<<'\''<<arr_i[c++]<<"'匹配"<<endl;}}else f=1;}else {int tx=index(X,VN);int ta=index(a,VT);n=M[tx][ta];td[t++]=M[tx][ta];if(ta==-1){f=2;cout<<a<<endl;}else if(n==-1)f=3;else {sp--;cout<<'\t'<<X<<"->";if(len(p[n])!=0){for(inti=len(p[n])-1;i>=0;i--){stack[++sp]=p[n][i];cout<<p[n][len(p[n])-1-i];} cout<<endl;}else cout<<"空串"<<endl;}}if(f==0)syntax();else {td[t]='-1';err(f);}}void lexical(){ //词法分析int i,j,d;char ch;j=d=0;for(i=0;var[i]!='#';i++){ch=var[i];if(ch=='d'&&var[i+1]=='o'){cout<<"do"<<'\t'<<"keword"<<endl;queue[j++]='d' ;i+=1;}else if(ch=='w'){ch=var[i+1];if(ch=='h'){ch=var[i+2];if(ch=='i'){ch=var[i+3];if(ch=='l'){ch=var[i+4];if(ch=='e'){ch=var[i+5];}}}}cout<<"while"<<'\t'<<"keyword"<<endl;queue[j++]='w';i+=4;}else if(index(ch,VT)<=0){if(ch!='{'&&ch!='}'&&ch!='('&&ch!=')'){cout<<ch<<'\t'<<"variable:i["<<d++< <"]"<<endl;arr_i[d-1]=ch;queue[j++]='i';}else cout<<ch<<'\t'<<"bound"<<endl;}elseif(index(ch,VT)>0){cout<<ch<<'\t'<<"operator"<<endl;queue[j++]=ch;} }queue[j]='#';for(i=0;queue[i]!='#';i++)cout<<queue[i];cout<<endl;}int main(){int i=0,j=0;int len,length;char temp;char S='K';sp=front=0;stack[0]='#';sp++;stack[1]='K';cout<<" ****************************"<<endl;cout<<" * DO-WHILE循环语句 *"<<endl;cout<<" * (简单优先法输出四元式) *"<<endl;cout<<" ****************************"<<endl;ifstream table;table.open("dowhile.txt");if(!table){cout<<"error!";}table.seekg(0,ios::end);length = table.tellg();table.seekg(0,ios::beg);while(length!=table.tellg()){table.read((char*)&temp,1);var[i]=temp;i++;if(var[i]==' ')i--;if(var[i]=='#')break;}table.close();len=i;var[i]='\0';cout<<"词法分析"<<endl;lexical();char fuzhi[20];int flag1,fuzhilen;int s=0; for(i=0;i<len;i++){if(var[i]==';'){flag1=i;}}fuzhilen=flag1-2;for(i=3;i<flag1;i++){fuzhi[s++]=var[i];}fuzhi[s]='#';char shuru;char zh[100];int kaishi=0;zh[0]='d';for(kaishi=1;kaishi<s+1;kaishi++){zh[kaishi]=fuzhi[kaishi-1];}zh[kaishi++]=';';zh[kaishi++]='W';for(i=flag1+8;i<len;i++){if(var[i]=='}')break;else{zh[kaishi++]=var[i];}}zh[kaishi++]='#';zhlen=kaishi;cout<<"输出四元式"<<endl;cout<<"do"<<endl;translatefuzhi(fuzhi);cout<<"("<<var[flag1+9]<<","<<var[flag1+8]<<","<<var[flag1+10]<<","<<"T2"< <")"<<endl;cout<<"if T2=true goto T0"<<endl;return 0;}三、测试结果:词法分析部分:输出四元式:四、课程小结:这次编译原理课程设计的题目是用简单优先分析法进行DO-WHILE循环语句的语法分析,并输出四元式.设计的特点是利用定义每个终极符和非终极符之间优先关系,来进行符号的移进与规约,如果栈顶符号优先级低于该单词,继续读入;若栈顶符号优先级高于或等于读入符号,则找句柄进行归约,找不到句柄就继续读入。
编译原理课程设计-翻译成四元式

编译原理课程设计一、课程设计题目:第(20)题:写一程序,演示对给定下标变量赋值语句文法,且已知建立内情向量,对给定的下标变量赋值语句翻译成四元式。
二、编程环境:在Turboc下编程运行,可随意输入数组维数,对输入的给定下标变量赋值语句翻译成四元式。
三、设计原理:一个含数组元素的赋值语句的文法模式可为下所示:A->V:=E V->i[elist]|i elist->elist,E|E E->E+E|(E)|V 即一个赋值语句A是一个V(指变量)后跟赋值号:=和一个算术表达式E。
为了计算数组元素的VARPART,需要把关于变量V的文法改写成:V->elist]|i elist->elist,E|i[E 把数组名i和最左的下标式写在一起的目的是使在整个下标串elist的翻译过程中随时都能知道数组名i的符号表入口,从而随时能够了解登记在符号表中的有关数i的全部信息。
为了计算VARPART的四元式序列,需要知道数组名的符号表入口,下标式的个数,将VARPART的中间结果单元名字在符号表中的位置等。
还要根据含有数组元素的赋值句的翻译规则进行翻译。
四、设计过程:数组元素a[i1,i2,…,in]地址D的计算公式为: D=CONSPART+VARPARTCONSPART=a-c ,其中c是常数(d2d3…dn+d3…dn+…+dn+1).由题目已知建立了内情向量表,但是为了方便起见还是要输入数组的维数以及是几乘几的数组。
为了计算常数c编了一个专门的函数Conspart(int a[],DIM);其核心是:for(j=1;j<DIM;j++)c=c*a[j]+1;为了将四元式的计算VARPART 的过程演示出来,知道其值为(i1d2d3…dn +i2d3d4…dn+…+in-1dn+in),即可通过一个循环来计算VARPART的值,如下VARPART:=VARPART*dk+1+ik+1因此也可通过循环来演示计算四元式VARPART的过程。
编译原理课程设计_算术表达式、for、while语句转换为四元式

计算机与信息学院《操作系统与编译原理联合课程设计报告》专题:编译原理部分学生姓名:学号:专业班级:指导教师:2014 年 7 月一、设计目标设计一个语法制导翻译器,将算术表达式、for语句、while语句翻译成四元式。
要求先确定一个定义算术表达式、for语句、while语句的文法,为其设计一个语法分析程序,为每条产生式配备一个语义子程序,按照一遍扫描的语法制导翻译方法,实现翻译程序。
对用户输入的任意一个正确的表达式,程序将其转换成四元式输出。
二、设计思路开发平台:Visual C++ MFC解决这个问题的方案分为以下几个步骤:1.将算数表达式、for语句、while语句转换为四元式的第一步为对读入的表达式进行处理,即删除不必要的空格、回车、换行等,保证之后的步骤能够顺利进行。
2.分析算术表达式、for语句、while语句的文法。
3.通过词法分析判断语句中的每个字符的类型,如:数字、字母、符号等。
4.建立每种文法的LR(0)分析表,通过每个文法的LR(0)分析表对相应的表达式进行语法分析。
5.在语法分析正确的情况下,通过语法分析的中间过程的符号栈输出四元式,四元式的形式为:(op arg1 arg2 result)。
(一)算术表达式转换为四元式将算术表达式转换为四元式首先考虑了括号的问题,对于不同的算术表达式第一步进行词法分析,即确定各种符号的位置。
而括号中的式子是优先级最高的,应该最先进行处理。
我使用了一个数组记录算术表达式中括号的位置,并且定义了first_cc和first_jj函数对括号的乘除法和加减法分别进行处理。
后将括号的式子以四元式的形式输出。
通过以上转换,已将原算术表达式中的括号中的容使用大写字母’A’、’B’……等代替(其中定义声明了change函数,用来将括号部分替换为大写字母)。
新的式子中,只含有加减乘除以及赋值这四种运算,后根据优先级的不同,逐步生成四元式。
其算法流程图如右图所示。
编译原理课程设计报告-简单文法的编译器的设计与实现

提供全套毕业论文,各专业都有课程设计报告设计题目:简单文法的编译器的设计与实现班级:计算机1206组长学号:20123966组长姓名:指导教师:设计时间:2014年12月摘要编译原理是计算机科学与技术专业一门重要的专业课, 它具有很强的理论性与实践性,目的是系统地向学生介绍编译系统的结构、工作原理以及编译程序各组成部分的设计原理和实现技术,在计算机本科教学中占有十分重要的地位。
计算机语言之所以能由单一的机器语言发展到现今的数千种高级语言,就是因为有了编译技术。
编译技术是计算机科学中发展得最迅速、最成熟的一个分支,它集中体现了计算机发展的成果与精华。
本课设是词法分析、语法分析、语义分析的综合,外加上扩展任务中间代码的优化和目标代码的生成,主要是锻炼学生的逻辑思维能力,进一步理解编译原理的方法和步骤。
关键词:编译原理,前端,目标代码,后端目录摘要 (3)1. 概述 (6)2. 课程设计任务及要求 (8)2.1 设计任务 (8)2.2 设计要求 (9)3. 算法及数据结构 (10)3.1算法的总体思想 (10)3.2 词法分析器模块 (11)3.2.1 功能 (11)3.2.2 数据结构 (11)3.2.3 算法 (12)3.3 语法分析器模块 (13)3.3.1功能 (13)3.3.2 数据结构 (13)3.3.3算法 (14)3.4 中间代码产生器模块 (24)3.4.1 功能 (24)3.4.2 数据结构 (24)3.4.3 算法 (25)3.5 优化器模块 (27)3.5.1 功能 (27)3.5.2 数据结构 (27)3.5.3 算法 (28)3.6 目标代码生成器模块 (30)3.6.1功能 (30)3.6.2 数据结构 (30)3.6.3 算法 (31)4. 程序设计与实现 (32)4.1 程序流程图 (32)4.2 程序说明 (33)4.3 实验结果 (35)5. 结论 (42)6. 参考文献 (43)7. 收获、体会和建议 (44)1 概述在计算机上执行一个高级语言程序一般要分为两步;第一步,用一个编译程序把高级语言翻译成机器语言程序;第二步,运行所得的机器语言程序求得计算结果。
WHILE循环语句的翻译程序设计(简单优先法、输出四元式)

WHILE循环语句的翻译程序设计(简单优先法、输出四元式)1 需求说明或问题描述1.1 问题描述对C++中while循环语句的理解及分析,通过编译中的词法分析、语法分析、语义分析及中间代码生成等编译过程,用简单优先分析法分析并翻译while语句。
1.2 需求说明1 写出符合给定的语法分析方法的文法及属性文法2 完成题目要求的中间代码四元式的描述3 写出给定的语法分析方法的思想,完成语法分析及语义分析程序设计4 设计若干用例,上机通过测试2 文法及语法设计2.1文法及属性文法:文法G=(V N ,V T ,P ,S)其中V N={S , B, E, C, A, B, P, T} V T={w, (, ), { ,}, i, ;}P={S -> w(B){E}E -> CC -> CAC -> AA -> iPAA -> i;P -> +|-|*|/B -> iTiB-> iT -> >|<|>=|<=|==}2.2 语法分析方法描述及语法分析表设计2.2.1 语法分析方法描述:简单优先分析法是按照文法符号(终极符和非终极符)的优先关系确定句柄的。
基本思想可设计如下,首先根据已知优先文法构造相应优先关系矩阵,并将文法的产生式保存,设置符号栈S,步骤如下:(1)将输入符号串a1a2…a n#依次逐个存入符号栈S中,直到遇到栈顶符号a i的优先性>下一个待输入符号a j为止。
(2)栈顶当前符号a i为句柄尾,由此向左在栈中找句柄的头符号a k,即找到a k-1<a k为止。
(3)由句柄a k...a i在文法的产生式中查找右部为a k…a i的产生式,若找到则用相应左部代替句柄,若找不到则为出错,这时可断定输入串不是该文法的句子。
(4)重复上述(1)、(2)、(3)步骤直到规约完输入符号串,栈中只剩文法的开始符号为止。
WHILE循环语句的翻译程序设计(LR方法、输出四元式)资料

目录课程设计任务书 (1)1系统描述 (2)2文法及属性文法描述 (2)2.1文法的描述 (2)2.2属性文法的描述 (2)3语法分析方法描述及语法分析表设计 (2)3.1语法分析表设计 (2)3.1.1文法的DFA (3)3.1.2LR(0)分析表 (4)3.1.3LR(0)分析方法描述说明 (4)4中间代码形式的描述及中间代码序列的结构设计 (4)5编译系统的概要设计 (5)5.1词法分析 (5)5.2语法分析 (6)5.3语法制导翻译 (7)6详细的算法描述 (8)7 软件的测试方法和测试结果 (14)8小结与体会 (18)9参考文献 (18)本科生课程设计成绩评定表 (20)课程设计任务书学生姓名:王世创专业班级:计算机0909班指导教师:高曙工作单位:计算机科学与技术学院题目: WHILE循环语句的翻译程序设计(LR方法、输出四元式)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。
实践:计算机实验室提供计算机及软件环境。
如果自己有计算机可以在其上进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。
(2)完成题目要求的中间代码四元式的描述。
(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。
(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
(5)设计报告格式按附件要求书写。
课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。
时间安排:设计安排一周:周1、周2:完成系统分析及设计。
编译原理-语法分析生成四元式

学号1406410107 成绩编译原理上机报告名称:语法分析生成四元式学院:信息与控制工程学院专业:计算机科学与技术班级:计算机1401班*名:***2016年11月11日一、上机目的(a)根据算符优先分析算法,编写一个分析对象的语法分析程序。
读者可根据自己的能力选择以下三项(由易到难)之一作为分析算法中的输入:Ⅰ:通过构造算符优先关系表,设计编制并调试一个算法优先分析程序Ⅱ:输入FIRSTVT,LASTVT集合,由程序自动生成该文法的算符优先关系矩阵。
Ⅲ:输入已知文法,由程序自动生成该文法的算符优先关系矩阵。
(b)程序具有通用性,即所编制的语法分析程序能够使用于不同文法以及各种输入单词串,并能判断该文法是否为算符文法和算符优先文法。
(c)有运行实例。
对于输入的一个文法和一个单词串,所编制的语法分析程序应能正确地判断,此单词串是否为该文法的句子,并要求输出分析过程。
二、基本原理和上机步骤1.借用实验二的结果,可将其中的取字符函数几乎原封不动地移植过来,其中的分割和分析单词的方法可借用过来分割现在这个实验的运算符、常量和变量。
2.模块结构:(1)初始化:设立算符优先关系表(或优先函数)、初始化变量空间(包括堆栈、结构体、数组、临时变量等);(2)控制部分:将一个表达式从文件中读出;(3)词法分析:将表达式分割成单词序列;(4)利用算符优先文法进行表达式处理:根据算符优先关系表(或优先函数)对表达式单词序列进行堆栈(或其他)操作,得到并保存四元组,如果遇到错误则显示错误信息;(5)输出四元组。
三、上机结果程序清单:#include<stdio.h>#include<stdlib.h>#define MAX 100void SET_Mul_Div(int i,int m);void SET_Add_Sub(int j,int m);void print();int m=0;int count=0;char tempvar='A';int temp;char string[MAX]; //用于存放表达式int main() {i nt p[MAX];c har ch;i nt c=-1,q=0;p rintf("请输入赋值语句:\n");w hile((ch = getchar())!='\n') {string[m++]=ch;if(ch=='='||ch=='+'||ch=='-'||ch=='*'||ch=='/')count++;else if(ch=='(') {p[++c]=m-1; }else if(ch==')'){q=m-1;SET_Mul_Div(p[c],q); //从左括号处理到又括号SET_Add_Sub(p[c],q);temp=(int)tempvar-1;tempvar=(char)temp;string[p[c]]=string[m-1]=tempvar;c--;temp=(int)tempvar+1;tempvar=(char)temp; }}/********调用生成四元式的函数********/p rint();/*********判断是否成功**********/i f(count==0)printf("Successful!\n");e lseprintf("Wrong!");p rintf("\n");s ystem("pause");}void SET_Mul_Div(int i,int m) //处理乘除运算{for(i++;i<=m-1;i++){i f(string[i]=='*'||string[i]=='/') {printf("(%c %c %c %c)\n",string[i],string[i-1],string[i+1], tempvar);string[i-1]=string[i]=string[i+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp;}}}void SET_Add_Sub(int j,int m) //处理加减运算{j++;for(;j<=m-1;j++){i f(string[j]=='+'||string[j]=='-') {printf("(%c %c %c %c)\n",string[j],string[j-1],string[j+1],tempvar);string[j-1]=string[j]=string[j+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp; }}}/*打印*/void print(){i nt i;f or(i=0;i<=m-1;i++)//处理乘除运算{if(string[i]=='*'||string[i]=='/'){printf("(%c %c %c %c)\n",string[i],string[i-1],string[i+1],tempvar);string[i-1]=string[i]=string[i+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp;}}i nt j;f or(j=0;j<=m-1;j++)//处理加减运算{if(string[j]=='+'||string[j]=='-'){printf("(%c %c %c %c)\n",string[j],string[j-1],string[j+1],tempvar);string[j-1]=string[j]=string[j+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp;}}i nt k;f or(k=0;k<=m-1;k++) //处理赋值运算{if(string[k]=='='){temp=(int)tempvar--;tempvar=(char)temp;printf("(%c %c %c) \n",string[k],string[k+1], string[k-1],tempvar);count--;string[k-1]=tempvar; }}}屏幕截图:四、讨论与分析通过本次实验我完成生成四元式的语法分析程序,掌握的结合语法分析实现翻译方案的思路和方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机与信息学院《操作系统与编译原理联合课程设计报告》专题:编译原理部分学生姓名:学号:专业班级:指导教师:2014 年 7 月一、设计目标设计一个语法制导翻译器,将算术表达式、for语句、while语句翻译成四元式。
要求先确定一个定义算术表达式、for语句、while语句的文法,为其设计一个语法分析程序,为每条产生式配备一个语义子程序,按照一遍扫描的语法制导翻译方法,实现翻译程序。
对用户输入的任意一个正确的表达式,程序将其转换成四元式输出。
二、设计思路开发平台:Visual C++ MFC解决这个问题的方案分为以下几个步骤:1.将算数表达式、for语句、while语句转换为四元式的第一步为对读入的表达式进行处理,即删除不必要的空格、回车、换行等,保证之后的步骤能够顺利进行。
2.分析算术表达式、for语句、while语句的文法。
3.通过词法分析判断语句中的每个字符的类型,如:数字、字母、符号等。
4.建立每种文法的LR(0)分析表,通过每个文法的LR(0)分析表对相应的表达式进行语法分析。
5.在语法分析正确的情况下,通过语法分析的中间过程的符号栈输出四元式,四元式的形式为:(op arg1 arg2 result)。
(一)算术表达式转换为四元式将算术表达式转换为四元式首先考虑了括号的问题,对于不同的算术表达式第一步进行词法分析,即确定各种符号的位置。
而括号中的式子是优先级最高的,应该最先进行处理。
我使用了一个数组记录算术表达式中括号的位置,并且定义了first_cc和first_jj函数对括号内的乘除法和加减法分别进行处理。
后将括号内的式子以四元式的形式输出。
通过以上转换,已将原算术表达式中的括号中的内容使用大写字母’A’、’B’……等代替(其中定义声明了change函数,用来将括号部分替换为大写字母)。
新的式子中,只含有加减乘除以及赋值这四种运算,后根据优先级的不同,逐步生成四元式。
其算法流程图如右图所示。
(二)for语句转换为四元式1.For语句的文法如下:S-> f ( E ; F ; G ){ H ;}S-> f ( E ; X ; Y ){ H ;}E-> id = cF-> id < cG-> id + +X-> id > cY-> id ––H-> id1 = id2 + id3H-> id1 = id2 + cH-> id1 = c+ id2其中c 表示常数const,f表示关键字for, id表示一般标识符。
for循环体内部的表达式一般为算术表达式,而算术表达式转换为四元式的方法在第一部分已给出,此处H只考虑比较简单的情况。
2.for语句的LR(0)分析表如下:3. 基本算法流程:本算法定义声明了两个结构体:一个是Node结构体,其中char型的type中存储当前符号的类型,CString型的sValue中存储的为当前符号,int型的eValue只有在符号类型为数字的情况下才进行存储,存储数字的大小;另一个为stack结构体,这个结构体是实现语法分析中的符号栈和状态栈使用的,并未这两个栈分别定义了各自的pop函数和push函数。
除此之外,本算法中的LR(0)分析表通过二维数组存储。
其中分为action表和goto表。
action表中的状态转换符号,用2-44表示,规约的符号,用101-110表示。
具体的算法流程图如下:(三)while语句转换为四元式1.while语句的文法如下:(1)S->while(B){E}(2)E->AE(3)E->A(4)A->iPA(5)A->i(6)B->iTi(7)B->i其中while、( 、) 、{ 、} 、P、T 、;和i均为终结符,而S、A、B、E这些大写字母均为非终结符。
T表示比较运算符,P表示算术运算符,i表示合法标识符。
2.While语句的LR(0)分析表如下:3.基本算法流程:本算法的基本思想与for语句转换成四元式的思想比较相似,都是对读入的语句进行词法分析,后再通过LR(0)分析表对语句进行语法分析,并同时输出四元式。
与for语句转换成四元式不同的是,while语句转换为四元式在结构体定义等方面做了改进。
首先是LR(0)分析表的存储方式进行了改进,本算法中为LR(0)分析表定义了一个table的结构体,将action和goto两个部分全部存入table的结构体中,是查表的时候更加方便。
除此之外,还定义了obj结构体,此结构体主要是为了存储所要输出的四元式,定义了此结构体之后,程序的调理变得更为清晰了。
本算法中符号栈以及状态栈的部分主要调用了c++中原有的stack结构体,使用其本身定义的pop函数以及push函数,简化的代码。
以下为算法的流程图:(四)输入、输出以及界面设计1.输入:本程序的输入均为语句或表达式,若每次测试程序均输入表达式,则会输入大量式子,浪费时间。
所以本程序采用文件读入的形式,只需要在指定位置输入文件名即可。
2.输出:本程序输出的四元式全部在MFC界面的文本框中显示。
可以复制,方便之后的使用。
3.界面设计:本程序为了方便使用以及界面美观,使用了MFC中的TabControl控件,界面设计如下:图中当前标签为“while语句”,显示的界面为“while语句转换为四元式”。
通过若点击其他标签按钮,界面也会切换到相应的界面。
每个界面都是一个对话框,如下图所示:(1)CompilerDesignDlg.cpp作为主要的文件,去调用其他的对话框。
首先对每一个对话框(IDD_DIALOG1-3)进行设置,样式:下层;边框:无。
如下图所示:(2)后在CompilerDesignDlg.h文件中添加每个对话框的头文件,以及申明每个对话框,代码如下:#include "Dlg1.h"#include "Dlg2.h"#include "Dlg3.h"CDlg1 page1;CDlg2 page2;CDlg3 page3;(3)在初始化函数CCompilerDesignDlg::OnInitDialog()中编写相关代码:m_tabCtrl.InsertItem(0, "算术表达式");m_tabCtrl.InsertItem(1, "for语句");m_tabCtrl.InsertItem(2, "while语句");page1.Create(IDD_DIALOG1, &m_tabCtrl);page2.Create(IDD_DIALOG2, &m_tabCtrl);page3.Create(IDD_DIALOG3, &m_tabCtrl);CRect rc;m_tabCtrl.GetClientRect(&rc);rc.top += 22;rc.bottom -= 3;rc.left += 2;rc.right -= 3;//设置子对话框尺寸并移动到指定位置page1.MoveWindow(&rc);page2.MoveWindow(&rc);page3.MoveWindow(&rc);page1.ShowWindow(true);page2.ShowWindow(false);page3.ShowWindow(false);m_tabCtrl.SetCurSel(0);(4)填写按钮响应函数,即实现点击按钮切换到相应界面的功能,双击Tab控件,创建函数,函数内代码实现如下:void CCompilerDesignDlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) {int CurSel = m_tabCtrl.GetCurSel();switch (CurSel){case 0:page1.ShowWindow(true);page2.ShowWindow(false);page3.ShowWindow(false);break;case 1:page1.ShowWindow(false);page2.ShowWindow(true);page3.ShowWindow(false);break;case 2:page1.ShowWindow(false);page2.ShowWindow(false);page3.ShowWindow(true);break;}*pResult = 0;}三、核心代码(一)算术表达式转化为四元式1.first_cc函数:对括号中的乘除法进行处理。
void CDlg1::first_cc(int i, int m){i++;for (; i <= m - 1; i++)//处理乘除运算{if (str[i] == '*' || str[i] == '/'){CString str00;CString strget;GetDlgItemText(IDC_OUT, strget);CString str01 = str[i];CString str02 = str[i - 1];CString str03 = str[i + 1];CString str04 = JG;str00 = str0 + str01 + str1 + str02 + str1 + str03 + str1 + str04 + str2;SetDlgItemText(IDC_OUT, strget + str00);change(i - 1);str[i - 1] = str[i] = str[i + 1] = JG;sum--;JG = (char)(int)JG++;}}}2.first_jj函数:对括号内的加减法进行处理。
void CDlg1::first_jj(int j, int m){j++;for (; j <= m - 1; j++)//处理加减运算{if (str[j] == '+' || str[j] == '-'){CString str00;CString strget;GetDlgItemText(IDC_OUT, strget);CString str01 = str[j];CString str02 = str[j - 1];CString str03 = str[j + 1];CString str04 = JG;str00 = str0 + str01 + str1 + str02 + str1 + str03 + str1 + str04 + str2;SetDlgItemText(IDC_OUT, strget + str00);change(j - 1);str[j - 1] = str[j] = str[j + 1] = JG;sum--;JG = (char)(int)JG++;}}}3.scan函数:用于从文件中读入表达式,并处理空格、回车、换行等。