当前位置:文档之家› 系统软件开发实践报告

系统软件开发实践报告

计算机科学与技术学院系统软件开发实践报告姓名:王冬升学号:08123228专业:计算机科学与技术班级:计科12-1班指导教师:张博2015年 4月摘要操作系统和编译原理是大学计算机专业的必修课程。

在这些课程的教学教程中,容易偏重于理论的介绍,而忽视了实践环节。

本课程设计是在完成C++程序设计、数据结构、操作系统、编译技术教学后所进行的,全面综合训练学生的系统软件开发能力关键字:编译系统、Flex、Bison、操作系统、启动、内存管理目录1 借助Flex进行词法分析 (2)1.1实验内容 (2)1.2 实验要求 (2)1.3 程序代码 (2)1.4 实验结果 (4)2 借助Flex/Bison进行语法分析 (5)2.1 实验内容 (5)2.2 实验要求 (5)2.3 程序代码 (5)2.4 实验步骤 (5)2.5 实验结果 (7)3 Flex/Bison综合实验 (7)3.1 实验内容 (7)3.2 计算器具体需要实现的功能 (7)3.3 实验要求 (7)3,4 程序代码 (8)3.5 实验结果 (11)4(操作系统实验)lib0:熟悉实验环境 (11)4.1 实验目的 (11)4.2 实验环境搭建 (11)4.3 GCC编译练习 (12)4.4 GDB调试练习 (12)5(操作系统实验)lib1:启动操作系统 (13)5.1 实验目的 (13)5.2 实验内容 (14)5.3 实验步骤 (14)5.4 操作系统启动过程 (15)5.5 实模式与保护模式 (16)6(操作系统实验)lib2:物理内存管理 (16)6.1 实验目的 (16)6.2 实验内容 (16)6.3 ………………………………………………………………7实验体会……………………………………………………………………8参考文献……………………………………………………………………1借助Flex进行词法分析1.1实验内容给定C语言的一个子集,具体内容如下:1. 下面是语言的关键字:else if switch for int float return void while 所有的关键字都是保留字,并且必须是小写。

2. 下面是专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */3. 其他标记是标识符(ID)和数字(NU ),通过下列正则表达式定义:ID = letter letter*NUM = digit digit*letter = a|..|z|A|..|Zdigit = 0|..|9注:小写和大写字母是有区别的。

4. 空格由空白、换行符和制表符组成。

空格通常被忽略,除了它必须分开ID、NUM 关键字。

5. 注释用通常的C语言符号/* . . . */围起来。

注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行。

注释不能嵌套1.2实验要求编写 LEX 源文件,实现C 语言子集的词法分析功能,最后上机调试。

要求编写一个测试程序,以给定的测试文件作为输入,输出运行结果到输出文件中1.3程序代码Lex.l源码:%{#include <stdio.h>#include <stdlib.h>#include <string.h>int yywrap();int lineno=1;%}delim [ \t]ws {delim}+letter [A-Za-z]digit [0-9]id {letter}+number {digit}+enter [ \n]spchar ("{"|"}"|"["|"]"|"("|")"|";"|"="|","|"+"|"-"|"*"|"/"|"<"|"<="|">"|">="|"=="|" !=")comment \/\*(\*[^/]|[^*])*\*\/kwd (else|if|switch|for|int|float|return|void|while)%%{ws} {}{comment} {}{enter} {lineno++;}{kwd} {fprintf(yyout,"%d行\tkeywod\t%s\n",lineno,yytext);}{spchar} {fprintf(yyout,"%d行\tspchar\t%s\n",lineno,yytext);}{id} {fprintf(yyout,"%d行\tidenti\t%s\n",lineno,yytext);}{number} {fprintf(yyout,"%d行\tnumber\t%s\n",lineno,yytext);}.%%int yywrap() {return 1;}int main(void){char in[100];printf("输入文件名:");scanf("%s",in);yyin = fopen(in,"r");yyout = fopen("out","w");yylex();return 0;}测试程序:1-1.cpp#include<iostream>using namespace std;int main() {int a;int d=123456;float b=123.45;int e=9;a=(1+2-1)*4/2;if(a>b)cout<<"a>b"<<endl;else cout<<"a<=b"<<endl;cout<<a<<endl;cout<<b<<endl;cout<<"Welcome to c++"<< endl;return 0;}1.4实验结果实验结果输出到.out文件中,截图示例:2借助Flex/Bison进行语法分析2.1实验内容利用附录提供的C语言文法的相关参考资料,利用Yacc/Bison编写一个C语言分析器。

具体内容:1)利用语法分析器生成工具Bison编写一个语法分析程序,与词法分析器结合能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子2)利用附录提供的C语言文法的相关参考资料,利用Yacc/Bison编写一个C语言分析器。

