编译原理实验报告.docx

上传人:b****1 文档编号:23259188 上传时间:2023-05-15 格式:DOCX 页数:46 大小:392.31KB
下载 相关 举报
编译原理实验报告.docx_第1页
第1页 / 共46页
编译原理实验报告.docx_第2页
第2页 / 共46页
编译原理实验报告.docx_第3页
第3页 / 共46页
编译原理实验报告.docx_第4页
第4页 / 共46页
编译原理实验报告.docx_第5页
第5页 / 共46页
点击查看更多>>
下载资源
资源描述

编译原理实验报告.docx

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

编译原理实验报告.docx

编译原理实验报告

《编译原理》

 

学号:

1441901105

姓名:

谢卉

 

实验一词法分析设计

实验学时:

4

实验类型:

综合

实验要求:

必修

一、实验目的

通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。

二、实验内容

用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析。

通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。

以下是实现词法分析设计的主要工作:

(1)从源程序文件中读入字符。

(2)统计行数和列数用于错误单词的定位。

(3)删除空格类字符,包括回车、制表符空格。

(4)按拼写单词,并用(内码,属性)二元式表示。

(属性值——token的机内表示)

(5)如果发现错误则报告出错

(6)根据需要是否填写标识符表供以后各阶段使用。

单词的基本分类:

◆关键字:

由程序语言定义的具有固定意义的标识符。

也称为保留字例如if、for、while、printf;单词种别码为1。

◆标识符:

用以表示各种名字,如变量名、数组名、函数名;

◆常数:

任何数值常数。

如125,1,0.5,3.1416;

◆运算符:

+、-、*、/;

◆关系运算符:

<、<=、=、>、>=、<>;

◆分界符:

;、,、(、)、[、];

三、词法分析实验设计思想及算法

1、主程序设计考虑:

◆程序的说明部分为各种表格和变量安排空间。

在具体实现时,将各类单词设计成结构和长度均相同的形式,较短的关键字后面补空。

k数组------关键字表,每个数组元素存放一个关键字(事先构造好关键字表)。

s数组------存放分界符表(可事先构造好分界符表)。

为了简单起见,分界符、算术运算符和关系运算符都放在s表中(编程时,应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。

id和ci数组分别存放标识符和常数。

instring数组为输入源程序的单词缓存。

outtoken记录为输出内部表示缓存。

还有一些为造表填表设置的变量。

◆主程序开始后,先以人工方式输入关键字,造k表;再输入分界符等造p表。

◆主程序的工作部分设计成便于调试的循环结构。

每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。

例如,把每一单词设计成如下形式:

(type,pointer)

其中type指明单词的种类,例如:

Pointer指向本单词存放处的开始位置。

还有一些为造表填表设置的变量。

◆主程序开始后,先以人工方式输入关键字,造k表;再输入分界符等造p表。

◆主程序的工作部分设计成便于调试的循环结构。

每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。

例如,把每一单词设计成如下形式:

(type,pointer)

其中type指明单词的种类,例如:

Pointer指向本单词存放处的开始位置。

词法分析设计流程图

2、词法分析过程考虑

◆根据输入单词的第一个字符(有时还需读第二个字符),

判断单词类,产生类号:

以字符k表示关键字;id表示标识符;

ci表示常数;s表示分界符。

◆对于标识符和常数,需分别及标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组id中,将常数变为二进制形式存入数组中ci中,并记录其在表中的位置。

lexical过程中嵌有两个小过程:

一个名为getchar,其功能为从instring中按顺序取出一个字符,并将其指针pint加1;另一个名为error,当出现错误时,调用这个过程,输出错误编号。

◆要求:

所有识别出的单词都用两个字节的等长表示,称为内部码。

第一个字节为t,第二个字节为i。

t为单词的种类。

关键字的t=1;分界符的t=2;算术运算符的t=3;关系运算符的t=4;无符号数的t=5;标识符的t=6。

i为该单词在各自表中的指针或内部码值。

表1为关键字表;表2为分界符表;表3为算术运算符的i值;表4为关系运算符的i值。

 

取字符和统计字符行列位置子程序

四、实验要求

1、编程时注意编程风格:

空行的使用、注释的使用、缩进的使用等。

2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。

3、根据测试数据进行测试。

测试实例应包括以下三个部分:

◆全部合法的输入。

◆各种组合的非法输入。

◆由记号组成的句子。

4、词法分析程序设计要求输出形式:

例:

输入VC++语言的实例程序:

Ifi=0thenn++;

a﹤=3b%);

输出形式为:

单词二元序列类型位置(行,列)

