编译原理实验指导书.docx

上传人:b****2 文档编号:3120511 上传时间:2023-05-05 格式:DOCX 页数:28 大小:210.97KB
下载 相关 举报
编译原理实验指导书.docx_第1页
第1页 / 共28页
编译原理实验指导书.docx_第2页
第2页 / 共28页
编译原理实验指导书.docx_第3页
第3页 / 共28页
编译原理实验指导书.docx_第4页
第4页 / 共28页
编译原理实验指导书.docx_第5页
第5页 / 共28页
编译原理实验指导书.docx_第6页
第6页 / 共28页
编译原理实验指导书.docx_第7页
第7页 / 共28页
编译原理实验指导书.docx_第8页
第8页 / 共28页
编译原理实验指导书.docx_第9页
第9页 / 共28页
编译原理实验指导书.docx_第10页
第10页 / 共28页
编译原理实验指导书.docx_第11页
第11页 / 共28页
编译原理实验指导书.docx_第12页
第12页 / 共28页
编译原理实验指导书.docx_第13页
第13页 / 共28页
编译原理实验指导书.docx_第14页
第14页 / 共28页
编译原理实验指导书.docx_第15页
第15页 / 共28页
编译原理实验指导书.docx_第16页
第16页 / 共28页
编译原理实验指导书.docx_第17页
第17页 / 共28页
编译原理实验指导书.docx_第18页
第18页 / 共28页
编译原理实验指导书.docx_第19页
第19页 / 共28页
编译原理实验指导书.docx_第20页
第20页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

编译原理实验指导书.docx

《编译原理实验指导书.docx》由会员分享,可在线阅读,更多相关《编译原理实验指导书.docx(28页珍藏版)》请在冰点文库上搜索。

编译原理实验指导书.docx

编译原理实验指导书

LIAOCHENGUNIVERSITY

 

编译原理

实验指导书

 

聊城大学计算机学院

2011年3月

目 录

《编译原理》课程实验教学大纲

课程名称:

编译原理

英文名称:

Compileprinciples

设置形式:

非独立设课

课程模块:

专业方向课

实验课性质:

专业实验

课程编号:

509615

课程负责人:

姜华

大纲主撰人:

姜华

大纲审核人:

左风朝

一、学时、学分

课程总学时:

72

实验学时:

8

课程学分:

4

二、适用专业及年级

计算机科学与技术、软件工程三年级

三、课程目标与基本要求

《编译原理》课程是计算机专业的核心课程,是培养计算机技术高级人才的必修课程。

该课程通过程序设计语言和语言处理软件的理论与技术的教学,培养学生利用计算机语言处理技术进行系统分析和软件设计的能力。

<<编译原理>>是理论与实践并重的课程,这门实验课要综合运用一、二、三年级所学的多门课程的内容。

实验目标与要求;1.学会用高级程序设计语言设计词法分析器。

2.学会用高级程序设计语言设计语法分析器。

四、主要仪器设备

Windows操作系统,编程语言采用C、C++,集成调试环境采用TC或MicrosoftVisualStudio6

五、实验项目及教学安排

 

实验项目

名称

实验内容

学时

要求

性质

类别

所用主要仪

器及台套数

所在实验室

1

用C或者C++语言设计一个词法分析器

1.   确定编译中使用的表格、词法分析器的输出形式、标识符与关键字的区分方法。

2.    把词法分析器设计成一个独立的过程。

4

必做

设计

综合型

微机,每人一台。

计算机学院实验中心

2

用C或者C++语言设计一个语法分析器。

1. 词法分析和语法分析在一起实现。

2.把语法分析器设计成一个独的过程。

4

必做

设计

综合型

微机,每人一台。

计算机学院实验中心

六、考核方式及成绩评定

根据学生实验出勤情况、实验态度、实验报告成绩等方面评定实验成绩。

实验报告平均成绩(含实验理论)占实验成绩的50%,实验技能平均成绩(含实验态度)占实验成绩的50%。

实验成绩占该课程考试总成绩的10%—20%。

在机器上将程序及运行结果上传至服务器,由实习教师给出优、良、中、及格、不及格。

七、实验教科书、参考书

1.实验教科书

自编实验指导书。

2.实验参考书

实验一 词法分析器的设计

基本信息

实验课程:

编译原理设课形式:

非独立

课程学分:

4实验项目:

词法分析器的设计

项目类型:

设计项目学时:

4

实验目的

1.掌握词法分析的原理;

2.熟悉符号表的建立与单词的分类方法;

3.掌握词法分析器的设计与调试;

实验内容

1.分析如表1所定义的PASCAL语言子集的语法,找出所有单词的组成及类别;

2.完成单词的分类及其编码;

3.完成保留字表、变量名表和常数表的结构设计;

4.建立识别单词符号集合的DFA;

5.由DFA设计词法分析程序;

6.调试并运行词法分析程序;

7.实验结果分析。

分析结果含义并写出自己的心得体会。

表1.PASCAL语言子集的语法定义

〈程序〉→〈变量说明〉BEGIN〈语句表〉END.

〈变量说明〉→VAR〈变量表〉:

〈类型〉;|〈空〉

〈变量表〉→〈变量表〉,〈变量〉|〈变量〉

〈类型〉→INTEGER

〈语句表〉→〈语句表〉;〈语句〉|〈语句〉

〈语句〉→〈赋值语句〉|〈条件语句〉|〈WHILE语句〉|〈复合语句〉|〈过程定义〉

〈赋值语句〉→〈变量〉∶=〈算术表达式〉

〈条件语句〉→IF〈关系表达式〉THEN〈语句〉ELSE〈语句〉

〈WHILE语句〉→WHILE〈关系表达式〉DO〈语句〉

〈复合语句〉→BEGIN〈语句表〉END

〈过程定义〉→PROCEDURE〈标识符〉〈参数表〉;BEGIN〈语句表〉END

〈参数表〉→(〈标识符表〉)|〈空〉

〈标识符表〉→〈标识符表〉,〈标识符〉|〈标识符〉

〈算术表达式〉→〈算术表达式〉+〈项〉|〈项〉

〈项〉→〈项〉*〈初等量〉|〈初等量〉

〈初等量〉→(〈算术表达式〉)|〈变量〉|〈无符号数〉

〈关系表达式〉→〈算术表达式〉〈关系符〉〈算术表达式〉

〈变量〉→〈标识符〉

〈标识符〉→〈标识符〉〈字母〉|〈标识符〉〈数学〉|〈字母〉

〈无符号数〉→〈无符号数〉〈数字〉|〈数字〉

〈关系符〉→=|<|<=|>|>=|<>

〈字母〉→A|B|C|…|X|Y|Z

〈数字〉→0|1|2|…|8|9

〈空〉→

提示:

(1)单词的分类。

可将所有标识符归为一类;将常数归为另一类;保留字和分隔符则可采取一词一类。

(2)符号表的建立。

可事先建立一保留字表,以备在识别保留字时进行查询。

变量名表及常数表则在词法分析过程中建立。

(3)单词串的输出形式。

所输出的每一单词,均按形如(CLASS,VALUE)的二元式编码。

对于变量标识符和常数,CLASS字段为相应的类别码,VALUE字段则是该标识符、常数在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串,其最大长度为四个字符;常数表登记项中则存放该整数的二进制形式)。

对于保留字和分隔号,由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。

不过,为便于查看由词法分析程序所输出的单词串,也可以在CLASS字段上直接放置单词符号串本身。

测试用输入:

测试用输入程序为。

Procedureprogram1(a,b);

Begin

Varxyz=50;

Whilea>bdo

begin

Ifxyz=0then

xyz=50;

xyz:

=xyz-a;

a:

=a-1;

end

End

实验扩充

构造语言的词法分析程序,要求识别出变量类型并记录相关信息。

实验说明

实验环境:

WINDOWS下,工具为TurboC2.0或VisualC6.0。

实验考核方式

1.提交实验报告

2.演示程序和答辩(抽查)

实验辅导

1.词法分析程序的功能

词法分析程序又称为扫描器,其功能在于依次扫视字符串形式源程序中的各个字符,逐个识别出其中的单词,并将其转换为内部编码形式的单词符号串作确为输出。

通常,可采用二元式

(class,value)

来表示一个单词符号的内部编码,其中:

class为一整数码,用于表示该单词的类别;value则是该单词之值(如变量名在符号表中序号,常数的二进制表示,以及运算符和分隔符的编码等等)。

概括地说,扫描器在其工作过程中,一般应完成下列的任务:

(1)识别出源程序中的各个单词符号,并将其转换为内部编码形式;

(2)删除无用的空白字符、回车字符以及其它非实质性字符;

