编译原理实验报告.docx
《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
编译原理实验报告
贵州师范大学数学与计算机科学学院
实验报告
课程名称:
编译原理
教师:
张琦
姓名:
班级:
2013级计算机专业本科班
目录
实验任务1:
熟悉概念图软件1
实验任务2:
体会编译器的功能2
实验任务3:
绘制编译原理课程学习概念图3
实验任务4:
正则表达式的使用4
实验任务5:
熟练掌握课程中涉及到的算法5
实验任务6:
编写词法分析程序6
实验任务7:
熟悉YACC的使用方法7
实验任务8:
测试一个完整的编译器前端程序8
实验任务1:
熟悉概念图软件
1.实验目的:
熟悉概念图软件的使用,为绘制课程学习概念图打下基础
2.实验内容:
总结现有的概念图软件的优缺点,选择一款你认为比较优秀的概念图软件,安装并撰写该软件的使用说明书。
3.验收时间:
第4周
1.什么是概念图?
答:
概念图,又被称为概念地图,是用图形化的形式显示概念与概念之间联系的方式。
诺瓦克指出概念图是一种能形象表达命题网络中一系列概念涵义及其关系的结构化图形,它由结点(概念语词)、连概念的线段和标签(连接词)组成,能清楚的表达某一命题中各概念结点间的内在逻辑。
2.介绍概念图有哪些形式?
答:
3.介绍制作概念图的基本步骤
1)打开软件
2)找到下图中的注册之后,点击MM就打开了画图的界面
4.介绍常用概念图软件有哪些?
对比优缺点。
答:
1)MindMapperPro20086.0.0.1826汉化绿色版_可视化的概念图...
2)CmapTools5.04.02多语版_概念图软件-绿色软件联盟
3)概念图软件inspiration-下载频道-CSDN.NET
4)概念图_有关概念图的软件_工具-绿色软件下载站-未来软件园
5)CmapTools5.04.02免费版(概念图制作软件)下载_大众源码网...
6)概念图工具KeystoneConceptMapv3.74-俺下载
我个人觉得1)比较好用,文件小,也是汉化版的,是初学者的最佳选择,更是英语不好的人的选择。
而其他的软件很大,不易懂。
7.选择一款你认为比较优秀的概念图软件,给出概念图
实验任务2:
体会编译器的功能
1.实验目的:
理解编译器的功能
2.实验内容:
例举你所使用过的编译器,并从中选择一个最熟悉的,写出从编写到运行一个应用程序的全过程。
3.验收时间:
第4周
1.实验目的:
理解编译器的功能
答:
编译器,是将便于人编写,阅读,维护的高级计算机语言翻译为计算机能解读、运行的低阶机器语言的程序。
编译器将原始程序(Sourceprogram)作为输入,翻译产生使用目标语言(Targetlanguage)的等价程序。
源代码一般为高阶语言(High-levellanguage),如Pascal、C++、Java等,而目标语言则是汇编语言或目标机器的目标代码(Objectcode),有时也称作机器代码(Machinecode)
2.实验内容:
例举你所使用过的编译器,并从中选择一个最熟悉的,写出从编写到运行一个应用程序的全过程。
答:
目前我学过的编译器主要有visualc++6.0、C#、Masm5.0、6.15,主要操作:
源代码(sourcecode)→预处理器(preprocessor)→编译器(compiler)→汇编程序(assembler)→目标代码(objectcode)→连接器(Linker)→可执行程序(executables)编译是从源代码(通常为高阶语言)到能直接被计算机或虚拟机执行的目标代码(通常为低阶语言或机器语言)的翻译过程。
程序清单如下:
//交换两个数.cpp:
定义控制台应用程序的入口点。
#include"stdafx.h"
#include"iostream"
usingnamespacestd;
classexchange
{
private:
intx,y;
public:
voidex()
{
cout<<"请输入x的值:
"<cin>>x;
cout<<"请输入y的值:
"<cin>>y;
inttemp;
temp=x;
x=y;
y=temp;
cout<<"x="<}
};
exchangeexc
int_tmain()
{exc.ex();
return0;
}
实验任务3:
绘制编译原理课程学习概念图
1.实验目的:
学会利用概念图复制和巩固本课程中所讲授的知识
2.实验内容:
编译原理课程每个章节的内容讲解完之后,根据自己的理解为其绘制学习概念图
3.验收时间:
每章课程结束后一周
3.第一章:
如下图
第三章:
如下图
实验任务4:
正则表达式的使用
1.实验目的:
体会正则表达式的使用
2.实验内容:
设计一个Windows窗体用于填写个人资料,出生日期自动从身份证号码中提取,在提交时检查以下内容:
(检查不合格时弹出消息框提)
1)检查用户名是否由6-18个字符组成,组成用户名的字符只能是英文大小写字母、数字、下划线;
2)检查真实姓名是否由2-4个汉字组成;
3)检查Email格式;
4)检查电话号码是否由11个数字(手机号)或8位数字(固定电话)或区号加固定电话号码组成;
5)检查邮政编码是否由6位数字组成;
6)检查身份证号码是否符合18位数字。
3.实验要求:
实验平台说明,提交源程序代码和实验结果截图
4.验收时间:
第8周
实验平台基于MicrosoftVisualStudio2010官方中文旗舰版的编译器C#语言操作下并用Windows窗体完成的。
1、下图是实验中的重要截图
2、以下是实验代码:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Text.RegularExpressions;
namespacecomplier
{
publicpartialclassForm1:
Form
{
publicForm1()
{
InitializeComponent();
}
privatevoidbutton1_Click(objectsender,EventArgse)
{
if(!
Regex.IsMatch(this.textBox1.Text,@"[a-zA-Z]\d[_]{6,18}"))
{
MessageBox.Show("用®?
户¡ì名?
须?
由®¨¦6到Ì?
18位?
英®¡é文?
大䨮小?
写¡ä字Á?
母?
,ê?
数ºy字Á?
,ê?
下?
划?
线?
组Á¨¦成¨¦!
");
}
else
if(!
Regex.IsMatch(this.textBox2.Text,@"[\u4e00-\u9fa5]{2,4}"))
{
MessageBox.Show("真?
实º¦Ì姓?
名?
须?
由®¨¦2到Ì?
4位?
汉o字Á?
组Á¨¦成¨¦!
");
}
else
if(!
Regex.IsMatch(this.textBox3.Text,@"^(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)"))
{
MessageBox.Show("身¦¨ª份¤Y证¡è有®D误¨®!
");
}
else
if(!
Regex.IsMatch(this.textBox4.Text,@"^(?
=.{8,})(?
=.*[A-Z])(?
=.*[a-z])(?
=.*[0-9])(?
=.*\\W).*$"))
{
MessageBox.Show("密¨¹码?
须?
为a强?
密¨¹码?
!
");
}
else
if(textBox5.Text!
=textBox4.Text)
{
MessageBox.Show("两¢?
次ä?
密¨¹码?
不?
一°?
致?
!
");
}
else
if(!
Regex.IsMatch(this.textBox6.Text,@"^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$"))
{
MessageBox.Show("邮®¨º箱?
格?
式º?
不?
正y确¨¡¤!
");
}
else
if(!
Regex.IsMatch(this.textBox7.Text,@"^((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})$)
"))
{
MessageBox.Show("电Ì?
话¡ã号?
码?
有®D误¨®!
");
}
else
if(!
Regex.IsMatch(this.textBox8.Text,@"^(\d{6})"))
{
MessageBox.Show("邮®¨º编À¨¤应®|为a6位?
数ºy字Á?
!
");
}
}
privatevoidtextBox9_TextChanged(objectsender,EventArgse)
{
try
{
stringbirthday="";
stringsex="";
if(textBox3.Text.Length==18)//处ä|理¤¨ª18位?
的Ì?
身¦¨ª份¤Y证¡è号?
码?
从䨮号?
码?
中D得Ì?
到Ì?
生¦¨²日¨?
和¨ª性?
别Àe代䨲码?
{
birthday=textBox3.Text.Substring(6,4)+"-"+textBox3.Text.Substring(10,2)+"-"+textBox3.Text.Substring(12,2);
sex=textBox3.Text.Substring(14,3);
}
if(textBox3.Text.Length==15)
{
birthday="19"+textBox3.Text.Substring(6,2)+"-"+textBox3.Text.Substring(8,2)+"-"+textBox3.Text.Substring(10,2);
sex=textBox3.Text.Substring(12,3);
}
textBox9.Text=birthday;
}
catch
{
}
return;
}
privatevoidgroupBox1_Enter(objectsender,EventArgse)
{
}
}
}
实验任务5:
熟练掌握课程中涉及到的算法
1.实验目的:
通过为算法绘制流程图达到对算法的深刻理解
2.实验内容:
为课程各章节中出现的核心算法绘制程序流程图
3.验收时间:
每章节完成后1周
3.如图:
实验任务6:
编写词法分析程序
1.实验目的:
体会词法分析程序的工作原理和功能
2.实验内容:
编写一个词法分析程序,实现的功能是:
输入一个C语言程序,经该词法分析程序处理后,输出单词记号序列。
3.实验要求:
提交程序清单(包含注释),提交输入一个C语言程序用词法分析程序处理后的运行结果截图以及运行环境配置说明。
4.验收时间:
第12周
(1)使用环境:
windows下vc++6.0或vs2010(在vs2010里运行需要加#include"stdafx.h"这个头文件而vc++6.0里不要)
)
(2)程序清单:
#include
#include
usingnamespacestd;
#defineMAX22
charch='';
stringkey[15]={"begin","end","if","then","else","while","write","read",
"do","call","const","char","until","procedure","repeat"};
intIskey(stringc){//关键字判断
inti;
for(i=0;iif(key[i].compare(c)==0)return1;
}
return0;
}
intIsLetter(charc){//判断是否为字母
if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A')))return1;
elsereturn0;
}
intIsDigit(charc){//判断是否为数字
if(c>='0'&&c<='9')return1;
elsereturn0;
}
voidanalyse(FILE*fpin){
stringarr="";
while((ch=fgetc(fpin))!
=EOF){
arr="";
if(ch==''||ch=='\t'||ch=='\n'){}
elseif(IsLetter(ch)){
while(IsLetter(ch)||IsDigit(ch)){
if((ch<='Z')&&(ch>='A'))ch=ch+32;
arr=arr+ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
if(Iskey(arr)){cout<elsecout<}
elseif(IsDigit(ch)){
while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin))){
arr=arr+ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
cout<}
elseswitch(ch){
case'+':
case'-':
case'*':
case'=':
case'/':
cout<case'(':
case')':
case'[':
case']':
case';':
case'.':
case',':
case'{':
case'}':
cout<case':
':
{ch=fgetc(fpin);
if(ch=='=')cout<<":
="<<"\t$运算符"<else{cout<<"="<<"\t$运算符"<fseek(fpin,-1L,SEEK_CUR);}
}break;
case'>':
{ch=fgetc(fpin);
if(ch=='=')cout<<">="<<"\t$运算符"<if(ch=='>')cout<<">>"<<"\t$输入控制符"<else{cout<<">"<<"\t$运算符"<fseek(fpin,-1L,SEEK_CUR);}
}break;
case'<':
{ch=fgetc(fpin);
if(ch=='=')cout<<"<="<<"\t$运算符"<elseif(ch=='<')cout<<"<<"<<"\t$输出控制符"<elseif(ch=='>')cout<<"<>"<<"\t$运算符"<else{cout<<"<"<<"\t$运算符"<fseek(fpin,-1L,SEEK_CUR);}
}break;
default:
cout<}
}
}
voidmain(){
charin_fn[30];
FILE*fpin;
cout<<"请输入源文件名(包括路径和后缀名):
";
for(;;){
cin>>in_fn;
if((fpin=fopen(in_fn,"r"))!
=NULL)break;
elsecout<<"文件路径错误!
请输入源文件名(包括路径和后缀名):
";
}
cout<<"\n********************分析如下*********************"<analyse(fpin);
fclose(fpin);
cout<cout<<"按任意键结束"<inta;
cin>>a;
}
(3)截图:
实验任务7:
熟悉YACC的使用方法
1.实验目的:
了解YACC的使用方法
2.实验内容:
借助互联网查找YACC的使用方法,并撰写使用说明手册
3.验收时间:
第16周
1、YACC定义:
yacc是开发编译器的一个有用的工具,采用LALR
(1)语法分析方法。
Yacc最初由AT&T的StevenC.Johnson为Unix操作系统开发,后来一些兼容的程序如BerkeleyYacc,GNUbison,MKSyacc和Abraxasyacc陆续出现。
它们都在原先基础上做了少许改进或者增加,但是基本概念是相同的。
由于所产生的解析器需要词法分析器配合,因此Yacc经常和词法分析器的产生器——一般就是Lex——联合使用。
IEEEPOSIXP1003.2标准定义了Lex和Yacc的功能和需求。
2、YACC使用说明
(1)yacc是一个语法分析程序的自动生成器。
(2)yacc文件构成
说明部分%%
规则部分%%
程序部分%%"%{"与"%}"是说明部分的起始符和与结束符。
终端和非终端符号
终端符号:
代表一类在语法结构上等效的标记。
终端符号有三种类型:
命名标记:
这些由%token标识符来定义。
按照惯例,它们都是大写。
字符标记:
字符常量的写法与C相同。
例如,--就是一个字符标记。
字符串标记:
写法与C的字符串常量相同。
例如,"<<"就是一个字符串标记。
lexer返回命名标记。
非终端符号:
是一组非终端符号和终端符号组成的符号。
按照惯例,它们都是小写。
终端符号的书写方式
%tokentname1tname2...
tname1,tname2都分别表示不同的终端符号。
%tokentname1integer1
integer1表示终端符号tname1的内部编码值。
当选用第一种方式时,当终结符为名字时,其编码值由257开始。
并按先后顺序,增量为1。
文字符号的编号就是其在符号表中的数值。
当按第二种方式时,终结符的编码由用户指定。
(3)union的定义和类型定义
利用union的定义和类型定义,就可以使yacc提供其他类型的返回值。
具体做法是在说明部分给出一个union的定义,使其包括所期望的数据类型。
在类型定义节里,对每个具有这种特殊要求的终结符或者非终结符与union中所定义的成员名进行相互搭配。
%union
{
inttype_type;
charchar_type;
QTREE*tree_type;
}
%typeIS
%typetlist
(4)结合性与优先级
优先级与结合性定义由下面的形式给出
关键字1终结符表1
关键字2终结符表2
其中关键字用来定义跟在它后边的终结符号的结合性
%left定义跟在它后面的终结符为左结合。
%right定义跟在它后面的终结符为右结合。
%nonassoc定义跟在它后面的终结符无结合性。
终结符优先级定义由行序来确定。
1由同一关键字引出的,出现在同一行的终结符具有相同的优先级。
2后行的优先级总是高于前行。
实验任务8:
测试一个完整的编译器前端程序
1.实验目的:
理清编译器前段程序各阶段的程序实现思路
2.实验内容:
将教材394页中给出的一个完整的编译器前端,加以调试和验证
3.实验要求:
提交源程序代码和执行结果评测图
4.验收时间:
第16周