系统软件开发实践实验报告计科4 徐竹.docx

上传人:b****8 文档编号:10895140 上传时间:2023-02-23 格式:DOCX 页数:35 大小:525.73KB
下载 相关 举报
系统软件开发实践实验报告计科4 徐竹.docx_第1页
第1页 / 共35页
系统软件开发实践实验报告计科4 徐竹.docx_第2页
第2页 / 共35页
系统软件开发实践实验报告计科4 徐竹.docx_第3页
第3页 / 共35页
系统软件开发实践实验报告计科4 徐竹.docx_第4页
第4页 / 共35页
系统软件开发实践实验报告计科4 徐竹.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

系统软件开发实践实验报告计科4 徐竹.docx

《系统软件开发实践实验报告计科4 徐竹.docx》由会员分享,可在线阅读,更多相关《系统软件开发实践实验报告计科4 徐竹.docx(35页珍藏版)》请在冰豆网上搜索。

系统软件开发实践实验报告计科4 徐竹.docx

系统软件开发实践实验报告计科4徐竹

中国矿业大学计算机学院

2012级本科生实验报告

 

课程名称系统软件开发实践

报告时间2015/5/1

学生姓名徐竹

学号08123325

专业计算机科学与技术

任课教师刘晋

 

任课教师评语

任课教师评语(①对实验课程基础理论的掌握;②对实验课程知识应用能力的评价;③对课程报告相关实验、作品、软件等成果的评价;④实验课学习态度和上课纪律;⑤实验课程成果和报告工作量;⑥总体评价和成绩;⑦存在问题等):

成绩:

任课教师签字:

年月日

 

实验一(第一周)词法分析器(flex实验)

一、实验目的

1、通过对flex基本知识的阅读,了解其工作原理和过程以及其匹配模式和规则,掌握简单的lex语法和规则;

2、在上述基础上能够自主编写出简单且可以运行的词法分析器,实现简单的词法分析功能;

3、通过实验,设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。

二、实验说明

本次编制调试的词法分析器基本可以实现如下简单功能:

1、可以匹配识别关键字:

elseifswitchforintfloatreturnvoidwhile(所有的关键字都是保留字,并且必须是小写);

2、可以匹配识别专用符号:

+-*/<<=>>===!

==;,()[]{}/**/

3、标识符(ID)和数字(NU)通过下列正则表达式定义:

ID=letterletter*

NUM=digitdigit*

letter=a|..|z|A|..|Z

digit=0|..|9

4、可以匹配识别空格(空格由空白、换行符和制表符组成,空格通常被忽略,,除了它必须分开ID、NUM关键字);

5、可以识别简单的注释(/*注释内容*/);

三、实验原理与分析

词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

词法分析阶段是编译过程的第一个阶段,是编译的基础。

这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。

词法分析是编译程序的第一个阶段且是必要阶段;词法分析的核心任务是扫描、识别单词且对识别出的单词给出定性、定长的处理;实现词法分析程序的常用途径:

自动生成,手工生成。

而本次实验用的是自动生成工具flex,相对于手动生成可以极大地减少工作量。

单词的描述也就是模式(LexicalPattern),模式一般用正规表达式进行精确描述。

FLEX通过读取一个有规定格式的文本文件,输出一个如下所示的C语言源程序。

  |输入文件*.l|------>|flex工具|------>|输出文件lex.yy.c|

FLEX的输入文件为LEX源文件,它内含正规表达式和对相应模式处理的C语言代码。

FLEX通过对.l源文件的扫描自动生成相应的词法分析函数intyylex(),并将之输出到lex.yy.c的文件中。

该文件即为LEX的输出文件或输出的词法分析器。

LEX的源文件由三个部份组成,每个部分之间用顶行的“%%”分割,其格式如下:

定义部份

%%

规则部份 

%%

用户附加C语言部份

其中,定义部分由C语言代码、模式的宏定义、条件模式的开始条件说明三部份组成。

C代码部份由顶行的%{和}%引入,LEX扫描源文件时将%{和}%之间的部分原封不动的拷贝到输出文件lex.yy.c中。

而模式宏定义则是一个正则表达式的定义。

正则表达式的匹配如下:

第二部分规则部份是LEX源文件的核心部份,它包括一组模式和在生成分析器识别相应模式后对相应模式进行处理的C语言动作(Action)。

LEX对第三部分不作任何处理,仅仅将之直接拷贝到输出文件lex.yy.c的尾部。

在些部份,可定义对模式进行处理的C语言函数、主函数和yylex要调用的函数yywrap()等。

如果用户在其它C模块中提供这些函数,用户代码部份可以省略。