(3)删除注释;

(4)进行词法检查,报告所发现的错误。

此外,视编译工作流程的组织,一些编译程序在进行词法分析时,还要完成将所识别出的标识符登录到符号表的工作。

2.实例分析

对于表2所列的各类单词符号,词法分析程序可按图1所示的状态转换图来构造。

表2一个语言的单词符号及分类码表

图1识别表2所列语言单词的DFA及相关的语义过程

相关变量和子程序说明如下:

◆函数GETCHAR每调用一次,就把扫描指示器当前所指示的源程序字符送入字符变量ch,然后把扫描指示器前推一个字符位置。

◆字符数组TOKEN用来依次存放一个单词词文中的各个字符。

◆函数CAT每调用一次,就把当前ch中的字符拼接于TOKEN中所存字符串的右边。

◆函数LOOKUP每调用一次,就以TOKEN中的字符串查保留字表,若查到,就将相应关键字的类别码赋给整型变量c;否则将c置为零。

◆函数RETRACT每调用一次,就把扫描指示器回退一个字符位置(即退回多读的那个字符)。

◆函数OUT一般仅在进入终态时调用此函数,调用的形式为OUT(c,VAL)。

其中,实参c为相应单词的类别码或其助记符;当所识别的单词为标识符和整数时,实参VAL为TOKEN(即词文分别为字母数字串和数字串),对于其余种类的单词,VAL均为空串。

函数OUT的功能是,在送出一个单词的内部表示之后,返回到调用该词法分析程序的那个程序。

可参考的C语言源程序如下:

#include

#include

#include

#defineID6

#defineINT7

#defineLT8

#defineLE9

#defineEQ10

#defineNE11

#defineGT12

#defineGE13

charTOKEN[20];

externintlookup(char*);

externvoidout(int,char*);

externreporterror(void);

voidscannerexample(FILE*fp)

{

charch;

inti,c;

ch=fgetc(fp);

if(isalpha(ch))/*itmustbeaidentifer!

*/

{

TOKEN[0]=ch;

ch=fgetc(fp);i=1;

while(isalnum(ch))

{

TOKEN[i]=ch;i++;

ch=fgetc(fp);

}

TOKEN[i]=′\0′

fseek(fp,-1,1);/*retract*/

c=lookup(TOKEN);

if(c==0)out(ID,TOKEN);

elseout(c,"");

}

Else

if(isdigit(ch))

{

TOKEN[0]=ch;

ch=fgetc(fp);i=1;

while(isdigit(ch))

{

TOKEN[i]=ch;i++;

ch=fgetc(fp);

}

TOKEN[i]=′\0′;

fseek(fp,-1,1);

out(INT,TOKEN);

}

Else

switch(ch)

{

case′<′:

ch=fgetc(fp);

if(ch==′=′)out(LE,"");

elseif(ch==′>′)out(NE,"");

else

{

fseek(fp,-1,1);

out(LT,"");

}

break;

case′=′:

out(EQ,"");break;

case′>′:

ch=fgetc(fp);

if(ch==′=′)out(GE,"");

else

{

fseek(fp,-1,1);

out(GT,"");

}

break;

default:

reporterror();

break;

}

return;

}

 

实验二 语法分析器的设计

基本信息

实验课程:

编译原理设课形式:

非独立

课程学分:

4实验项目:

语法分析器的设计

项目类型:

设计项目学时:

4

实验目的

1.掌握自上而下语法分析的基本思想;

2.掌握利用预测分析法进行语法分析的原理和过程;

3.熟悉文法的机内表示;

4.掌握语法分析器的设计与调试,提高编程能力、动手能力以及独立分析问题、解决问题的能力和综合运用所学知识的能力。

实验内容

1.输入任意文法,改写文法使其成为LL

(1)文法。

2.构造文法的预测分析表;

3.设计堆栈和预测分析表的机内表示;

4.设计并书写语法分析程序;

5.调试并运行语法分析程序;

6.实验结果分析

●分析程序中文法存储所采用的数据结构

●分析结果并写出自己的心得体会

提示:

对于所选定的分析方法,如有需要,应选择一种合适的数据结构,以构造所给文法的机内表示。

实验说明:

实验环境:

WINDOWS下,工具为TurboC2.0或VisualC6.0。

实验考核方式:

1.提交实验报告

2.演示程序和答辩(抽查)实验预习

实验辅导

1.设计原理及算法描述

