编译原理试验指导.docx

上传人:b****6 文档编号:8244249 上传时间:2023-01-30 格式:DOCX 页数:11 大小:82.81KB
下载 相关 举报
编译原理试验指导.docx_第1页
第1页 / 共11页
编译原理试验指导.docx_第2页
第2页 / 共11页
编译原理试验指导.docx_第3页
第3页 / 共11页
编译原理试验指导.docx_第4页
第4页 / 共11页
编译原理试验指导.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

编译原理试验指导.docx

《编译原理试验指导.docx》由会员分享,可在线阅读,更多相关《编译原理试验指导.docx(11页珍藏版)》请在冰豆网上搜索。

编译原理试验指导.docx

编译原理试验指导

 

编译原理实验指导

 

计算机工程学院

 

内容简介

 

编译原理是计算机专业中的一门专业必修课程,在理论上它要求学生掌握有关形式语言和自动机的抽象概念,在技术上要求学生能够熟练地利用各种数据结构进行编程,很具有挑战性。

我们希望学生在学习完本课之后,能够对形式语言和其内部结构有一个较深刻的认识。

本书包含三个实验:

词法分析器,LL1语法分析、语义与代码生成。

这三个实验构成了编译器的主要组成部分,全部在VC++6.0环境下完成。

目录

实验一词法分析实验1

实验二LL1语法分析4

实验三语义及代码生成7

实验一词法分析实验

1、实验目的

加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。

2、实验内容

对源程序进行词法分析:

要求识别出关键字、标识符、数字和符号,并以(单词类别,单词值)二元组的形式显示。

如inta;经过词法分析程序后得到的二元组为:

intint

IDa

;;

以下为词法分析程序的测试数据

main()

{

inta,b;

a=10;

b=a+20;

}

请对以上代码利用词法分析程序分析并得到相应的二元组。

3、实验分析

在本次实验中是对一个简化的c语言程序进行分析,它的单词符号有:

●标识符:

字母打头,后接字母数字,识别出的标识符用ID标记。

●保留字(它是标识符的子集):

if,else,for,while,do,int,write,read,识别出的保留字直接用该保

留字标记。

●无符号整数:

由数字组成,用NUM标记。

●分界符:

+、-、*、/、(、)、;、,>、<、{、}、!

等单分界符,直接用单分界符标记。

>=、<=、!

=、==等双字符分界符,直接用双分界符标记。

●注释符:

用/*….*/括起

为了从源程序字符流中正确识别出各类单词符号,相邻的标识符、整数或保留字之间至少要用一个空格分开。

此语言的各类单词符号的正则文法规则如下:

∷=|ID|ID

∷=|

∷=a|b|…|z|A|B|…|Z

∷=1|2|…|9|0

∷=+|-|*|/|=|(|)|{|}|:

|,|;|<|>|!

∷=>=|<=|!

=|==

∷=/*

∷=*/

图1单词符号的状态图

根据状态图,分析相应动作就可以构造出词法分析程序的算法流程图,如下图所示,在程序开始时,首先读入一个字符,若为空字符,则继续读,直到读进一个非空字符,读进的字符有如下6种情况,要进行不同的处理。

(1)字母。

继续读,直到遇见空格、分界符、文件尾或非字母数字字符。

组合标记符,查保留字表。

若为保留字,输出相应单词记号;若不是,输出标记符的单词记号及单词值(标识符)。

(2)数字。

继续读,直到遇见空格、或非数字字符出现或文件尾。

输出无符号整数的单词记号及数字串。

(3)=、<、>、!

读入下一个字符,判断是否为双字符分界符,若是,组成双字符分界符,输出相应单词记号及双分界符;若不是,输出单分界符记号。

(4)非=、<、>、/等与双分界符首字符不同的单分界字符。

输出相应单词记号及单分界符。

(5)/。

读入下一个字符。

若不是“*”,输出/的单词记号;若是“*”,进行注释处理。

词法分析不输出“/*”,并要跳过整个注释内容直到遇到“*/”为止,然后返回开始状态,继续识别下一个单词符号。

(6)非法字符。

如果读进的字符不属于上面任意情况,则说明词法分析程序从源程序读入了一个不合法的字符,即该字符不属于程序语言所定义的所有单词符号首字符集合。

词法分析程序在遇到不合法字符时要进行错误处理,报告错误信息,跳过这个字符,然后转入开始状态,继续识别下一个单词符号。

图2词法分析程序流程图

4、实验步骤

(1)启动VisualC++系统,新建一个工程;

(2)新建一个源程序文件;

(3)编译,调试该程序;

(4)运行该程序,输入测试数据,观察输出数据;

(5)分析实验结果。

实验二LL1语法分析

1、实验目的

(1)一切LL

(1)文法;含有直接左递归但可以转化为LL