yylex()函数被调用之后,它首先检查全局文件指针变量yyin是否有定义,如有,则将之设置为将要扫描的文件指针。

如无,则设置为标准输入文件stdin。

同理,如全局文件指针变量yyout无定义,则将之设置为标准输出文件stdout。

若有多个模式与被扫描文件中的字符串相匹配,则yylex()执行能匹配最长字符串的模式,称为“最长匹配原则”;若还有多个模式匹配长度相同的字符串,则yylex()选择在LEX源文件中排列最前面的模式进行匹配,称为“最先匹配原则”。

yylex()常通过超前搜索一个字符来实现这样的原则,如果使用超前搜索匹配了某一模式,则yylex()在进行下一次分析前,将回退一个字符。

另外,LEX提供控制模式在一定状态下使用的功能,称为条件模式。

LEX首先在定义部份通过%start来定义条件句。

在规则部份可通过宏BEGIN条件名 来激活条件。

BEGIN INITIAL或BEGIN0将休眠所有的条件模式,使分析器回到开始状态。

四、实验步骤和过程分析

1、lex源代码编写

通过前期对flex的了解自主编写了以下简单的的词法分析器,该词法分析器能够实现基本的词法分析功能如行数、关键字个数、单词个数以及简单注释等的判别。

由于功能简单,所以本次代码完全是自己一一在记事本里面编写而成;

digit[0-9]

NUM[digit][digit]*/*此正则表达式用于对数字进行匹配*/

letter[A-Za-z]

ID[letter][letter]*/*此正则表达式是用于对标示符进行模式匹配*/

"else"{num_id++;}

"while"{++num_id;}/*这是实现代对关键字进行匹配*/

"+"|"-"|"*"|"/"|"="|"<"|"<="|">"|">="|"=="|"!

="|";"|","|"("|")"|"["|"]"|"{"|"}"|"/*"|"\*"{fuhao++;}/*这些代码可以用于匹配其它符号*/

[^\t\n]+{nword++;}/*识别单词个数*/

\n{hangshu++;}/*对行数进行识别并统计*/

/*下面再编写一个comment函数用于判断注释*/

comment(){

charc,c1;

loop:

while((c=input())!

='*'&&(c!

=0))

putchar('\n');

if((c1=input())!

='/'&&c!

=0)

{

unput(c1);

gotoloop;

}

if(c!

=0)

putchar('\n');}

intyywrap()

{return1;}

最后将这些代码按照flex语法进行整合得到完整flex源码。

2、通过命令行调试运行得到lex.yy.exe文件;

3、编写测试文件(命名为123.cpp)并与lex.yy.exe放于同一文件夹内;

123.cpp:

#include

usingnamespacestd;

intmain

{

inta=33,b=1123;

c=12;

c=a+b;

cout<<"felx123"<

return0;

}

4、运用命令行的lex.yy.exe<123.cpp运行得到结果:

五、实验小结

本次实验通过对flex基本知识的阅读基本掌握了简单的lex语法和规则,也可以自行设计编制调试一个具体的词法分析程序,不仅加深对了词法分析原理的理解,也初步掌握了在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。

实验二(第二周)语法分析器(bison简单实验)

一、实验目的

1、了解语法分析工具bison的用法和自动生成语法分析器的过程和原理;

2、学习和掌握flex与bison联合编译的思想和方法,能够通过这种方法编译实现基本编译器的构造和设计。

二、实验说明

bison是属于GNU项目的一个语法分析器生成器。

Bison把一个关于“向前查看从左到右最右”(LALR)上下文无关文法的描述转化成可以分析该文法的C或C++程序。

它也可以为二义文法生成“通用的从左到右最右”(GLR)语法分析器。

本次试验主要是学习并利用语法分析器生成工具Bison编写一个语法分析程序,与词法分析器结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子,实验中可以编写一个测试程序,以给定的测试文件作为输入,输出运行结果到输出文件中。

三、实验原理与分析

Bison是一种通用目的的分析器生成器。

它将LALR

(1)上下文无关文法的描述转化成分析该文法的C程序。

使用bison的前提是使用flex事先生成相关词法分析器。

Flex可以识别正则表达式,而bison可以识别语法。

Flex把输入流分解为若干个片段(记号),而bison则可以将这些记号基于逻辑进行合并。

Bison基于我们所给定的语法来生成一个可以识别这个语法中有效语句的语法分析器。

而且bison只处理语法,你需要保证其他部分的完整性。

语法由一系列规则组成,语法分析器就是基于这些规则来识别语法上正确的输入。

Bison的.y文件也是分成三个部分:

1、声明部分:

所有词法单元的定义可以放在此处

2、规则部分:

具体的语法和相应的动作

3、用户自定义部分。

第三部分会被bison原封不动的拷贝进生成的.C文件

当bison读入一个终结符(token),它会将该终结符及其语意值一起压入堆栈。

这个堆栈叫做分析器堆栈(parserstack)。

把一个token压入堆栈通常叫做移进(shifting)。

但堆栈并不是每读入一个终结符就分配一个栈元素给它。

当已经移进的后n个终结符和组(groupings)与一个文法规则相匹配时,它们会被根据那个规则结合起来。

这叫做归约(reduction)。

栈中的那些终结符和组会被单个的组(grouping)替换。

那个组的符号就是那个规则的结果。

执行该规则的相应的动作(Action)也是归约处理的一部分,这个动作会计算这个组的语意值。

分析器通过移进和归约尝试着缩减整个输入到单个的组。

这个组的符号就是文法中的起始符号(start-symbol)。

Bison分析器并不总是在后n个终结符与组匹配某一规则时立即就进行归约。

这种策略对于大部分语言来说并不合适。

相反,当可以进行归约时,分析器有时会“预读”(looksahead)下一个终结符来决定做什么。

当一个终结符被读进来后,并不会立即移进堆栈,而是首先作为一个预读终结符(look-aheadtoken)。

此后,分析器开始对栈上的终结符和组执行一个或多个归约,而预读终结符仍然放在一边。

当没有归约可做时,这个预读终结符才会被移进堆栈。

这并不表示所有可能的归约都已经做了,这要取决于预读终结符的类型,一些规则可能选择推迟它们的使用。

四、实验过程详细分析和步骤

(1)简单bison与flex联合编译实验

1、window下首先将bison安装在与flex安装的相同目录下,编写编写bison文件即.y文件并保存在bison目录下,然后通过调用命令行生成.tab.c和.tab.h文件;

2、编写词法分析文件并将上述的.Tab.h包含在头文件中,然后后调用命令行生成.yy.c文件,利用命令行将.yy.c和.tab.c文件生成为可执行文件exe文件;

3、在命令行里利用生成的exe文件调用测试文件得到结果。

(2)利用语法分析器生成工具Bison编写一个语法分析程序,与词法分析器结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子。

1、编写代码并分别编译flex和bison产生相应文件;

2、comment函数调用yyinput,编译的时候出现了链接错误,将lex.yy.c中的yyinput函数定义拷贝一份到input.lex,重命名为my_yyinput即可解决,另外还要修改生成的cgrammar-new.tab.c文件中的一段代码并删去“if(!

yyin)yyin=stdin”才可以编译通过(解析之前,还要设置yyin为输入文件指针);

3、在命令行里利用生成的exe文件调用测试文件得到结果。

五、实验小结

相对于flex源文件,bison源文件的编写更为艰难,但通过实验了解了flex与bison联合编译的思想和方法,并明白了bison将词法分析阶段的规则进行合并的过程,这些将有助于在接下来的实验中完成简单编译器。

 

实验三(第三周)简单桌面计算器

一、实验说明

使用flex和bison开发了一个具有全部功能的桌面计算器,能够支持变量,过程,循环和条件表达式,使它成为一个虽然短小但是具有现实意义的编译器。

重点学习抽象语法树的用法,它具有强大而简单的数据结构来表示分析结果。

该计算器具体需要实现的功能包括变量命名、实现赋值功能、实现比较表达式(大于、小于、等于等等)、实现if/then/else和do/while的流程控制、用户可以自定义函数;简单的错误恢复机制。

最后编写测试程序时首先自定义两个函数sq和avg,sq函数使用Newton方法来迭代计算平方根;avg函数计算两个数值的平均值。

利用定义好的函数进行计算,得到计算结果并显示出来。

二、实验原理与设计分析

还要分析下,在Bison与Flex联用时,Bison只定义标记的ID。

Flex则需要知道这些词法标记的ID,才能在识别到一个词法标记时返回这个ID给Bison。

Bison传递这些ID给Flex的方法,就是在调用bison命令时使用参数-d。

使用这个参数后,Bison会生成一个独立的头文件,该文件的名称形式为name.tab.h。

在Flex的词法规则文件中,在定义区段里包含这个头文件即可。

在编译器中最强大的数据结构之一就是抽象语语法树。

抽象语法树作为一种通用的中间表示,不仅包含各种语言共有的语法结构,某些特定类型的树节点还可以表示一些语言特有的语法结构。