所谓LL

(1)分析法,就是指从左到右扫描输入串(源程序),同时采用最左推导,且对每次直接推导只需向前看一个输入符号,便可确定当前所应当选择的规则。

实现LL

(1)分析的程序又称为LL

(1)分析程序或LL1

(1)分析器。

一个文法要能进行LL

(1)分析,那么这个文法应该满足:

无二义性,无左递归,无左公因子。

当文法满足条件后,再分别构造文法每个非终结符的FIRST和FOLLOW集合,然后根据FIRST和FOLLOW集合构造LL

(1)分析表,最后利用分析表,根据LL

(1)语法分析构造一个分析器。

2.分析过程

LL

(1)的语法分析程序包含了三个部分,总控程序,预测分析表函数,先进先出的语法分析栈,本程序也是采用了同样的方法进行语法分析,该程序是采用了C语言来编写,其逻辑结构图如图2所示。

图2LL

(1)语法分析逻辑结构图

LL

(1)预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号a做哪种过程的。

对于任何(X,a)总控程序每次都执行下述三种可能的动作之一:

(1)若X=a=‘#’,则宣布分析成功,停止分析过程。

(2)若X=a‘#’,则把X从STACK栈顶弹出,让a指向下一个输入符号。

(3)若X是一个非终结符,则查看预测分析表M。

若M[A,a]中存放着关于X的一个产生式,那么,首先把X弹出STACK栈顶,然后,把产生式的右部符号串按反序一一弹出STACK栈(若右部符号为ε,则不推什么东西进STACK栈)。

若M[A,a]中存放着“出错标志”,则调用出错诊断程序ERROR。

事实上,LL

(1)的分析是根据文法构造的,它反映了相应文法所定义的语言的固定特征,因此在LL

(1)分析器中,实际上是以LL

(1)分析表代替相应方法来进行分析的。

3.构造LL

(1)分析表

例如考查文法G[E]:

E→E+T|T

T→T*F|F

F→(E)|i|

我们容易看出此文法没有左公因子也没有二义性,但却存在两个直接左递归,这里我们利用引入新非终结符的方法来消除它使方法满足要求,即:

(1)改写文法。

对形如:

U→Ux|y的产生式(其中x,yV+,y不以U开头),引入一个新的非终结符U’后,可以等价地改写成为:

U→yU’

U’→xU’|ε

显然改写后,U和U’都不是左递归的非终结符。

因此文法G[E]按上述方法消去左递归后可等价地写成:

E→TP

P→+TP|ε

T→FQ

Q→*FQ|ε

F→(E)|i

(2)FIRST和FOLLOW集合构造。

在构造LL

(1)预测分析表之前,首先要构造该文法的每个非终结符的FIRST和FOLLOW集合,按照下面描述的算法来构造这两个集合。

①FIRST集合的构造算法:

●若X∈VT,则FIRST(X)={X}。

●若X∈VN,且有产生式X→a……,则把a加入到FIRST(X)中;若X→ε也是一条产生式,则把ε也加到FIRST(X)中。

●若X→Y……是一个产生式且Y∈VN,则把FIRST(Y)中的所有非ε-元素都加到FIRST(X)中;若X→Y1Y2…Yk是一个产生式,Y1,…,Yi-1都是非终结符,而且,对于任何j,1≤j≤i-1,FIRST(Yj)都含有ε(即Y1…Yi-1*ε),则把FIRST(Yj)中的所有非ε-元素都加到FIRST(X)中;特别是,若所有的FIRST(Yj)均含有ε,j=1,2,…,k,则把ε加到FIRST(X)中。

连续使用上面的规则,直至每个集合FIRST不再增大为止。

②FOLLOW集合的构造算法:

●对于文法的开始符号S,置#于FOLLOW(S)中;

●若A→αBβ是一个产生式,则把FIRST(β)|{ε}加至FOLLOW(B)中;

●若A→αB是一个产生式,或A→αBβ是一个产生式而βε(即ε∈FIRST(β)),则把FOLLOW(A)加至FOLLOW(B)中。

连续使用上面的规则,直至每个集合FOLLOW不再增大为止。

算法中利用二维数组分别表示各产生式右部的FIRST和左部的FOLLOW集合

(3)预测分析表构造。

构造G[E]的LL

(1)预测分析表。

预测分析表M[A,a]是如下形式的一个矩阵。

A为非终结符,a是终结符或‘#’。