(1)文法的文法;含有间接左递归但可以转化为LL

(1)文法的文法

(2)计算出文法的First()Follow()

(3)构造相应文法的预测分析表

(4)对某个输入句子进行分析

2、实验内容

LL

(1)文法是一类可以进行确定的自顶向下语法分析的文法。

就是要求描述语言的文法是无左递归的和无回溯的。

根据LL

(1)文法的定义,对于同一非终结符A的任意两个产生式A:

=a和A:

=b,都要满足:

SELECT(A:

=a)∩SELECT(A:

=b)=Ø。

(1)文法的左递归

当一个文法是左递归文法时,采用自顶向下分析法会使分析过程进入无穷循环之中。

所以采用自顶向下语法分析需要消除文法的左递归性。

文法的左递归是指若文法中对任一非终结符A有推导AA…,则称该文法是左递归的。

左递归又可以分为直接左递归和间接左递归。

●直接左递归

若文法中的某一产生式形如A→Aα,α∈V*,则称该文法是直接左递归的。

消除直接左递归的方法:

设有产生式是关于非终结符A的直接左递归:

A→Aα|β(α,β∈V*,且β不以A开头)

对A引入一个新的非终结符A′,把上式改写为:

A→βA′

A′→αA′|ε

●间接左递归

若文法中存在某一非终结符A,使得AA…至少需要两步推导,则称该文法是间接左递归的。

消除间接左递归的方法:

【方法一】采用代入法把间接左递归变成直接左递归。

【方法二】直接改写文法:

设有文法G10[S]:

S→Aα|β⑴

A→Sγ⑵

因为SAαSγα,所以S是一个间接递归的非终结符。

为了消除这种间接左递归,将⑵式代入⑴式,即可得到与原文法等价的文法(可以证明):

S→Sγα|β⑶

⑶式是直接左递归的,可以采用前面介绍的消除直接左递归的方法,对文法进行改写后可得文法:

S→βS′

S′→γαS′|ε

1计算first集合

(1)若X∈VT,则First(X)={X}

(2)若X∈VN,且有产生式X→a…,a∈VT则First(X)={X}

(3)若X∈VN,且有产生式X→ε,则First(X)={X}

(4)若X,Y1,Y2,…,Yn都∈VN,而由产生式X→Y1Y2…Yn。

当Y1,Y2,…,Yi-1都能推导出ε时,(其中1≤i≤n),则First(Y1)-{ε},First(Y2)-{ε},…,First(Yi)都包含在First(X)中

(5)当(4)中所有Yi都能推导出ε,(i=1,2,…,n),则First(X)=First(Y1)∪First(Y2)∪…First(Yn)∪{ε}

反复使用上述步骤直到每个符合的First集合不再增大为止。

2计算Follow集

对文法中的每个A∈VN,计算Follw(A):

