编译原理实验报告.docx
- 文档编号:23259188
- 上传时间:2023-05-15
- 格式:DOCX
- 页数:46
- 大小:392.31KB
编译原理实验报告.docx
《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(46页珍藏版)》请在冰豆网上搜索。
编译原理实验报告
《编译原理》
实
验
报
告
学号:
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','+','*','(',')'构成的以'#'结束的字
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)