(单词种别,单词属性)

for(1,for)关键字(1,1)

i(6,i)标识符(1,2)

=(4,=)关系运算符(1,3)

0(5,0)常数(1,4)

then(1,then)关键字(1,5)

n(6,n)标识符(1,6)

++ErrorError(1,7)

;(2,;)分界符(1,8)

a(6,a)标识符(2,1)

﹤=(4,<=)关系运算符(2,2)

3bErrorError(2,4)

%ErrorError(2,4)

)(2,))分界符(2,5)

;(2,;)分界符(2,6)

五、实验步骤

1、根据流程图编写出各个模块的源程序代码上机调试。

2、编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计的词法分析程序;直至能够得到完全满意的结果。

3、书写实验报告;实验报告正文的内容:

◆功能描述:

该程序具有什么功能?

◆程序结构描述:

函数调用格式、参数含义、返回值描述、函数功能;函数之间的调用关系图。

◆详细的算法描述(程序总体执行流程图)。

◆给出软件的测试方法和测试结果。

◆实验总结(设计的特点、不足、收获及体会)。

六、实验代码

#include"stdafx.h"

#include

#include

#include

usingnamespacestd;

#defineMAX10000

structWordString

{

stringWord;//单词

intcategory;//类别

};

char*key[7]={"int","for","while","do","return","break","continue"};//关键字

WordStringwords[MAX];//创建一个单词符号串

stringtext;//读入的文本存入text中

stringword;//分割出的单词用word表示

intlength;//字符个数

intk;//总单词个数

char*fenhao[1]={";"};

introwx;

introwy;

voidscan()