2.2 实验要求1)编写 Bison源文件,实现C 语言的语法分析功能,最后上机调试。

2)要求编写一个测试程序,以给定的测试文件作为输入,输出运行结果到输出文件中。

2.3程序代码由于本实验的lex源文件和yacc源文件代码较长而且在“实验附录:C语言相关文法”文件夹中已经给出相关源码的链接,由于报告篇幅限制不再贴出源码Test.测试文件源码:void main(){ int i = 0;int j = 0;}void t1(){ int i = 0;}typedef unsigned int uint;uint xx;uint yy;2.4实验步骤1、flex -l input.lexbison -d cgrammar-new.y (产生头文件和.c文件)2、comment函数调用yyinput,编译会有链接错误,解决方法一,将lex.yy.c中的yyinput函数定义拷贝一份到input.lex, 重命名为my_yyinput,或者将lex.yy.c中的#ifdef __cplusplusstatic int yyinput()#elsestatic int input()#endif改为static int yyinput()上述问题出现的情形:词法分析器的后缀名为.c, 而不是.cpp3、cgrammar-new.tab.c中如下程序段/*----------.| yyparse. |`----------*/#ifdef YYPARSE_PARAM# if defined (__STDC__) || defined (__cplusplus)int yyparse (void *YYPARSE_PARAM)# elseint yyparse (YYPARSE_PARAM)void *YYPARSE_PARAM;# endif#else /* ! YYPARSE_PARAM */#if defined (__STDC__) || defined (__cplusplus)intyyparse (void)#elseintyyparse () ;#endif#endif改为int yyparse () 或者 int yyparse (void)4、lex.yy.c中,将下面语句注释if ( ! yyin )yyin = stdin;5、解析之前,设置yyin为输入文件指针extern FILE *yyin;if(!(yyin = fopen(,"r"))) {printf("the exist\n");exit(0);}2.5实验结果实验结果输出到.out文件中,截图示例:3 Flex/Bison综合实验3.1实验内容使用flex和bison开发了一个具有全部功能的桌面计算器,能够支持变量,过程,循环和条件表达式,使它成为一个虽然短小但是具有现实意义的编译器。

重点学习抽象语法树的用法,它具有强大而简单的数据结构来表示分析结果3.2计算器具体需要实现的功能变量命名;实现赋值功能;实现比较表达式(大于、小于、等于等等)实现if/then/else 和do/while的流程控制;用户可以自定义函数;简单的错误恢复机制3.3实验要求编写 Flex/Bison源文件,实现C 语言的语法分析功能,最后上机调试。

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