(1)设S为文法的开始符合,把{#}加入Follow(S)中;

(2)若A→αBβ是一个产生式,则把First(β)的非空元素加入Follow(B)中,如果β能推导出ε,则把Follow(A)也加入(B)中;

(3)反复使用以上步骤直到每个非终结符号的Follow集不再增大为止。

3预测分析方法

预测分析方法是自顶向下分析的另一种方法,一个预测分析器是由三个部分组成:

预测分析程序;先进后出栈;预测分析表。

预测分析程序的框图如下:

实验三语义及代码生成

1、实验目的

理解并掌握语义分析的基本概念,基本方法;掌握代码优化与目标生成的基本原理与技术实现;编写类C语言编译程序的目标代码生成的程序,调试成功后,以给出的程序段为测试数据,并按一定格式显示结果。

2、实验内容和分析

与实验二的语法规则相比,只有部分规则需要添加动作符号,下面我们列出添加了动作符号的规则。

(1)↓vartablep,datap->intID↑n@name-def↓n,t;

动作解释:

vartablep指出符号表的最后一个记录的下一个位置,即第一个空白记录位置。

每当有一个记录加入符号表,该值加1;datap表示已经分配的地址空间,它开始时为0,每声明一个变量,该值则根据变量类型累加,如整型加2,实型加4等等。

@name-def↓n,t的动作:

查询符号表,从vartablep所指的前一个位置起往回查直到第一个记录,若没有,将标识符名n及类型1、datap的值填入符号表vartablep所指的位置,然后vartablep加1,datap根据类型t增加;若有,报告错误:

变量重复定义。

(2):

:

=ID↑n@LOOK↓n↑d@ASSIGN=@STO↓d|

(3):

:

=

|>@GT

|<@LES

|>=@GE

|<=@LE

|==@EQ

|!

=@NOTEQ

(4):

:

={(+@ADD|-<项>@SUB)}

(5):

:

={(*@MULT|/@DIV)}

(6):

:

=()|ID↑n@LOOK↓n↑d@LOAD↓d|NUM↑i@LOADI↓i

(2)、(3)、(4)、(5)、(6)规则中的动作符号解释如下:

@LOOK↓n↑d:

查符号表n,给出变量地址d;没有,变量没定义

@ASSIGN:

超前读一个符号,如果是'=',则表示进入赋值表达式,如果不是'=',则选择<比较表达式>,然后还要将超前读的这个符号退回。

@STO↓d:

输出指令代码STOd,且codep++(因产生了指令,所以指令记数加1)

@LOADI↓i:

输出指令代码LOADIi,且codep++

@LOAD↓d:

输出指令代码LOADd,且codep++

@GT、@ADD等:

输出后的指令代码GT、ADD等

(7):

:

=if()@BRF↑label1@BR↑label2

@SETlabel↓label1[else]@SETlabel↓label2

其中动作符号的含义如下

@BRF↑label1:

输出BRFlabel1,codep++

@BR↑label2:

输出BRlabel2,codep++

@SETlabel↓label1:

设置标号label1

@SETlabel↓label2:

设置标号label2

(8):

:

=while@SETlabel↑label1()@BRF↑label2

@BR↓label1@SETlabel↓label2

动作解释如下:

@SETlabel↑label1:

设置标号label1

@BRF↑label2:

输出BRFlabel2,codep++

@BR↓label1:

输出BRlabel1,codep++

@SETlabel↓label2:

设置标号label2

(9):

:

=for(;

@SETlabel↑label1@BRF↑label2@BR↑label3;

@SETlabel↑label4@BR↓label1)

@SETlabel↓label3@BR↓label4@SETlabel↓label2

动作解释:

@SETlabel↓label1:

设置标号label1

@BRF↑label2:

输出BRFlabel2,codep++

@BR↑label3:

输出BRlabel3,codep++

@SETlabel↓label4:

设置标号label4

@BR↑label1:

输出BRlabel1,codep++

@SETlabel↓label3:

设置标号label3

@BR↑label4:

输出BRlabel4,codep++

@SETlabel↓label2:

设置标号label2

(10):

:

=write@OUT;

动作解释:

@OUT:

输出OUT

(11):

:

=readID↑nLOOK↓n↑d@IN↓d;

动作解释:

@LOOK↓n↑d:

查符号表n,给出变量地址d;没有,变量没定义

@IN:

输出IN

@STI↓d:

输出指令代码STId

抽象机常用汇编指令如下:

LOADD将D中的内容加载到操作数栈

LOADI常量将常量压入操作数栈

LOAD(D)将变量地址D压入操作数栈

STOD将操作数栈栈顶单元内容存入D

ADD将次栈顶单元与栈顶单元内容相加,和置于栈顶

SUB将栈顶单元减去次栈顶单元内容,差置于栈顶

MULT将次栈顶单元与栈顶单元内容相乘,积置于栈顶

DIV将栈顶单元除次栈顶单元内容,商置于栈顶(分母为栈)

BRlab无条件转移到lab

BRFlab检查栈顶单元逻辑值,若为假(0)则转移到lab

EQ将栈顶两单元做等于比较,并将结果真或假(1或0)置于栈顶

NOTEQ将栈顶两单元做不等于比较,并将结果真或假(1或0)置于栈顶

GT次栈顶大于栈顶操作数,则栈顶置1,否则置0

LES次栈顶小于栈顶操作数,则栈顶置1,否则置0

GE次栈顶大于等于栈顶操作数,则栈顶置1,否则置0

LE次栈顶小于等于栈顶操作数,则栈顶置1,否则置0

AND将栈顶两单元做逻辑与运算,并将结果真或假(1或0)置于栈顶

OR将栈顶两单元做逻辑或运算,并将结果真或假(1或0)置于栈顶

NOT将栈顶的逻辑值取反

构造语义和代码生成程序,然后对测试程序进行分析

测试程序

{

inta;

intb;

reada;

writea;

if(a==10)b=1;elseb=2;

writeb;

while(a<=6)b=3;

writeb;

b=0;

for(a=0;a<5;a=a+1)b=4;

writeb;

}

3、实验分析

在本实验中仍采用递归下降分析法,根据实验二中的语法分析,用上面给出的各语句程序替换语法分析对应的同名函数程序,即可将语法分析改为语义分析和代码生成程序。

为了简化起见,在类C编译程序中没有进行复杂的错误处理。

在语法和语义分析中,一旦遇到语法或语义错误,则停止编译,立即返回,并报告发生的错误。

4、实验步骤

(1)启动VisualC++系统,新建一个工程;

(2)新建一个源程序文件;

(3)编译,调试该程序;

(4)运行该程序,输入测试数据,观察输出数据;

(5)分析实验结果。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 初中教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1