抽象语法树易于转换成寄存器转移语言,而寄存器转移语言适合在不同平台下进行优化,这使得GCC的两层中间表示具有良好的通用性。

作为一种良好的中间表示,抽象语法树包含了完整的源程序信息。

利用抽象语法树可以实现多种源程序处理工具,比如智能编辑器、源程序浏览器等。

此外,抽象语法树的解析器也可以作为程序静态分析工具的前端,为其提供一种便于分析的输入。

抽象语法树结构比较简单,其对应的词法规则和语法规则易于构造,使用flex和bison工具生成的解析器能够有效地对抽象语法树进行解析。

解析器由三部分组成,分别是flex生成的词法分析器、bison生成的语法分析器和手工编写的驱动程序。

词法分析器识别抽象语法树文件的记号流,提供给语法分析器;语法分析器利用嵌入其中的语义动作识别语法树节点,完成解析任务;驱动程序负责为词法分析器和语法分析器提供一个调用接口,并提供解析所需的数据结构和函数的实现。

在计算器里,factor仅仅是为了告诉语法分析器各个操作符的相对优先级,抽象语法树可以把分析树中的不需要关注的节点移除。

三、实验步骤和设计实现过程分析

本部分主要说明一下计算器的设计过程以及在设计过程中用到的一些重点算法和思想等内容。

1、首先我们要做开始声明部分,在.h头文件中我们可以用以下语句来定义抽象语法树的

structast{intnodetype;structast*l;structast*r;};

节点,且所有节点都有公共的初始nodetype。

而删除和释放抽象语法树可以用语句voidtreefree(structast*)来实现即可。

常量使用numval,符号引用使用symref

赋值使用symasgn,它有一个指向被赋值符号的指针和使用抽象语法树表示的值;

2、语法分析器的设计,其中在语法分析器的最后提供了小部分错误恢复机制,这让我们有可能在错误发生时把语法分析器恢复到可以继续工作的状态;

3、词法分析器中设计六个比较操作符都返回一个带有字面值以便于区分的CMP记号,其中这六个关键字和四个内置函数通过文字模式加以识别,它们放在通用模式之前以便于在通用模式之前进行匹配;

4、最后还要加一个辅助函数,正如《flex与bison》中所讲的一样,例程treefree的扩展版本会递归的遍历一颗抽象语法树并释放这棵树的所有节点。

本计算器的核心例程是eval,它用来计算分析器中构造的抽象语法树。

我们采用深度优先遍历算法来计算表达式的值;

5、完成以上工作后我们就可以在命令行里依次输入指令得到运行结果了:

四、实验小结

使用bison和flex工具学习编译原理,远比单独看书然后自己编写一些程序生动的多。

这样你就不会在那些复杂的字符处理。

但对于初学者来说,完全编译出来本次试验的桌面计算器的编译器还是挺困难的。

因此本次计算器的实现主要还是依靠flex与bison这本书的帮助才得以实现。

本计算器虽然短小但却很具有代表意义。

我们添加了命名的变量和赋值、比较表达式、if和then等的流程控制内置和用户自定义函数以及错误恢复机制等。

实验四(第四周)操作系统实验(Lab0实验)

一、实验目的

1、掌握OS基本概念:

看在线课程,能理解OS原理与概念;看在线实验指导书并分析源码,能理解labcodes_answer的labs运行结果;

2、掌握OS设计实现:

在1的基础上,能够通过编程完成labcodes的8个lab实验中的基本练习和实验报告;

3、本次lab0实验主要是让我们熟悉实验环境以便于后续的实验操作。

二、实验说明

ucore的运行环境可以是真实的X86计算机,不过考虑到调试和开发的方便,我们可采用X86硬件模拟器,比如QEMU、BOCHS、VirtualBox、VMware、Player等。

ucore的开发环境主要是GCC中的gcc、gas、ld和MAKE等工具,也可采用集成了这些工具的IDE开发环境Eclipse-CDT等。

在分析源代码上,可以采用Scitools提供的understand软件(跨平台),windows环境上的source、insight软件,或者基于emacs+ctags,vim+ctags等,都可以比较方便在在一堆文件中查找变量、函数定义、调用/访问关系等。

软件开发的版本管理可以采用GIT、SVN等。

比较文件和目录的不同可发现不同实验中的差异性和进行文件合并操作,可使用meld、kdiff3、UltraCompare等软件。

调试(deubg)实验有助于发现设计中的错误,可采用gdb(配合qemu)等调试工具软件。

并可整个实验的运行环境和开发环境既可以在Linux或Windows中使用。