2)利用定义好的函数进行计算,得到计算结果并显示出来3.4程序代码Cal.l源码%{#include "cal.tab.h"%}%option noyywrapinteger [0-9]+dreal ([0-9]*"."[0-9]+)ereal ([0-9]*"."[0-9]+[EedD][+-]?[0-9]+)real {dreal}|{ereal}nl \nplus "+"minus "-"times "*"divide "/"lp "("rp ")"module "%"power "^"%%[ \t] ; /*skip any blanks */{integer} { sscanf(yytext, "%d", &yylval.integer);return INTEGER;}{real} { sscanf(yytext, "%lf", &yylval.real);/*yylval = atof(yytext); it doesn't work under MSVSC*/return REAL; }{plus} { return PLUS;}{minus} { return MINUS;}{times} { return TIMES;}{divide} { return DIVIDE;}{module} { return MODULE;}{power} { return POWER;}{lp} { return LP;}{rp} { return RP;}{nl} { return NL;}. { return yytext[0];}Cal.y源码%{#include <stdio.h>#include <math.h>%}%union{ double real; /* real value */int integer; /* integer value */}%token <real> REAL%token <integer> INTEGER%start lines%token NUMBER NL%token PLUS MINUS TIMES DIVIDE MODULE POWER LP RP%type <real> rexpr%type <integer> iexpr%left PLUS MINUS /*left associative */%left TIMES DIVIDE MODULE /*left associative */%left POWER%left UNARYMINUS%%lines: /* nothing */| lines line NL| lines error NL{ yyerror();yyerrok; };line : iexpr{printf("%d\n",$1);}| rexpr{printf("%lf\n",$1);} ;iexpr: INTEGER{ $$ = $1; }| iexpr PLUS iexpr{ $$ = $1 + $3;}| iexpr MINUS iexpr{ $$ = $1 - $3;}| iexpr TIMES iexpr{ $$ = $1 * $3;}| iexpr DIVIDE iexpr{ if($3)$$ = $1 / $3;else { $$ = $1;printf (stderr, "%d.%d-%d.%d: division by zero",@3.first_line, @3.first_column,@st_line, @st_column); }} | iexpr MODULE iexpr{ $$ = $1 % $3; }| iexpr POWER iexpr{ $$ = pow($1, $3);}| MINUS iexpr %prec UNARYMINUS{ $$ = - $2;}| LP iexpr RP{ $$ = $2;}| LP iexpr error{ $$ = $2; yyerror("missing ')'"); yyerrok;}| PLUS iexpr %prec UNARYMINUS{ $$ = $2;};rexpr :REAL{ $$ = $1; }| rexpr PLUS rexpr{ $$ = $1 + $3; }| rexpr MINUS rexpr{ $$ = $1 - $3; }| rexpr TIMES rexpr{ $$ = $1 * $3; }{if ($3)$$ = $1 / $3;else{$$ = $1;printf (stderr, "%d.%d-%d.%d: division by zero",@3.first_line, @3.first_column,@st_line, @st_column);} } | rexpr POWER rexpr{ $$ = pow($1,$3); }| LP rexpr RP{ $$ = $2; }| LP rexpr error{ $$ = $2; yyerror("missing ')'"); yyerrok;}| MINUS rexpr %prec UNARYMINUS{ $$ = -$2; }| PLUS rexpr %prec UNARYMINUS{ $$ = $2;}| iexpr PLUS rexpr{ $$ = (double)$1 + $3;}| iexpr MINUS rexpr{ $$ = (double)$1 - $3;}| iexpr TIMES rexpr{ $$ = (double)$1 * $3;}| iexpr DIVIDE rexpr{ if($3) $$ = (double)$1 / $3;else{ $$ = $1;printf (stderr, "%d.%d-%d.%d: division by zero",@3.first_line, @3.first_column,@st_line, @st_column);}} | iexpr POWER rexpr{ $$ = pow((double)$1,$3); }| rexpr PLUS iexpr{ $$ = $1 + (double)$3;}| rexpr MINUS iexpr{ $$ = $1 - (double)$3;}| rexpr TIMES iexpr{ $$ = $1 * (double)$3;}| rexpr DIVIDE iexpr{ if($3)$$ = $1 / (double)$3;else{ $$ = $1;printf (stderr, "%d.%d-%d.%d: division by zero",@3.first_line, @3.first_column,@st_line, @st_column);}}{ $$ = pow($1,(double)$3); };%%void main(){yyparse();}int yyerror(char* msg){printf("Error: %s encountered \n", msg);}3.5实验结果实验结果截图:4(操作系统实验)lib0:熟悉实验环境4.1实验目的1)了解操作系统开发实验环境2)熟悉命令行方式的编译、调试工程3)掌握基于硬件模拟器的调试技术4)熟悉C语言编程和指针的概念5)了解X86汇编语言4.2实验环境搭建1)在线实验--基于"实验楼"在线平台2)Windows下基于MingW进行实验3)Windows下基于VirtualBox or VMWare进行实验4)在MAC OS下进行实验5)手动在物理PC中安装环境4.3 GCC编译练习采用实验环境:在线实验--基于"实验楼"在线平台gcc示例:#include<stdio.h>int main(void){printf("hello!\n");return 0;}在实验环境中右键->从模板创建->空文件,将上述示例代码输入1)保存为hello.c打开命令行,输入以下命令:2)编译:gcc -Wall hello.c -o hello3)执行:./hello操作及结果截图:4.4 GDB调试练习1)输入命令:gcc -o hello hello.c –g进行编译2)输入命令:gdb进入调试3)依次输入以下命令熟悉gdb调试:进入hello文件run:运行hellobreak 1:在第一行插入断点clear 1:清除第一行的断点list :显示hello文件的内容quit:退出gdb调试对应命令执行结果截图:GDB的其它调试命令补充:next :单步到程序源代码的下一行,不进入函数。

相关主题