矩阵元素M[A,a]中存放这一条关于A的产生式,指出当A面临输入符号a是所应采用的规则。

M[A,a]也可能存放一条“出错标志”,指出当A根本不该面临输入符号a。

算法中利用二维数组存储分析表。

4.利用分析表进行预测分析

(1)总控程序的流程图

LL

(1)分析法总控程序流程图如图3所示。

图3LL

(1)分析法总控程序流程图

(2)总程序的算法描述如下:

BEGIN

首先把‘#’然后把文法开始符号推进STACK栈;

把第一个输入符号读进a;FLAG:

=TRUE;

WHILEFLAGDO

BEGIN

把栈顶符号出栈到X中;

IFXinVTTHEN

IFX=aTHEN把下一输入符号读进a

ELSEERROR

ELSEIFX=‘#’THENIFX=aTHENFLAG:

=FALSE

ELSEERROR

ELSEIFM[A,a]={X→x1x2…xk}THEN把xk,xk–1,…,x1依次进栈/*若x1,x2…xk=e,则不进栈*/

ELSEERROR

ENDOFWHILE;STOP/*分析成功,过程结束*/

END

(5)实例分析

①实例

考查文法G[E]:

E→E+T|T

T→T*F|F

F→(E)|i|

文法改造为LL

(1)文法为测试文法G[E]:

E→TG

G→+TG|^

T→FS

S→*FS|^

F→(E)|i

分析例句:

i*(i)#,i+i#

输入:

串w和文法G的分析表M。

输出:

如果W属于L(G),则输出W的最左推导,否则报告错误。

方法:

开始时,#S在分析栈中,其中S是文法的开始符号,在栈顶;令指针ip指向W#的第一个符号;

②主要数据结构描述

chartermin[50];/*终结符号*/

charnon_ter[50];/*非终结符号*/

charv[50];/*所有符号*/

charleft[50];/*左部*/

charright[50][50];/*右部*/

intM[20][20];/*二维数组存储分析表*/

栈T用来存放产生式的右边

Str数组存放要分析的句子串

③可参考的C语言源程序

V/*LL

(1)分析法源程序,只能在VC++中运行 */

#include

#include

#include

#include

charA[20];/*分析栈*/

charB[20];/*剩余串*/

charv1[20]={'i','+','*','(',')','#'};/*终结符 */

charv2[20]={'E','G','T','S','F'};/*非终结符  */ 

intj=0,b=0,top=0,l;/*L为输入串长度*/ 

typedefstructtype/*产生式类型定义     */

{       charorigin;/*大写字符 */

       chararray[5];/*产生式右边字符*/

       intlength;/*字符个数     */

}type;

 typee,t,g,g1,s,s1,f,f1;/*结构体变量 */

typeC[10][10];/*预测分析表     */ 

voidprint()/*输出分析栈 */

{       inta;/*指针*/

       for(a=0;a<=top+1;a++)

              printf("%c",A[a]);

       printf(""t"t");

}/*print*/ 

voidprint1()/*输出剩余串*/

{       intj;

       for(j=0;j

              printf("");

       for(j=b;j<=l;j++)

              printf("%c",B[j]);

       printf(""t"t"t");

}/*print1*/

voidmain()

{       intm,n,k=0,flag=0,finish=0;

       charch,x;

       typecha;/*用来接受C[m][n]*/

       /*把文法产生式赋值结构体*/

       e.origin='E';

       strcpy(e.array,"TG");

       e.length=2;

       t.origin='T';

       strcpy(t.array,"FS");

       t.length=2;

       g.origin='G';

       strcpy(g.array,"+TG");

       g.length=3;

       g1.origin='G';

       g1.array[0]='^';

       g1.length=1;

   s.origin='S';

       strcpy(s.array,"*FS");

       s.length=3;

       s1.origin='S';

       s1.array[0]='^';

       s1.length=1;

       f.origin='F';

       strcpy(f.array,"(E)");

       f.length=3;

       f1.origin='F';

       f1.array[0]='i';

       f1.length=1;

        for(m=0;m<=4;m++)/*初始化分析表*/

              for(n=0;n<=5;n++)

                      C[m][n].origin='N';/*全部赋为空*/

  /*填充分析表*/

  C[0][0]=e;C[0][3]=e;

  C[1][1]=g;C[1][4]=g1;C[1][5]=g1;

  C[2][0]=t

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

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2