关于实验环境的配置基本是有五种方式(在线实验--基于"实验楼"在线平台、Windows下基于MingW进行实验、Windows下基于VirtualBoxorVMWare进行实验、在MACOS下进行实验和手动在物理PC中安装环境),我选择的是手动在自己的电脑上上安装ubuntu并在ubuntu系统中安装实验环境相关软件在shell(比如gnome-terminal)下可执行相关命令来安装相关软件。

以下是在自己的笔记本上安装实验环境成功的截图:

Linux文件系统被组织成一个有层次的树形结构。

文件系统的最上层是/,或称为根目录。

在Unix和Linux的设计理念中,一切皆为文件——包括硬盘、分区和可插拔介质。

这就意味着所有其它文件和目录(包括其它硬盘和分区)都位于根目录中。

例如:

/home/jebediah/cheeses.odt给出了正确的完整路径,它指向cheeses.odt文件,而该文件位于jebediah目录下,该目录又位于home目录,最后,home目录又位于根(/)目录下。

了解这些对今后更深一步了解操作系统的结构尤为重要。

使用命令行并不像您想象的那么困难。

使用命令行不需要专门知识,和其它软件一样,它也仅仅是一个程序。

Linux中绝大部分工作都可以用命令行完成,尽管大部分程序都有相应的图形工具,但有时这些图形工具会捉襟见肘,不够用。

此时便是命令行大显身手的时候。

终端常常被称为命令行或者shell。

QEMU是一个通用并开放源代码的模拟器,是一套由FabriceBellard所编写的以GPL许可证分发源码的模拟处理器,在GNU/Linux平台上使用广泛。

其功能相当的强大,例如:

可以用QEMU来模拟一个完整的系统,同时,也可以用QEMU来实现系统源码级的调试:

要想深入理解ucore,就需要了解支撑ucore运行的硬件环境,即了解处理器体系结构(了解硬件对ucore带来影响)和机器指令集。

ucore目前支持的硬件环境是基于Intel80386以上的计算机系统。

80386有四种运行模式:

实模式、保护模式、SMM模式和虚拟8086模式。

这里对涉及ucore的实模式、保护模式做一个简要介绍。

 

实模式:

80386加电启动后处于实模式运行状态,在这种状态下软件可访问的物理内存空间不能超过1MB,且无法发挥Intel 80386以上级别的32位CPU的4GB内存管理能力。

实模式将整个物理内存看成分段的区域,程序代码和数据位于不同区域,操作系统和用户程序并没有区别对待,而且每一个指针都是指向实际的物理地址。

 

保护模式:

实际上,80386就是通过在实模式下初始化控制寄存器,GDTR,LDTR,IDTR与TR等管理寄存器以及页表,然后再通过加载CR0使其中的保护模式使能位置位而进入保护模式的。

当80386工作在保护模式下的时候,其所有的32根地址线都可供寻址,物理寻址空间高达4GB。

在保护模式下,支持内存分页机制,提供了对虚拟内存的良好支持。

保护模式下80386支持多任务,还支持优先级机制,不同的程序可以运行在不同的优先级上。

优先级一共分0~3 4个级别,操作系统运行在最高的优先级0上,应用程序则运行在比较低的级别上;配合良好的检查机制后,既可以在任务间实现数据的安全共享也可以很好地隔离各个任务。

80386是32位的处理器,即可以寻址的物理内存地址空间为2^32=4G字节。

在理解操作系统的过程中,需要用到三个地址空间的概念。

地址是访问地址空间的索引。

物理内存地址空间是处理器提交到总线上用于访问计算机系统中的内存和外设的最终地址。

一个计算机系统中只有一个物理地址空间。

线性地址空间是每个运行的应用程序看到的地址空间,在操作系统的虚存管理之下,每个运行的应用程序都认为自己独享整个计算机系统的地址空间,这样可让多个运行的应用程序之间相互隔离。

处理器负责把线性地址转换成物理地址。

在Ubuntu Linux中的C语言编程主要基于GNU C的语法,通过gcc来编译并生成最终执行文件。

GNU make(简称make)是一种代码维护工具,在大中型项目中,它将根据程序各个模块的更新情况,自动的维护和生成目标代码。

make命令执行时,需要一个 makefile (或Makefile)文件,以告诉make命令需要怎么样的去编译和链接程序。

首先,我们用一个示例来说明makefile的书写规则。

以便给大家一个感兴认识。

这个示例来源于gnu的make使用手册,在这个示例中,我们的工程有8个c文件,和3个头文件,我们要写一个makefile来告诉make命令如何编译和链接这几个文件。

只要我们的makefile写得够好,

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

当前位置:首页 > 工作范文 > 行政公文

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

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