{

inti,j;

k=0;

word="";

for(i=0;i<=length-1;i++)

{

if(word!

=""){

if(((word[0]>='A')&&(word[0]<='Z'))||((word[0]>='a')&&(word[0]<='z')))//首字符是字母

{

if(((text[i]>='A')&&(text[i]<='Z'))||((text[i]>='a')&&(text[i]<='z'))||((text[i]>=48)&&(text[i]<=57)))

{

word+=text[i];

}

else

{

words[k].Word=word;

for(j=0;j<7;j++)

{

if(words[k].Word==key[j])

{

words[k].category=1;//表示关键字

break;

}

elseif(j==6)

words[k].category=2;//表示标识符

}

k++;

word="";

i--;

}

}

elseif(word[0]==','||word[0]=='{'||word[0]=='}'||word[0]=='('||word[0]==')')//首字符是界限符

{

words[k].Word=word;

words[k].category=5;//表示界限符

k++;

word="";

i--;

}

elseif(word[0]==';')

{

words[k].Word=word;

words[k].category=7;//表示界限符

k++;

word="";

i--;

}

elseif(word[0]=='+'||word[0]=='-'||word[0]=='*'||word[0]=='/'||word[0]=='='||word[0]=='>'||word[0]=='<'||word[0]=='!

')//首字符是运算符

{

if(text[i]=='=')

{

word+=text[i];

words[k].Word=word;

words[k].category=4;//表示运算符

k++;

word="";

}

else

{

words[k].Word=word;

words[k].category=4;//表示运算符

k++;

word="";

i--;

}

}

elseif(word[0]>=48&&word[0]<=57)//首字符是数字

{

if(text[i]>=48&&text[i]<=57)

{

word+=text[i];

}

elseif((text[i]>='A'&&text[i]<='Z')||(text[i]>='a'&&text[i]<='z'))

{

word+=text[i];

words[k].category=6;//表示出错,标识符以数字开头

}

else

{

words[k].Word=word;

if(words[k].category!

=6)

words[k].category=3;//表示常数

k++;

word="";

i--;

}

}

}

else

{

if(text[i]!

=10&&text[i]!

=32&&text[i]!

=9)

{

word+=text[i];

}

}

}

}

 

intmain()

{

introwx=1,rowy=1;

FILE*fp;//文件指针

fp=fopen("F:

//text.txt","r");//打开文件

if(fp==NULL)

{

printf("文件打开错误\n");

exit(0);

}

inti=0;

while(!

feof(fp))//判断是否到文件结尾

{

text+=fgetc(fp);

i++;

}

length=i;//text最后一个字符是空字符

fclose(fp);//关闭文件

scan();

printf("\t—————————词法分析器—————————\n");

printf("\t单词\t\t类型\t\t二元序列\t坐标\n");

for(i=0;i

{

if(words[i].category==1)

{

printf("\t%s\t\t关键字\t\t",words[i].Word.c_str());

printf("(%d,%s)\t",words[i].category,words[i].Word.c_str());

printf("(%d,%d)\n",rowx,rowy);

rowx+=1;

}

if(words[i].category==2)

{

printf("\t%s\t\t标识符\t\t",words[i].Word.c_str());

printf("(%d,%s)\t\t",words[i].category,words[i].Word.c_str());

printf("(%d,%d)\n",rowx,rowy);

rowx+=1;

}

if(words[i].category==3)

{

printf("\t%s\t\t常数\t\t",words[i].Word.c_str());

printf("(%d,%s)\t\t",words[i].category,words[i].Word.c_str());

printf("(%d,%d)\n",rowx,rowy);

rowx+=1;

}

if(words[i].category==4)

{

printf("\t%s\t\t运算符\t\t",words[i].Word.c_str());

printf("(%d,%s)\t\t",words[i].category,words[i].Word.c_str());

printf("(%d,%d)\n",rowx,rowy);

rowx+=1;

}

if(words[i].category==5)

{

printf("\t%s\t\t分界符\t\t",words[i].Word.c_str());

printf("(%d,%s)\t\t",words[i].category,words[i].Word.c_str());

printf("(%d,%d)\n",rowx,rowy);

rowx+=1;

}

if(words[i].category==7)

{

printf("\t%s\t\t分界符\t\t",words[i].Word.c_str());

printf("(%d,%s)\t\t",words[i].category,words[i].Word.c_str());

rowx=1;

rowy+=1;

printf("(%d,%d)\n",rowx,rowy);

}

if(words[i].category==6)

{

printf("\t%s\t\tEorror\t\t",words[i].Word.c_str());

printf("(%d,%d)\n",rowx,rowy);

rowx+=1;

}

}

/*switch(words[i].category)

{

case1:

printf("%s\t关键字\t",words[i].Word.c_str());

printf("(%d,%s)\t",words[i].category,words[i].Word.c_str());

printf("(%d,%d)\n",rowx,rowy);

rowx+=1;

break;

case2:

printf("%s\t标识符\t",words[i].Word.c_str());

printf("(%d,%s)\t",words[i].category,words[i].Word.c_str());

if(word==";")

{

rowy++;

rowx=1;

}

printf("(%d,%d)\n",rowx,rowy);

break;

}*/

getchar();

return0;

}

七、实验结果

 

实验二LL

(1)分析法

实验学时:

2

实验类型:

综合

实验要求:

必修

一、实验目的

通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。

使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。

有利于提高学生的专业素质,为培养适应社会多方面需要的能力。

二、实验内容

◆根据某一文法编制调试LL

(1)分析程序,以便对任意输入的符号串进行分析。

◆构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序。

◆分析法的功能是利用LL

(1)控制程序根据显示栈栈顶内容、向前看符号以及LL

(1)分析表,对输入符号串自上而下的分析过程。

三、LL

(1)分析法实验设计思想及算法

◆模块结构:

(1)定义部分:

定义常量、变量、数据结构。

(2)初始化:

设立LL

(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);

(3)控制部分:

从键盘输入一个表达式符号串;

(4)利用LL

(1)分析算法进行表达式处理:

根据LL

(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

四、实验要求

1、编程时注意编程风格:

空行的使用、注释的使用、缩进的使用等。

2、如果遇到错误的表达式,应输出错误提示信息。

3、对下列文法,用LL

(1)分析法对任意输入的符号串进行分析:

(1)E->TG

(2)G->+TG|—TG

(3)G->ε

(4)T->FS

(5)S->*FS|/FS

(6)S->ε

(7)F->(E)

(8)F->i

输出的格式如下:

五、实验步骤

1、根据流程图编写出各个模块的源程序代码上机调试。

2、编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计的LL

(1)分析程序;直至能够得到完全满意的结果。

3、书写实验报告;实验报告正文的内容:

◆写出LL

(1)分析法的思想及写出符合LL

(1)分析法的文法。

◆程序结构描述:

函数调用格式、参数含义、返回值描述、函数功能;函数之间的调用关系图。

◆详细的算法描述(程序执行流程图)。

◆给出软件的测试方法和测试结果。

◆实验总结(设计的特点、不足、收获及体会)。

六、实验代码

//ConsoleApplication1.cpp:

定义控制台应用程序的入口点。

//

#include"stdafx.h"

#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;C[2][3]=t;

C[3][1]=s1;C[3][2]=s;C[3][4]=C[3][5]=s1;

C[4][0]=f1;C[4][3]=f;

printf("提示:

本程序只能对由'i','+','*','(',')'构成的以'#'结束的字

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

当前位置:首页 > 考试认证 > 交规考试

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

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