编译原理实践报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DO-WHILE循环语句的翻译程序设计(递归下降法、输出三地址表示)
1系统描述
1.1实践题目
对循环语句do { 赋值语句} while( 布尔表达式);的翻译程序设计。
1.2实践目的
通过设计、编制、调试一个复合语句的语法及语义分析程序,加深对计算机高级编程语言语法及语义分析方法原理的理解,同时逆向掌握高级编程语言的定义,灵活使用高级程序语言。
1.3实践内容及要求
对选定的复合语句:
(1)按选定的不同题目写出符合自身编译分析方法要求的文法和属性文法。(2)按选定的题目给出采用的分析方法的思想及分析表设计。
(3)给出选定的语法成分的中间代码序列的结构设计。
(4)完成相应的词法分析、语法分析和语义分析程序设计。
(5)编制好翻译程序后,设计若干用例,上机测试并通过所设计的分析程序。2文法及属性文法的描述
2.1文法的描述
文法是对语言结构的定义与描述。即从形式上用于描述和规定语言结构的称为“文法”(或称为“语法”)。我们通过建立一组规则(产生式),来描述句子的语法结构。规定用“::=”表示“由……组成”。因此所谓文法是在形式上对句子结构的定义与描述,而未涉及语义问题。
通过对题目的分析,我们需要调用递归调用的自顶向下的分析方法来对文法
进行语法分析,而递归调用的分析方法对文法也有限制。其一是任一非终结符B 都不是左递归的,否则会产生死循环。其二是对A的任意两个右部βi , βj ,有:select(A→βi)∩ select(A→βj)=φ。
综上所述,我们设计了关于循环语句do { 赋值语句} while( 布尔表达式);的文法:
S->do{L}while(P);
L->AL|ξ
A->id=E1;
E1->T1E
E>+T1E|-T1E|ξ
T1->FT
T->*FT|/FT|ξ
F->id|(E1)
P->E1 op E1
2.2属性文法的描述
属性文法是在上下文无关文法的基础上,为每个文法符号(终结符或非终结符)配备若干相关的“特性”(称为属性)。这些属性代表与文法符号相关信息,例如它的类型、值、代码序列、符号表内容等等。属性与变量一样,可以进行计算和传递。属性加工的过程即是语义处理的过程。一个属性文法包含一个上下文无关文法和一系列语义规则,这些语义规则附在文法的每个产生式上。
综上所述,在之前设计的上下文无关文法的基础上,设计了循环语句的属性文法:
3语法分析方法描述
不确定的自顶向下分析法,也就是带回溯的自顶向下分析法。带回溯的自顶向下分析是一个试探过程,当分析不成功是则推翻分析退回到适当位置再重新试探其余候选可能的推导。这样需要记录推导每步所选过的产生式,直到把所有可能的推导序列都试空仍不成功才能确定输入串是不是该文法的句子而报错。在程序语言的语法定义中有许多采用递归定义。我们在对它进行语法分析时,编制的处理程序也采取递归的方式,可使其结构简单易读。
递归下降法的主要思想是:对每个非终结符按其产生式结构写出相应语法分析子程序。因为文法递归相应子程序也递归,子程序的结构与产生式结构几乎一致。所以称此种方法称为递归子程序法或递归下降法。
根据设计的循环语句的文法我需要将文法中的非终结符(S、L、A、E1、E、T1、T、F、P)编写出对应的语法分析子程序。如下:
S的子程序:
If char ϵ select(S->do{L}while(P);) then ξ(“do{”); ξ(L);ξ(“} while(”);ξ(P);ξ(“);”)
else error
L的子程序:
If char ϵ select(L->AL) then ξ(A); ξ(L);
else if char ϵ select(L->ε) then READ(char)
else error
A的子程序:
If char ϵ select(A->id=E1;) then ξ(“id=”); ξ(E1); ξ(“;”);
else error
E1的子程序:
If char ϵ select(E1->T1E) then ξ(T1); ξ(E);
else error
E的子程序:
If char ϵ select(E>+T1E) then ξ(“+”);ξ(T1); ξ(E);
else if char ϵ select(E>-T1E) then ξ(“-”); ξ(T1); ξ(E);
else if char ϵ select(E->ε) then READ(char)
else error
T1的子程序:
If char ϵ select(T1->FT) then ξ(F); ξ(T);
else error
T的子程序:
If char ϵ select(T->*FT) then ξ(“*”);ξ(F); ξ(T);
else if char ϵ select(T->/F T) then ξ(“/”); ξ(F); ξ(T);
else if char ϵ select(T->ε) then READ(char)
else error
F的子程序:
If char ϵ select(F->id) then ξ(id);
else if char ϵ select(F->(E1)) then ξ(“(”); ξ(E1); ξ(“)”);
else error
P的子程序:
If char ϵ select(P->E1 op E1) then ξ(E1); ξ(op); ξ(E1);
else error
4中间代码形式的描述及中间代码序列的结构设计4.1中间代码形式的描述
中间代码(语言)是一种特殊结构的语言,编译程序所使用的中间代码有多种形式。按其结构分常见的有逆波兰式(后缀式)、三地址代码(三元式、四元式)和树形表示(抽象语法树)、DAG表示。根据题目要求需将循环语句do { 赋值语句} while( 布尔表达式);转换成三地址形式的中间代码形式。
三地址代码的一般形式为:x := y op z 常用的三地址表示有:
赋值语句:x := y op z,x := op y,x := y
无条件转移:goto L
条件转移:if x relop y goto L
过程调用:param x 和call p , n
过程返回:return y
索引赋值:x := y[i]和x[i] := y
地址和指针赋值:x := &y,x := y和 x := y
4.2中间代码序列的结构设计
根据上述的关于三地址中间代码的概念与定义,我们就可以将循环语句do { 赋值语句} while( 布尔表达式);翻译成合法的中间代码,举例如下:
例子:do { a2=m+5; a1=3+s;}while(a>3);
翻译的三地址:0 t0=m+5
1 a2=t0
2 t2=3+s
3 a1=t2
4 if a>3 goto 0
5 goto out