编译原理波兰式和四元式

合集下载

编译原理_习题

编译原理_习题

第2章 习题及解答: 习题及解答:
试求下述文法G(Z)所定义的语言: 试求下述文法G(Z)所定义的语言: G(Z)所定义的语言 Z,BG(Z): Z->b|bB ,B->bZ + 【解】 L(G)={ x | Z => x, x∈VT* } 文法所定 义的语言
推导运算法: ⒈ 推导运算法: ∵ Z => b Z => bB => bbZ => bbb Z => bB => bbZ => bbbB => bbbbZ => bbbbb
第2章
习题及解答: 习题及解答:
试构造下述语言L的文法: 试构造下述语言L的文法: L={ ambn |m≥0,n≥1}; 【解】 • 分析: 1. 此语言仅有一种句型: 分析:
a mb n ; 2. ambn 中包含有两个短语:am 和 bn

S(句子 句子),A( 设:S(句子),A(短语1), B(短语2) • 于是: ※产生式形式: 于是: 产生式形式: 【解1】 G1(S): S -> AB |ε A -> Aa |ε B -> Bb | b 或 G2(S): S -> AB |ε A -> aA |ε B -> bB | b
G(S): S -> a A S b ① | B d ② A -> c S ③ | ε ④ B -> b B ⑤ | d ⑥ 三对选择集合两两不相交! ∵ 三对选择集合两两不相交! ∴ G(S)是 LL(1)文法! G(S)是 LL(1)文法! 文法 LL(1)分析表 分析表: (2) LL(1)分析表: a S b c d #
b
②-
a 无用 状态

编译原理复习整理(重点含答案)

编译原理复习整理(重点含答案)

1、给出下面语言的相应文法。

L1={a n b n c i|n≥1,i≥0}从n,i的不同取值来把L1分成两部分:前半部分是anbn:A→aAb|ab后半部分是ci:B→Bc|ε所以整个文法G1[S]可以写为:G1(S):S→AB;A→aAb|ab;B→cB|ε3、构造一个DFA,它接受 ={a,b}上所有包含ab的字符串。

(要求:先将正规式转化为NFA,再将NFA确定化,最小化)4、对下面的文法G:E →TE ’ E ’→+E|ε T →FT ’ T ’→T|εF →PF ’ F ’ →*F ’|ε P →(E)|a|b|∧(1)证明这个文法是LL(1)的。

(2)构造它的预测分析表。

(1)FIRST(E)={(,a,b,^}FIRST(E')={+,ε}FIRST(T)={(,a,b,^}FIRST(T')={(,a,b,^,ε}FIRST(F)={(,a,b,^}FIRST(F')={*,ε}FIRST(P)={(,a,b,^}FOLLOW(E)={#,)} FOLLOW(E')={#,)}FOLLOW(T)={+,),#}FOLLOW(T')={+,),#}FOLLOW(F)={(,a,b,^,+,),#}FOLLOW(F')={(,a,b,^,+,),#}FOLLOW(P)={*,(,a,b,^,+,),#} (2)考虑下列产生式:'→+'→'→'→E E T T F F P E a b ||*|()|^||εεεFIRST(+E)∩FIRST(ε)={+}∩{ε}=φ FIRST(+E)∩FOLLOW(E')={+}∩{#,)}=φ FIRST(T)∩FIRST(ε)={(,a,b,^}∩{ε}=φ FIRST(T)∩FOLLOW(T')={(,a,b,^}∩{+,),#}=φ FIRST(*F')∩FIRST(ε)={*}∩{ε}=φFIRST(*F')∩FOLLOW(F')={*}∩{(,a,b,^,+,),#}=φFIRST((E))∩FIRST(a) ∩FIRST(b) ∩FIRST(^)=φ 所以,该文法式LL(1)文法. (3)+*()a b ^ #EE TE →'E TE →' E TE →' E TE →'E' '→+E E'→E ε'→E εTT F T →'T F T →' T F T →' T F T →'T' '→T ε'→T T '→T ε '→T T '→T T '→T T '→T εFF P F →'F P F →' F P F →' F P F →'F' '→F ε '→'F F * '→F ε '→F ε '→F ε '→F ε '→F ε '→F εPP E →()P a → P b → P →^5、考虑文法: S →AS|b A →SA|a (1)列出这个文法的所有LR(0) 项目。

程序设计语言编译原理第三版第7章

程序设计语言编译原理第三版第7章

N→ Є
D →id: T { enter(top(tblptr), , T.type, top(offset)); top(offset):= top(offset) +T.width } 24
§7.2
说明语句
2.含嵌套说明的翻译模式:
(1)语义规则中的操作: Mktable (previous): 创建一张新符号表,并返回指向新表的一个指针; Enter (table, name, type, offset):
(2)置相对地址为当前offset之值, (3)使offset加上该名字所表示的数据对象的域宽。
20
§7.2 说明语句
3. 相应的翻译模式:
PD { offset:=0 } { enter (, T.type,offset);
DD;D
Did:T
offset:=offset+t.width } Tinteger
(0) (1) (2) (3) (4) (5)
(2) (3) (4)
16
§7.1 中间语言
4.间接三元式:便于代码优化处理
方法:间接码表+三元式表
按运算的先后顺序列出有关三元式在三元表中的位置 例: 语句X:=(A+B)*C;Y:=D↑(A+B)的间接三元式表示如下所示: 间接代码 三元式表 (1) (2) (3) (1) (4) (5)
30
已归约串
PLACE
输入串
语义动作
# #X # X:= # X:= # X:= # X:= # X:=
X:= -B*(C+D)# X := -B*(C+D)# X_ -B*(C+D)# X__ B*(C+D)# -B X__B *(C+D)# -E X__B *(C+D)# { E.place:=p=<B>} E1 X_T1 *(C+D)# {E1.place:=newtemp=T1; 生成四元式(1) } … … … … # X:=E*(C X_T1__C +D)# # X:=E*(E1 X_T1__C +D)# { E1.place:=p=<C> } … … … …

编译原理四元式

编译原理四元式

编译原理四元式什么是编译原理四元式编译原理四元式是编译器中的一种数据结构,用于将源代码转化为计算机能够理解和执行的中间代码。

它由四个字段组成:操作符、操作数1、操作数2和结果。

四元式可以描述源代码中的各种数学和逻辑运算,以及赋值和控制流等操作。

四元式的优点1.易于生成:四元式的生成比解析源代码直接生成目标代码更容易,因为四元式是对源代码的直接翻译。

2.易于优化:通过对四元式进行优化,可以减少生成的目标代码的长度和运行时间。

3.易于理解:四元式是一种中间表示形式,可以帮助开发人员更好地理解和调试源代码。

4.易于扩展:可以通过添加新的操作符和操作数类型来扩展四元式的功能。

四元式的组成四元式由四个字段组成:操作符、操作数1、操作数2和结果。

操作符表示进行的操作,如加法、乘法等;操作数1和操作数2是参与操作的数值或变量;结果是操作的结果。

四元式的形式如下:<操作符, 操作数1, 操作数2, 结果>四元式的生成过程四元式的生成过程可以分为词法分析、语法分析和语义分析三个步骤。

1.词法分析:将源代码分割成一个个的词法单元,如标识符、关键字、操作符等。

2.语法分析:根据源代码的语法规则,生成语法树。

语法树是一个由节点和边组成的树状结构,每个节点表示一个语法单元,例如表达式、语句等。

3.语义分析:遍历语法树,并根据语义规则生成四元式。

语义规则定义了源代码中各个语法单元的含义和操作。

四元式的生成过程既可以手动实现,也可以通过编译器生成器生成。

四元式的应用四元式主要用于编译器的各个阶段,在优化和生成目标代码过程中起到关键作用。

1.优化:通过对四元式进行优化,可以减少生成的目标代码的长度和运行时间。

常见的优化技术包括常量折叠、公共子表达式消除和无用代码删除等。

2.目标代码生成:通过对四元式进行目标代码生成,可以将中间代码转化为目标机器代码。

目标机器代码是计算机能够直接执行的二进制指令。

四元式还可以用于源代码的调试和性能分析。

编译原理试卷A参考答案

编译原理试卷A参考答案

《编译原理》试卷A 参考答案注意事项:1. 请考生按要求在试卷装订线内填写姓名、学号和年级专业。

2. 请仔细阅读各种题目的回答要求,在规定的位置填写答案。

3. 不要在试卷上乱写乱画,不要在装订线内填写无关的内容。

4. 满分100分,考试时间为120分钟。

题号一二三四总分统分人得分一、单项选择题(每小题2分共20分)1.中间代码生成所依据的是语言的(C )。

A: 词法规则B: 语法规则C: 语义规则D: 产生式规则2.词法分析器的加工对象是(C )。

A: 中间代码B: 单词C: 源程序D: 元程序3.同正则表达式a*b*等价的文法是(C )。

A: G1: S aS|bS|εB: G2: S aSb|εC: G3: S aS|Sb|εD: G4: S abS|ε4.文法G[A]:A→b A→bH H H →BA B→Ab H →a 不是(B ):A: 2型文法B: 正规文法C: 0型文法D: 1型文法5.算符优先分析每次都是对(算符优先分析每次都是对( B B B )进行规约。

)进行规约。

A: A: 短语短语短语 B: B: B: 最左素短语最左素短语最左素短语 C: C: C: 素短语素短语素短语 D: D: D: 句柄句柄6.一个LR (1)文法合并同心集后,如果不是LALR(1)文法必定存在(B ):A: 移进-归约冲突B: 归约-归约冲突C: 识别句型D: 收集类型信息7.下列不属于类型检查范畴的描述是(C )。

A: 运算符的分量类型的相容性B: 形参和实参类型的相容性C :形参和实参的个数的一致性D: 赋值语句的左右部类型的相容性8.( B B )不是)不是DFA 的成分。

A:A:有穷字母表有穷字母表有穷字母表 B: B: B:初始状态集合初始状态集合C:C:终止状态集合终止状态集合终止状态集合 D: D: D:有限状态集合有限状态集合9.若B 为非终结符,则A α.B β为(为( B B B )项目。

编译原理试题库

编译原理试题库

一填空题1.编译程序首先要识别出源程序中每个,然后再分析每个并翻译其意义。

单词,句子2.编译器常用的语法分析方法有和两种。

自底向上,自顶向下2.通常把编译过程分为分析与综合两大阶段。

词法、语法和语义分析是对源程序的分析,中间代码生成、代码优化与目标代码的生成则是对源程序的综合。

前端,后端4.程序设计语言的发展带来了日渐多变的运行时存储管理方案,主要分为两大类,即方案和分配方案。

静态存储分配,动态存储5.对编译程序而言,输入数据是,输出结果是。

源程序,目标程序6.文法G包括四个组成部分:一组终结符号,一组非终结符号,一组,以及一个开始符号。

产生式7.文法按产生式的形式分为四种类型,它们是:0型文法,又称短语文法;1型文法,又称上下文有关文法;2型文法,又称;3型文法,又称。

上下文无关文法,正规文法8.最右推导称为,由规范推导产生的句型称为规范句型。

规范推导9.设G是一个文法,S是它的开始符号,如果S=>*α,则称α是一个。

仅由终结符号组成的句型是一个。

句型,句子10 对于一个文法G而言,如果L(G)中存在某个句子对应两棵不同,那么该文法就称为是二义的。

语法树11.通常程序设计语言的单词符号分为五种:基本字、、常数、算符、界限符。

标识符12.在自底向上分析法中,LR分析法把“可归约串”定义为。

句柄13.编译中常用的中间代码形式有逆波兰式、三元式、和四元式等。

树代码14.对中间代码优化按涉及的范围分为,和全局优化。

局部优化,循环优化15.局部优化主要包括、利用公共子表达式和删除无用赋值等内容。

合并已知量16.为了构造不带回溯的递归下降分析程序,我们通常要消除和提取左递归,左公共因子17.计算机执行用高级语言编写的程序主要有两种途径:和。

解释执行,编译执行18.扫描器是词法分析,它接收输入的,对源程序进行词法分析并识别出一个个,供语法分析器使用。

源程序,单词符号19.自下而上分析法采用,,和等四种操作。

编译原理期末总结复习

编译原理期末总结复习

编译原理期末总结复习编译原理期末总结复习篇一:一、简答题1.什么是编译程序?答:编译程序是一种将高级语言程序(源程序)翻译成低级语言(目标程序)的程序。

将高级程序设计语言程序翻译成逻辑上等价的低级语言(汇编语言,机器语言)程序的翻译程序。

2.请写出文法的形式定义?答:一个文法G抽象地表示为四元组 G=(Vn,Vt,P,S)–其中Vn表示非终结符号– Vt表示终结符号,Vn∪Vt=V(字母表),Vn∩Vt=φ– S是开始符号,–P是产生式,形如:α→β(α∈V+且至少含有一个非终结符号,β∈V*)3.语法分析阶段的功能是什么?答:在词法分析的基础上,根据语言的语法规则,将单词符号串分解成各类语法短语(例:程序、语句、表达式)。

确定整个输入串是否构成语法上正确的程序。

4.局部优化有哪些常用的技术?答:优化技术1—删除公共子表达式优化技术2—复写传播优化技术3—删除无用代码优化技术4—对程序进行代数恒等变换(降低运算强度)优化技术5—代码外提优化技术6—强度削弱优化技术7—删除归纳变量优化技术简介——对程序进行代数恒等变换(代数简化)优化技术简介——对程序进行代数恒等变换(合并已知量)5.编译过程分哪几个阶段?答:逻辑上分五个阶段:词法分析、语法分析、语义分析与中间代码生成、代码优化、目标代码生成。

每个阶段把源程序从一种表示变换成另一种表示。

6. 什么是文法?答:文法是描述语言的语法结构的形式规则。

是一种工具,它可用于严格定义句子的结构;用有穷的规则刻划无穷的集合;文法是被用来精确而无歧义地描述语言的句子的构成方式;文法描述语言的时候不考虑语言的含义。

7. 语义分析阶段的功能是什么?答:对语法分析所识别出的各类语法范畴分析其含义,进行初步的翻译(翻译成中间代码);并对静态语义进行审查。

8.代码优化须遵循哪些原则?答:等价原则:不改变运行结果有效原则:优化后时间更短,占用空间更少合算原则:应用较低的代价取得较好的优化效果9.词法分析阶段的功能是什么?答:逐个读入源程序字符并按照构词规则切分成一系列单词任务:读入源程序,输出单词符号—滤掉空格,跳过注释、换行符—追踪换行标志,指出源程序出错的行列位置—宏展开,……10.什么是符号表?答:符号表在编译程序工作的过程中需要不断收集、记录和使用源程序中一些语法符号的类型和特征等相关信息。

编译原理题——简答题

编译原理题——简答题

编译原理A1.简要说明语义分析的基本功能。

2. 考虑文法 G[S]:S → (T) | a+S | aT → T,S | S消除文法的左递归及提取公共左因子。

3试为表达式 w+(a+b)*(c+d/(e-10)+8) 写出相应的逆波兰表示。

4. 按照三种基本控制结构文法将下面的语句翻译成四元式序列:while (A<C ∧ B<D){if (A ≥ 1) C=C+1;else while (A ≤ D)A=A+2;}。

5. 已知文法 G[S] 为S → aSb|Sb|b,试证明文法 G[S] 为二义文法。

A答案1答:语义分析的基本功能包括: 确定类型、类型检查、语义处理和某些静态语义检查。

2解:消除文法G[S]的左递归:S→(T) | a+S | aT→ST′T′→,ST′| ε提取公共左因子:S→(T) | aS′S′→+S | εT→ST′T′→,ST′| ε3答:w a b + c d e 10 - / + 8 + * +4答:该语句的四元式序列如下(其中E1、E2和E3分别对应A<C∧B<D、A≥1和A≤D,并且关系运算符优先级高):100 (j<,A,C,102)101 (j,_,_,113)102 (j<,B,D,104)103 (j,_,_,113)104 (j=,A,1,106)105 (j,_,_,108)106 (+, C, 1, C)107 (j,_,_,112)108 (j≤,A,D,110) 109 (j,_,_,112)110 (+, A, 2, A)111 (j,_,_,108)112 (j,_,_,100)1135答:证明:由文法G[S]:S→aSb|Sb|b,对句子aabbbb对应的两棵语法树为:因此,文法G[S]为二义文法。

编译原理B1.什么是句子?什么是语言 ?2. 写一文法,使其语言是偶正整数的集合,要求:(1)允许0打头;(2) 不允许0打头。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验三波兰式和四元式及计算
课程编译原理实验名称波兰式和四元式第页班级11计本学号姓名
实验日期:2013年月日报告退发(订正、重做)
一、实验目的:
将非后缀式用来表示的算术表达式转换为用逆波兰式来表示的算术表达式,并计算用逆波兰式来表示的算术表达式的值。

二、实验说明
1、逆波兰式定义
将运算对象写在前面,而把运算符号写在后面。

用这种表示法表示的表达式也称做后缀式。

逆波兰式的特点在于运算对象顺序不变,运算符号位置反映运算顺序。

采用逆波兰式可以很好的表示简单算术表达式,其优点在于易于计算机处理表达式。

2、产生逆波兰式的前提
中缀算术表达式
3、逆波兰式生成的实验设计思想及算法
(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。

(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。

(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。

(4)如果不是数字,该字符则是运算符,此时需比较优先关系。

做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。

如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。

倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。

(5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得
到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。

3、逆波兰式计算的实验设计思想及算法
(1)构造一个栈,存放运算对象。

(2)读入一个用逆波兰式表示的简单算术表达式。

(3)自左至右扫描该简单算术表达式并判断该字符,如果该字符是运算对
象,则将该字符入栈。

若是运算符,如果此运算符是二目运算符,则将对栈顶部的两个运算对象进行该运算,将运算结果入栈,并且将执行该运算的两个运算对象从栈顶弹出。

如果该字符是一目运算符,则对栈顶部的元素实施该运算,将该栈顶部的元素弹出,将运算结果入栈。

(4)重复上述操作直至扫描完整个简单算术表达式的逆波兰式,确定所有
字符都得到正确处理,我们便可以求出该简单算术表达式的值。

三、实验要求
(一)准备:
1.阅读课本有关章节,
2.考虑好设计方案;
3.设计出模块结构、测试数据,初步编制好程序。

(二)上课上机:
将源代码拷贝到机上调试,发现错误,再修改完善。

第二次上机调试通过。

(三)程序要求:
程序输入/输出示例:
输出的格式如下:
(1)
(2)输入一以#结束的中缀表达式(包括+—*/()数字#)
(3)
(4)逆波兰式
备注:(1)在生成的逆波兰式中如果两个数相连则用&分隔,如28和87,中间用&分隔;
注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、数字,结束符#;
2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);
3.对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。

同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;
(四)代码实现
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form7 : Form
{
public Form7()
{
InitializeComponent();
}
private void button4_Click(object sender, EventArgs e)
{
if (textBox1.Text == "") MessageBox.Show("请输入表达式");
else
{
string s = textBox1.Text; int i; for (i = 0; i < s.Length - 1; i++) ;
if (s[i] != '#') MessageBox.Show("必须以#结尾");
else
{
string s1, s2;
s1 = textBox1.Text;
Bolan bol = new Bolan();
s2 = bol.bl(s1);
textBox2.Text = s2;
}
}
}
private class Bolan
{
private string s1, s2="";
char ch;
char ch1;
char ch2;
char[] ex = new char[100];
Stack<char> stk = new Stack<char>();
public string bl(string s)
{
int i = 0, t = 0;
ch = s[i]; i++;
while (ch != '#')
{
if (ch >= '0' && ch <= '9')
{
int sum = 0;
while ((ch >= '0' && ch <= '9'))
{
sum = sum * 10 + ch - '0';
ch = s[i++];
} i--;
if (s2.Length == 0) s2 +=sum.ToString();
else
{
if(s2[s2.Length-1]<='9'&&s2[s2.Length-1]>='0')
s2 += "&" + sum.ToString();
else s2 += sum.ToString();
}
}
else
{
if (stk.Count == 0) stk.Push(ch);
else
switch (ch)
{
case'(':
stk.Push(ch);
break;
case')':
while (stk.Peek() != '(')
{
ch1 = stk.Pop(); ex[t] = ch1; t++; s2 += ch1; }
stk.Pop();
break;
case'+': while (stk.Count != 0 && stk.Peek() != '(') {
ch1 = stk.Pop(); ex[t] = ch1; s2 += ch1; t++;
}
stk.Push(ch);
break;
case'-':
while (stk.Count != 0 && stk.Peek() != '(')
{
ch1 = stk.Pop(); ex[t] = ch1; s2 += ch1; t++; }
stk.Push(ch);
break;
case'*': if (stk.Peek() == '*' || stk.Peek() == '/') {
ch1 = stk.Pop(); ex[t] = ch1; t++; s2 += ch1; }
stk.Push(ch);
break;
case'/': if (stk.Peek() == '*' || stk.Peek() == '/') {
ch1 = stk.Pop(); ex[t] = ch1; t++; s2 += ch1; }
stk.Push(ch);
break;
default: break;
}
}
ch = s[i]; i++;
}
while (stk.Count != 0)
{
ch1 = stk.Pop(); ex[t] = ch1; t++; s2 += ch1;
}
return s2;
}
}
private void Form7_Load(object sender, EventArgs e)
{
}
}
}
运行结果截图:
(五)练习该实验的目的和思路:
程序较复杂,需要利用到程序设计语言的知识和大量编程技巧,逆波兰式的生成是算符优先分析法的应用,是一种较实用的分析法,通过这个练习可大大提高软件开发能力。

相关文档
最新文档