程序的编译、运行和调试

程序的编译、运行和调试
程序的编译、运行和调试

2.5 程序的编译、运行和调试(1)

2.5.1 编译和运行

应用程序开发的最后一步就是编译、运行,检查程序错误,并提供用户最终可使用的程序。Delphi 7提供了两种方法对程序进行编译:

(1)使用Project菜单中的Compile命令。该命令编译当前项目中所有修改过的文件(自上次生成执行文件以来),生成可执行的EXE文件。如果使用项目组,且要编译项目组中的所有项目,使用Compile All Projects命令。

(2)使用Project菜单中的Build命令。该命令编译当前项目中的所有文件,生成可执行的EXE文件,而不管这些文件修改没有。如果使用项目组,且要编译项目组中所有项目,使用Build All Projects命令。

Delphi 7编译器在生成EXE文件时,遵循下列规则:

(1)项目文件(.DPR)每次都要被编译。

(2)如果一个单元的源代码自上次编译后修改过,该单元就要再编译。单元编译后,会生成一个带有.DCU扩展名的文件。

(3)如果Delphi不能定位一个单元的源代码,则那个单元不被编译。

(4)如果一个单元的interface(接口)部分被修改,则所有使用到该单元的单元都要被重新编译。

(5)如果一个单元连接了一个OBJ文件,则OBJ文件一旦被修改,该单元也要被编译。(6)如果一个单元包含一个Include文件,则Include文件一旦被修改,该单元也要被修改。为了显示编译进度和结果,可以选择Tools菜单中Environment Options命令,在对话框中选择Preferences选项卡,从中选择Show compile progress(显示编译进度)选项。如图2.21所示。

如果程序编译成功,单击OK按钮,关闭编译对话框。如果遇到错误,Delphi 7在代码编辑器的状态行报告错误,并把光标定位在包含错误代码的程序行上。出错后的窗体界面如图2.22所示。

要运行程序,可以使用Run菜单中的Run命令,或单击加速条上的Run按钮。该命令同样要编译当前项目中自上次生成执行文件以来所有修改过的文件,生成可执行的EXE文件,并运行该程序。

2.5.2 调试

Delphi提供了一个功能强大的Integrated Debugger(内置调试器),因而对程序的调试不用离开集成开发环境就可以进行。

程序错误基本可以分为两类,即运行时错误和逻辑错误。所谓运行时错误是指程序能正常编译但在运行时出错。逻辑错误是指程序设计和实现上的错误,程序语句是合法的,并顺利执行了,但执行结果却不是所希望的。

对于这两类错误,调试器都可以帮助你快速定位错误,并通过对程序运行的跟踪和对变量值的监视帮助你寻找错误的真正原因和解决错误的途径。

程序调试的主要内容可以概括为如下几方面:

(1)准备和开始;

(2)控制程序的执行;

(3)断点的使用;

(4)检查数据的值。

程序调试只有用户实际上机操作才能真正掌握。在这一节中我们主要对调试中的主要问题和一些关键点进行介绍。

1. 调试的准备和开始

在程序开发过程中程序编码和调试是一个持续的循环过程,只有在对程序进行了彻底地测试后才能交付最终用户使用。为了保证调试的彻底性,在调试前应制定一个详细的调试计划。一般说来应该把程序划分为几个相对独立的部分,分别进行调试,以利于错误的迅速定位,确保每一部分程序都按设计的要求运行。

调试计划准备好后就可以开始程序的调试。

在程序调试过程中,程序的执行完全在我们控制之中。可以在任何位置暂停程序的执行检查变量和数据结构的值,显示函数调用序列,修改程序中变量的值以便观察不同值对程序行为的影响。

2. 调试的方法

程序运行控制的方法和使用见表2.6。

表2.6 调试方法列表

“跟踪”和“步进”都是一种单步执行方式,但“步”的含义不同。对“跟踪”而言它一次执行一条简单程序语句,当碰到包含调试信息的函数或过程调用时则跳入该函数或过程,并执行其第一条可执行语句。对“步进”而言,它一次执行一条当前模块的可执行语句,而不管该语句是否是函数或过程调用。

“运行到光标位置”和“运行到断点”都是程序正常运行到某一确定的源代码位置,而后进入调试状态。但相对于“运行到光标位置”而言,“运行到断点”更为灵活。因为断点一次可设置多个,同时也可以对断点设置一定的条件,只有满足该条件程序运行才会中止。

3. 断点的使用

(1)设置断点

首先在Code Editor中选定你想设置断点的代码行,而后进行如下的任一种操作:

1)按F5;

2)单击选定代码行左边的空白;

3)从Breakpoint List右键菜单中选择Add Breakpoint命令;

4)选择代码编辑器窗口中的右键菜单的Toggle Breakpoint命令;

5)选择Run菜单的Add Breakpoint命令,打开Edit Breakpoint Dialog Box(断点编辑对话框),而后选择New命令确认一个新的断点设置,或者选择Modify命令对一个存在的断点进行修改。

断点必须位于可执行代码行上,凡设置在注释、空白行、变量声明上的断点都是无效的。另外,断点既可以在设计状态下设置,也可以在运行调试状态下设置。

(2)Breakpoint List(断点列表)窗口

断点列表窗口列出了所有断点所在的源文件名、行号、条件以及已通过的次数。如果一个断

点非法或失去功能,则在列表窗口中变灰。

断点列表窗口如图2.24所示,可以通过选择View|Debug Windows|Breakpoint命令打开。断点列表窗口是断点操作的基础。

(3)显示和编辑断点处的代码

利用断点列表窗口可以快速找到断点在源代码中的位置。

首先选定断点而后从右键菜单中选择View Source或Edit Source命令。此时Code Editor更新,显示该断点位置处的代码。如果选择的是View Source命令,则断点列表窗口仍保持活动;如果选择的是Edit Source命令,则Code Editor获得输入焦点,可以在断点位置修改源代码。

(4)断点功能的丧失和恢复

使断点失去功能可以使断点从当前程序运行中隐藏起来。假如定义了一个断点,当前并不需要,但可能在以后使用,则这一功能是很有用的。

隐藏断点有以下的方法:

1)选择断点列表窗口右键菜单的Enable命令可以使当前选中断点失去功能。

2)代码行左边的断点标志小圆的右键菜单中的Enable命令可以使相应断点失去功能。

用同样的方法可以恢复断点。

(5)断点的删除

断点删除可以在代码编辑器或断点列表窗口中进行,有以下一些方法可以使用:

1)把光标停到包含断点的行并按F5键。

2)选择右键菜单的Debug子菜单的Toggle Breakpoint命令。

3)单击包含断点行左边的终止符。

4)在断点列表窗口进行时,选中欲删除的断点并选择右键菜单的Delete命令。

其中步骤1)~3)都是在代码编辑器中进行。

6)修改断点属性

在断点列表窗口双击选定断点或从右键菜单中选择Properties命令,可以打开Source Breakpoint Properties对话框,用于显示和修改断点的属性,

利用断点编辑对话框可以改变断点的位置,设置断点条件。

断点条件包括两种:布尔表达式和通过次数。

Condition文本框用于设置布尔表达式条件。如果表达式值为真(或非零)则程序运行在断点处中止;否则调试器将忽略该断点。

Pass count文本框用于设置通过次数条件,即只有当程序运行在该断点处通过设定次数时,程序运行才在该断点处中止。这往往用于对循环体内语句的调试。

有一点应引起注意的是:当Condition和Pass count同时设置时,Pass count是指满足条件的通过次数。

(7)断点和程序执行点颜色的设置

选择Tools菜单,再选择Editor Options命令进入代码编辑器设置对话框,而后选择Color 标签页。此时即可对有关项按自己的希望设置背景和前景色。如图2.26所示:

4. 监视数据的值

(1)监视表达式

Watch List(监视列表)窗口显示程序运行中当前监视表达式的值。

选择View命令,再选择Debug Windows子菜单,再选择Watches命令就可以打开监视列表(Watch List)窗口。如图2.27所示。

从代码编辑器中添加一个监视表达式最方便的方法是:首先在要监视的表达式所在行单击,然后从代码编辑器右键菜单中选择Debug/Add Watch at Cursorwgwy命令把表达式添加到监

视列表窗口。

也可以利用下面的方法产生一个监视表达式:

1)用下列方法之一打开Watch Properties(监视属性)对话框,如图2.28所示。

·从主菜单中选择Run/Add Watch命令。

·在光标处从代码编辑器右键菜单中选择Add Watch命令。

·按Ctrl+F5键。

·双击监视列表窗口中的一个监视表达式。

·从监视列表窗口选定一个表达式而后从右键菜单中选择Edit命令。

2)在监视属性对话框的Expression下拉列表框中输入或选择一个被监视的表达式。

3)设定表达式的显示格式和使用状态。

与断点类似,利用右键菜单也可以使监视表达式功能丧失、恢复或删除监视表达式。

5. 计算/修改表达式

选择Run/Evaluate/Modify命令可打开计算/修改(Evaluate/Modify)对话框,如图2.29所示。当单击Evaluate按钮时,Expression下拉列表框中表达式的值显示在Result域中。Expression下拉列表框中可以输入或选择任何合法的表达式(包括对象的属性),但不包括:·包含有当前执行点不能引用的局部或静态变量的表达式。

·函数或过程调用。

Expression下拉列表框中的表达式可以带特定的格式字符,用于规定其显示格式。格式字符及其功能见表2.7。

表2.7格式字符及其功能

格式字符功能

$,H,X 以十六进制格式显示标量

D 以十进制格式显示标量

C 把ASCII码值在0~31的特殊字等显示为ASCII码图形

Fn 用n个有效数字显示浮点数

M 以十六进制方式显示一变量的内存转储值

P 以段和偏移量格式显示指针。两部分皆为4位十六进制值

R 显示记录、对象的域名和值,例如X:5,Y:2

S 用ASCII码显示字符串(包括特殊字符)。用于修改内存转储值

修改表达式的值常用于验证错误解决方案的正确性。在Expression下拉列表框中输入或选定想修改的表达式,单击Evaluate按钮观察表达式的当前值。而后在New Value下拉列表框中输入或选中一个新值,单击Modify按钮确认并更新数据项。这种修改只影响特定的程序运行。

修改表达式的值(特别是指针变量和数组下标)可能会引

起无法预计的后果,因而使用中要特别小心。

6. 显示函数调用

选择主菜单上的View命令,再选择Debug Windows | Call

Stack命令可以显示调栈(Call Stack)窗口(见图2.30)。

调栈窗口的顶端列出了应用程序最近的函数调用。

利用调栈窗口可以退出当前跟踪的函数,可以利用右键菜

单命令显示或编辑位于特定函数调用处的源代码

编译实验报告+源代码

课程设计报告 ( 2013-- 2014年度第1学期) 名称:编译技术课程设计B 题目:简单编译程序的设计与实现院系:计算机系 班级:XXX 学号:XXX 学生姓名:XXX 指导教师:XXX 设计周数:XXX 成绩: 日期:XX 年XX 月

实验一.词法分析器的设计与实现 一、课程设计(综合实验)的目的与要求 1.1 词法分析器设计的实验目的 本实验是为计算机科学与技术专业的学生在学习《编译技术》课程后,为加深对课堂教学内容的理解,培养解决实际问题能力而设置的实践环节。通过这个实验,使学生应用编译程序设计的原理和技术设计出词法分析器,了解扫描器的组成结构,不同种类单词的识别方法。能使得学生在设计和调试编译程序的能力方面有所提高。为将来设计、分析编译程序打下良好的基础。 1.2 词法分析器设计的实验要求 设计一个扫描器,该扫描器是一个子程序,其输入是源程序字符串,每调用一次识别并输出一个单词符号。为了避免超前搜索,提高运行效率,简化扫描器的设计,假设该程序设计语言中,基本字(也称关键词)不能做一般标识符用,如果基本字、标识符和常数之间没有确定的运算符或界符作间隔,则用空白作间隔。 单词符号及其内部表示如表1-1所示,单词符号中标识符由一个字母后跟多个字母、数字组成,常数由多个十进制数字组成。单词符号的内部表示,即单词的输出形式为二元式:(种别编码,单词的属性值)。 表1-1 单词符号及其内部表示

二、设计(实验)正文 1.词法分析器流程图 2.词法分析器设计程序代码 // first.cpp : 定义控制台应用程序的入口点。// #include"stdafx.h" #include #include using namespace std; int what(char a) { if((int(a)>=48)&&(int(a)<=57)) {

编译原理(PL0编译程序源代码)

/*PL/0编译程序(C语言版) *编译和运行环境: *Visual C++6.0 *WinXP/7 *使用方法: *运行后输入PL/0源程序文件名 *回答是否将虚拟机代码写入文件 *回答是否将符号表写入文件 *执行成功会产生四个文件(词法分析结果.txt符号表.txt虚拟代码.txt源程序和地址.txt) */ #include #include"pl0.h" #include"string" #define stacksize 500//解释执行时使用的栈 int main(){ bool nxtlev[symnum]; printf("请输入源程序文件名:"); scanf("%s",fname); fin=fopen(fname,"r");//以只读方式打开pl0源程序文件 cifa=fopen("词法分析结果.txt","w"); fa1=fopen("源程序和地址.txt","w");//输出源文件及各行对应的首地址 fprintf(fa1,"输入pl0源程序文件名:"); fprintf(fa1,"%s\n",fname); if(fin){ printf("是否将虚拟机代码写入文件?(Y/N)");//是否输出虚拟机代码 scanf("%s",fname); listswitch=(fname[0]=='y'||fname[0]=='Y'); printf("是否将符号表写入文件?(Y/N)");//是否输出符号表scanf("%s",fname); tableswitch=(fname[0]=='y'||fname[0]=='Y'); init();//初始化 err=0; cc=cx=ll=0; ch=' '; if(-1!=getsym()){ fa=fopen("虚拟代码.txt","w"); fas=fopen("符号表.txt","w"); addset(nxtlev,declbegsys,statbegsys,symnum); nxtlev[period]=true; if(-1==block(0,0,nxtlev)){//调用编译程序 fclose(fa); fclose(fa1); fclose(fas); fclose(fin); return 0; } if(sym!=period){ error(9);//结尾丢失了句号 }

linux实验报告3 Linux上C程序编译,调试和工程文件管理

深圳大学实验报告 课程名称:Linux操作系统 实验项目名称:Linux上C程序编译,调试和工程文件管理学院:计算机与软件学院 专业:软件工程 指导教师:冯禹洪 报告人:文成学号:2011150259 班级:02 实验时间:2013/12/31 实验报告提交时间:2013/12/31 教务处制

一、实验目标: 熟悉Linux上C程序设计环境,包括以下内容: 1. 联机帮助man命令 2. 编译工具gcc的使用 3. 熟悉使用gdb来调试程序 4. 熟悉C工程文件的管理工具makefile 二、实验环境与工件 湖边Linux实验室 Fedora 13 三、实验内容与步骤 1.动态库函数可以在多个应用程序之间共享,可以减少应用程序文件的容量和 应用程序的装载时间。因此,熟悉构建动态库可以提高软件的编写质量。请跟随以下步骤构建动态库message,并用其编写程序、编译和运行。(40分) 1.1编写源程序message.c(见图1)和main.c(见图2) 图1. message.c源程序 图2.main.c源程序 1.2用以下命令对message.c进行编译,其中,“-fPIC”选项是告诉gcc产生的 代码不要包含对函数和变量具体内存位置的引用。

1.3以上命令将获得目标文件message.o,使用以下命令建立共享函数库 message: 1.4使用1.3获得的共享函数库来编译main.c文件 1.5设置共享函数库搜索路径 1.6运行程序并附上结果 1.7构建静态可执行程序 1.7.1$gcc –c message.c 1.7.2$ar –crv libmsg.a message.o 1.7.3$gcc –o main main.c –L./ -lmsg 1.7.4$./main 1.8运行以下两个命令并截图说明结果: $ldd goodbye $ldd main $ls –l goodbye main /*附加题:经观察,如果用ubuntu, main 和googbye的大小在一些发行版本下没有区别,如果实验如此,请尝试解释这一现象。附加题目,平时成绩+5分,超过40分不算。*/ 2.图3-4中的reverse程序是有bug的,请使用gdb去观察程序的行为,对关键 行为截图说明,定位错误(截图说明)并修正程序bug。附上修正的程序及其运行结果。(40分) 图3. reverse.h头文件

VC++6.0中如何编译运行及调试C语言程序

VC++6.0中如何编译运行调试C语言程序1.启动VC++6.0 (如下图) 2.单个源文件的编译运行 例如下面的源代码 #include void main() { int i,sum=0; for(i=1;i<=10;i++) { sum=sum+i; } printf("sum=%d\n",sum); }

打开VC++6.0,如图1所示 (图1)选择“文件”→“新建”,打开如图2所示 (图2)

选择“文件”项,如图3所示 (图3) 选择“C++ Source File”项,并在“文件名”项目下输入“sum.c”如图4所示 (图4)

单击“确定”,打开如图5所示 (图5) 输入如上源代码,如图6所示 (图6) 选择按编译按钮调试程序,看看有没有错误,有的话改正,没有的话就可以再按连接按钮检查连接(多文件工程时常用,检查文件间是否正常连接)。

(图7) 在下端的输出窗口会有错误和警告的提示,如果没有错误选择“执行”(或按Ctrl+F5组合键)即可出现运行结果,如图8所示 (图8)

3.多个源文件的编译运行 以上是运行单个源文件的情况,但是在程序设计时,往往是由几个人各自独立编写不同的程序,显然这些程序是不能写在一起进行编译的,这时就需要建立项目工作区来完成几个独立程序的编译,具体方法如下。 首先建立两个文本文件,分别命名为“file1.c”和“file.c”,分别在两个文件中输入如下两个源代码,然后保存。 源代码1: #include void main() { void sum(); sum(); } 源代码2: #include void sum() { int i,sum=0; for(i=1;i<=10;i++) { sum=sum+i; } printf("sum=%d\n",sum); } 打开VC++6.0,选择“文件”→“新建”打开如图9所示

TurboC程序设计的基本步骤及如何编译、调试和运行源程序

Turbo C程序设计的基本步骤及如何编译、调试和运行源程序 本节主要介绍Turbo C程序设计的基本步骤及如何编译、调试和运行源程序。并给出Turbo C的常用编辑命令。最后介绍Turbo C编译、连接和运行时的常见错误。 一、Turbo C程序设计基本步骤 程序设计方法包括三个基本步骤: 第一步:分析问题。 第二步:画出程序的基本轮廓。 第三步:实现该程序。 3a.编写程序 3b.测试和调试程序 3c.提供数据打印结果 下面,我们来说明每一步的具体细节。 第一步:分析问题 在这一步,你必须: a. 作为解决问题的一种方法,确定要产生的数据(输出)。作为这一子步的一部分你应定义表示输出的变量。 b. 确定需产生输出的数据(称为输入),作为这一子步的一部分,你应定义表示输入的变量。 c. 研制一种算法,从有限步的输入中获取输出。这种算法定义为结构化的顺序操作,以便在有限步解决问题。就数字问题而言,这种算法包括获取输出的计 Word文档资料

算,但对非数字问题来说,这种算法包括许多文本和图象处理操作。 第二步:画出程序的基本轮廓 在这一步,你要用一些句子(伪代码)来画出程序的基本轮廓。每个句子对应一个简单的程序操作。对一个简单的程序来说,通过列出程序顺序执行的动作,便可直接产生伪代码。然而,对复杂一些的程序来说,则需要将大致过程有条理地进行组织。对此,应使用自上而下的设计方法。 当使用自上而下的设计方法时,你要把程序分割成几段来完成。列出每段要实现的任务,程序的轮廓也就有了,这称之为主模块。当一项任务列在主模块时,仅用其名加以标识,并未指出该任务将如何完成。这方面的容留给程序设计的下一阶段来讨论。将程序分为几项任务只是对程序的初步设计。整个程序设计归结为下图所示的流程图1. 0 1 1主模块 1 I 1 1 I 输入数据I 1主模块I I计算购房所需的金额I 1 I I计算装修所需的金额I 1任务1I I计算总金额I 1任务2I I输出计算结果I 1任务3I I I 1任务4I 1 ---------------- 1 -------------------- 1 I I I——1II——1II——1II1II——1I 1 ---------------------- 1 I输入数据II购房额?? II装修额..I I总额..I I输出 Word文档资料

(完整word版)PL0源代码(C语言版)

/*PL/0 编译系统C版本头文件pl0.h*/ # define norw 13 //a number of reserved word /*关键字个数*/ # define txmax 100 //length of identifier table /*名字表容量*/ # define nmax 14 //max number of digits in numbers /*number的最大位数*/ # define al 10 //length of identifier /*符号的最大长度*/ # define amax 2047 //maximum address /*地址上界*/ # define levmax 3 //max depth of block nesting /*最大允许过程嵌套声明层数[0,lexmax]*/ # define cxmax 200 //size of code array /*最多的虚拟机代码数*/ /*符号*/ enum symbol{ nul, ident, number, plus, minus, times, slash, oddsym, eql, neq, //slash斜线 lss, leq, gtr, geq, lparen, //leq :less than or equal to; gtr: great than;lparen:left parenthesis rparen, comma, semicolon,period, becomes,//comma逗号semicolon分号period句号becomes赋值号 beginsym, endsym, ifsym, thensym, whilesym, writesym, readsym, dosym, callsym, constsym, varsym, procsym, }; #define symnum 32 /*-------------*/ enum object{ //object为三种标识符的类型 constant, variable, procedur, }; /*--------------*/ enum fct{ //fct类型分别标识类PCODE的各条指令 lit, opr, lod, sto, cal, inte, jmp, jpc, //书本P23 }; #define fctnum 8 /*--------------*/ struct instruction //指令 { enum fct f; //功能码 int l; //层次差 int a; //P23 }; FILE * fas; //输出名字表

交叉编译与调试!!!

交叉编译与调试方法 一、交叉编译 1. 建立工作目录 2. 编写源代码 3. 编写makefile文件 4. 编译应用程序 #arm-linux-gcc -g hello.c -o hello 5. 启动NSF,挂载共享文件目录 将光盘中的gdbserver与gdb程序拷贝到共享目录 二、调试步骤 1、在Target Board开启gdbserver 进入共享目录 #gdbserver :2345 hello (我的host-ip是192.168.0.178) gdbserver开始监听2345端口(你也可以设其他的值),然后启动hello,你会看到“Process test created:pid=88” 2、回到Host端 添加环境变量 #export PATH=$PATH:/home/cby/arm-gdb/bin(arm-linux-gdb的路径) 调试 #arm-linux-gdb hello 最后一行显示:This GDB was configured as “--host=i686-pc-linux-gnu,--target =arm-linux”... 说明此gdb在X86的Host上运行,但是调试目标是ARM代码。 (gdb)target remote :2345 (我的target-board-ip is 192.168.0.105) 注意:你的端口号必须与gdbserver开启的端口号一致,这样才能进行通信。 建立链接后,就可以进行调试了。调试在Host端,跟gdb调试方法相同。

注意的是要用“c”来执行命令,不能用“r”。因为程序已经在Target Board上面由gdbserver 启动了。结果输出是在Target Board端,用超级终端查看。 4. 交叉调试 (gdb)list (gdb)break func (gdb)break 22 (gdb)info br (gdb)c (这里不能用run) (gdb) n (gdb) p result (gdb) finish (跳出func 函数) (gdb) next (gdb) quit 建立连接后进行gdb 远程调试和gdb 本地调试方法相同

编译原理实验 简单词法分析(含源代码和实验结果)

附录一实验报告样式 《编译原理》实验报告 实验2 简单词法分析 姓名陈婷婷学号1009050121 班级计科1001班 时间:2012/4/5 地点:文波 同组人:无 指导教师:朱少林 实验目的 通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解;提高词法分析方法的实践能力。掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法;掌握词法分析的实现方法;上机调试编出的词法分析程序。 实验内容 ⑴掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。 ⑵掌握词法分析的实现方法。 ⑶上机调试编出的词法分析程序。 ⑷为简单起见,假设编译语言为具有下特征的C_minus。该词法分析器要求至少能够识别C_minus中的以下几类单词: a.关键字:else if int return void while共6个,所有的关键字都是保留字,并且必须是小写; b.标识符:识别与C语言词法规定相一致的标识符,通过下列正则表达式定义:ID = letter (letter | digit)*; c.常数:NUM=(+ | - |ε)digit digit*(.digit digit* |ε)(e(+ | - |ε) digit digit* |ε),letter = a|..|z|A|..|Z|,digit = 0|..|9,包括整数,如123, -123, +123等;小数,如123.45, +123.45, -123.45;科学计数法表示的常数,如+1.23e3,-2.3e-9; d.专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */;

C源程序调试方法

C源程序调试方法: 所谓源程序调试是指对程序的查错和排错,一般应经过以下几个步骤: 1进行静态检查 写好一个程序后,不要匆忙用编译器编译,应对写好的源程序进行人工检查,这一步是十分重要的,它能发现程序设计人员由于疏忽而造成的大多错误。为了减少编程错误,在编写程序中应力求做到以下几点: ①应当采用结构化程序方法编程,以增加可读性。 ②应尽可能多加注释,以帮助理解每段程序的作用。 ③在编写复杂的程序时,不要将全部的语句都写在main函数中,而要多利 用函数,用一个函数来实现单独的功能,既易于阅读也便于调试。各函数之间除了用参数传递数据这一渠道外,能够不用其他的渠道就尽量不用,数据间应尽量减少耦合的关系。 2、上机动态检查调试, 根据编译器提示的语法错误,提出编译器提示的全部错误(error)并一一改正,直到通过编译,生成下载文件或调试文件,还应该仔细检查编译器的警告(warning)信息,确认所有的警告信息并不会影响编译结果的正确性。有时,编译器的错误提示并非正确,而且出错的情况繁多且各种错误相互关联,因此要善于分析,找出真正的错误。 3、 Studio环境中进行硬件仿真或软件仿真。 测试的目的是为了测试软硬件能否在各处复杂的情况下正常工作,在测试时应当尽可能地将程序流程中的各分支和各种极限情况都测试一次,程序运行结果不对,大多属于逻辑错误,应将源程序与流程图仔细对照,是很容易发现错误的。 软件思想:本系统主要是用Mega 16主控单片机,控制液晶显示,输入键盘和电机的运行,Mega 16单片机根据键盘输入指令,运行相应的程序。当选择学习示教程序时,就是运用键盘控制电机的运行,然后记录电机运行的相关速度和最终的坐标到相应的寄存器,并在液晶显示器中显示学习示教程序运行状态,使用户更好的进行电机设置和了解电机的运行状态。

第2章 PL0编译程序的实现 完整课后习题答案+吕映芝编

第2章 PL/0编译程序的实现 第1题 PL/0语言允许过程嵌套定义和递归调用,试问它的编译程序如何解决运行时的存储管理。 答案: PL/0语言允许过程嵌套定义和递归调用,它的编译程序在运行时采用了栈式动态存储管理。(数组CODE存放的只读目标程序,它在运行时不改变。)运行时的数据区S是由解释程序定义的一维整型数组,解释执行时对数据空间S的管理遵循后进先出规则,当每个过程(包括主程序)被调用时,才分配数据空间,退出过程时,则所分配的数据空间被释放。应用动态链和静态链的方式分别解决递归调用和非局部变量的引用问题。 第2题 若PL/0编译程序运行时的存储分配策略采用栈式动态分配,并用动态链和静态链的方式分别解决递归调用和非局部变量的引用问题,试写出下列程序执行到赋值语句b∶=10时运行栈的布局示意图。 var x,y; procedure p; var a; procedure q; var b; begin (q) b∶=10; end (q); procedure s; var c,d; procedure r; var e,f; begin (r) call q; end (r); begin (s) call r; end (s); begin (p) call s;

end (p); begin (main) call p; end (main). 答案: 程序执行到赋值语句b∶=10时运行栈的布局示意图为: 第3题 写出题2中当程序编译到r的过程体时的名字表table的内容。 size name kind level/val adr 答案: 题2中当程序编译到r的过程体时的名字表table的内容为: name kind level/val adr size x variable 0 dx y variable 0 dx+1 p procedure 0 过程p的入口(待填) 5

编译原理实验-查填符号表(含源代码和运行结果)

《编译原理》实验报告 实验1 查填符号表 姓名学号班级计科1001班 时间:2012/3/22 地点:文波 同组人:无 指导教师:朱少林 实验目的 1、运用所学知识,选择语言、选择算法(数据结构),编程实现符号表管理程序。 2、熟悉编译过程,训练编写程序的能力,为后续实验积累经验。 实验内容 1、运用所学知识,编程实现符号表管理程序。读出源程序中与C语言词法规定相一致的标识符,并在符号表中进行查找,若存在则输出该标识符及其编号和位置;否则将其填入符号表,并分配编号,确定位置,输出该标识符。 2、输出标识符表。 实验环境 软件:VC++6.0 实验前准备 1、方案设计: ①准备模拟数据:由于是识别符合c语言规定的标识符,故本实验中使用“测试文件.c” ②写出c语言标识符的正规式定义:letter_→A|B|C|…Z|a|b|…z|_ digit→0|1|…9 id→letter_(letter_|digit)* ③画出不确定的有限自动机 不确定的有限自动机如下:

进行化简: A={1} B={2,3,4,5,9} C={3,4,5,6,8,9} D={3,4,5,7,8,9} 状态letter_ digit A B B C D C C D D C D 进行化简:{A} {B,C,D} 化简后的确定有限自动机如下: ④程序思想:该实验重点是构造识别标识符的函数。程序中,使用的数据结构如下: struct record { char name[20]; }; typedef struct record RECORD; record是用来记录标识符的名字,并且规定标识符的长度最大为20

实验二 简单程序的编译、链接、调试

实验二简单程序的编译、链接、调试 一、实验目的 1.熟悉GNU gcc 编译器的使用方法和常用的编译选项 2.熟悉gdb 调试器的各个命令,学习如何有效的调试程序 二、实验内容 1.使用vi 编辑器编写一个简单程序,输出“hello,world!”字符串; 2.用gcc编译器编译所写的程序,练习编译器各个参数的用法; 3.用ld连接器把程序连接成可执行程序,练习连接器各个参数的用法; 4.学习用gdb调试器调试程序,练习使用断点来跟踪程序的运行,查看变量的值或地址,查看寄存器的内容,练习的调试器的各个常用命令; 三、实验指导与步骤 1. 登录Linux,在终端控制台提示符下键入vi启动编辑器(或键入startx启动X Window,通过程序组启动vi编辑器);也可以使用Gedit 编辑器; 2. 新建一个文件,将文件保存到您的HOME目录,文件扩展名取为*.c,vi编辑器 的编辑格式将自动转换成C格式; 3. 按实验内容要求,编写源代码,将代码输入刚刚新建的文件,保存; 4. 在提示符下键入cd $HOME,看看您的主目录是什么;再键入ls 命令查看有没有 你新建的文件; 5. 在提示符下键入gcc –h,查看gcc编译器的帮助信息; 6. 键入gcc -c –Wall hello.c;如果编译不通过,要理解这些错误,并改正过来;警告 一般无关紧要,但也要重视,警告也可能造成运行时错误;常见编译错误一般有:函数找不到原型,符号不能解释(可能没有定义或没有包含必要的头文件),语法错误:“””,“’”,“}”“)”,“;”等边界符不匹配,函数调用的参数类型不匹配或参数个数不对等等; 6. 如果编译成功,再键入ls命令查看生成了什么文件; 7. 在提示符下键入ld –h,查看ld 连接器的帮助信息。目标文件(*.o) 一般不用单独 连接,所以ld 连接器一般也不单独调用。如果源代码没有任何错误,gcc不带任何编译选项,就可以把源代码编译、连接成可执行程序; 8. 键入gcc –g hello.c –o hello_g,-g选项保证编译后的程序中包含了大量标准调试信 息,以方便调试过程;-o选项指定了输出文件名,如果不指定文件名,默认的输出文件名就是a.out。 9. 键入gdb hello_g,,调试你的程序。主要练习查看变量或寄存器的值,设置断点、 单步跟踪程序运行。 四、实验报告要求 1.实验目的 2.实验内容 gcc编译器、ld连接器的常用选项及基本功能;练习单独调用ld连接器;gdb调试器的基本命令及功能。 3.实验详细步骤 画出从编辑源代码到调试成功的整个过程图;记录自己实际完成的步骤,实验过程中所碰到的难题以及你解决问题的步骤和方法;记录编译程序时编译器报告的错误、解释错误意义和改正方法;记录调试过程调试器报告的错误、解释错误意义和

编译原理PL0编译程序的实现1(希赛教育基础学院)

◇第二章PL/0编译程序的实现 【课前思考】 复习第1章介绍的一个高级程序设计语言编译程序的功能和实现的步骤。编译程序就是一个语言的翻译程序,通常是把一种高级程序设计语言(称源语言)书写的程序翻译成另一种等价功能语言(称目标语言)的程序。换句话说,编译是指把一种用源语言表示的算法转换到另一种等价的用目标语言表示的算法。编译程序实现的必要步骤有词法、语法、语义分析和代码生成。此外必需有符号表管理程序和出错处理程序。本章介绍的PL/0编译程序的实现是用PASCAL语言书写的。 【学习目标】 本章目的:以PL/0语言编译程序为实例,学习编译程序实现的基本步骤和相关技术,对编译程序的构造和实现得到一些感性认识和建立起整体概念,为后面的原理学习打下基础。 ◇了解并掌握用语法图和扩充的巴科斯-瑙尔范式(EBNF)对PL/0语言的形式描述。 ◇了解并掌握PL/0语言编译程序构造和实现的基本技术和步骤。 ◇了解并掌握PL/0语言编译程序的目标程序在运行时数据空间的组织管理。 【学习指南】 ◇要求读者阅读PL/0语言编译程序文本,了解一个编译程序构造的必要步骤和实现技术。一个编译程序的实现比较复杂,读懂一个典型的程序从设计思想到实现技术也有一定难度,特别是入门开始需要耐心。一但读懂,不仅了解编译程序的实现方法和技术,还可学到许多编程技巧和好的编程风格。 ◇阅读PL/0语言编译程序文本时,应从整体结构开始逐步细化,弄清楚每个过程的功能和实现方法及过程之间的相互关系。 ◇建议用一个PL/0源程序的例子为导引作为阅读PL/0语言编译程序文本的入门,然后再逐步全面读懂。 ◇通过对PL/0语言编译程序某些指定功能的扩充,加深对编译程序构造步骤和实现技术的理解,并能在实践中应用。 【难重点】 重点: ◇弄清源语言(PL/0)目标语言(类pcode)实现语言(pascal) 这3个语言之间的关系和作用。 ◇掌握用语法图和扩充的巴科斯-瑙尔范式(EBNF)对一个高级程序设计语言的形式描述。 ◇了解PL/0语言编译程序的语法分析技术采用的是自顶向下递归子程序法。 ◇掌握PL/0语言编译程序的整体结构和实现步骤,并弄清词法分析、语法分析、语义分析、代码生成及符号表管理每个过程的功能和相互联系。 ◇掌握PL/0语言编译程序的目标程序在运行时采用栈式动态存储管理的实现技术。 难点: ◇符号表管理起着编译期间和目标程序运行时信息联系的纽带,符号表的建立并不困难,但信息之间的关系往往需要反复学习才能理解。 【知识结构】

编译原理PL0报告(附源码教程)

编译原理课程设计 学院计算机学院 专业计算机科学与技术班级 学号 姓名 指导教师 20 年月日

一、课程设计要求 基本内容(成绩范围:“中”、“及格”或“不及格”) (1)扩充赋值运算:*= 和/= 扩充语句(Pascal的FOR语句): ①FOR <变量>:=<表达式> TO <表达式> DO <语句> ②FOR <变量>:=<表达式> DOWNTO <表达式> DO <语句> 其中,语句①的循环变量的步长为2, 语句②的循环变量的步长为-2。 (3)增加运算:++ 和--。 选做内容(成绩评定范围扩大到:“优”和“良”) (1)增加类型:①字符类型;②实数类型。(2)扩充函数:①有返回值和返回语句;②有参数函数。(3)增加一维数组类型(可增加指令)。 (4)其他典型语言设施。 二、概述 目标:实现PL0某些特定语句 实现语言:C语言 实现工具平台:VS201 运行平台:WIN7 三、结构设计说明与功能块描述 PL/0编译程序的结构图

PL/0编译程序的总体流程图 四、主要成分描述 1、符号表 编译程序里用了一个枚举类型enum symbol,然后定义了enum symbol sym来存放当前

的符号,前面讲过,主程序定义了一个以字符为元素的一维数组word,称保留字表,这个保留字表也存放在符号表里,为了识别当前的符号是属于哪些保留字;还有标识符,拼数,拼符合词等的符号名都存放在符号表里,当sym存放当前的符号时,我们可以判断它是属于哪类的符号,然后加以处理。 在运行的过程中,主程序中又定义了一个名字表,也就是符号表,来专门存放变量、常量和过程名的各个属性,里面的属性包括name,kind,val/level,adr,size,我们来举一个PL/0语言过程说明部分的片段: Const a=35,b=49; Var c,d,e; Procedure p; Var g; 当遇到标识符的引用时就调用position函数,根据当前sym的符号类型来查table表,看是否有过正确的定义,若已有,则从表中取相应的有关信息,供代码的生成用。若无定义则调用出错处理程序。 2、运行时存储组织和管理 对于源程序的每一个过程(包括主程序),在被调用时,首先在数据段中开辟三个空间,存放静态链SL、动态链DL和返回地址RA。静态链记录了定义该过程的直接外过程(或主程序)运行时最新数据段的基地址。动态链记录调用该过程前正在运行的过程的数据段基址。返回地址记录了调用该过程时程序运行的断点位置。对于主程序来说,SL、DL和RA的值均置为0。静态链的功能是在一个子过程要引用它的直接或间接父过程(这里的父过程是按定义过程时的嵌套情况来定的,而不是按执行时的调用顺序定的)的变量时,可以通过静态链,跳过个数为层差的数据段,找到包含要引用的变量所在的数据段基址,然后通过偏移地址访问它。

PL0编译程序设计说明书

PL/0编译程序设计说明书 小组组长:李文(00000000) 小组成员:******(00000000) ******(00000000) ******(00000000) ******(00000000) 2006年1月16日

1引言 (3) 1.1编写目的 (3) 1.2背景 (3) 1.3定义 (3) 1.4参考资料 (5) 2总体设计 (5) 2.1需求规定 (5) 2.2运行环境 (6) 2.3模块流程 (6) 2.4模块机理说明 (7) 2.5模块设计与实现 (10) 2.6人工处理过程 (12) 2.7程序的亮点 (13) 2.8尚未问决的问题 (13) 3程序介绍和使用说明 (13) 4程序测试结果分析 (16)

概要设计说明书 1引言 1.1编写目的 此文档为VK 1.0版PL/0编译器详细设计说明书,旨在说明该编译器的设计思想和实现。此说明书可以在阅读本编译器代码时有效地帮助您理解本编译器的设计方法和实现过程,希望能提供给您所需的帮助。 1.2背景 名称:VK1.0版PL/0编译器 说明: 此编译器为北京师范大学信息科学学院计算机科学与技术系2003级2005-2006学年度第一学期编译原理课程实验作业。 本软件由李文小组合作开发,组长李文,同组人员有吕叶、刘晟忻、肖纯、曲文星。 本软件主要用于PL/0程序的编译,软件提供生成中间代码,并执行检测。本软件为开源软件,故除了用于编译以外还可给编译器开发者提供开发参考。 本软件开发运行在Windows 32位平台上,尚未开发其他平台版本。 1.3定义 本软件开发中,用到了一些PL/0语言和PCODE的定义以及编译原理术语,下面给予说明。 ●PL/0语言: ?BNF范式: 〈程序〉∷=〈分程序〉. 〈分程序〉∷=[〈常量说明部分〉][〈变量说明部分〉][〈过程说明部分〉]〈语 句〉 〈常量说明部分〉∷=CONST〈常量定义〉 {,〈常量定义〉}; 〈常量定义〉∷=〈标识符〉=〈无符号整数〉 〈无符号整数〉∷=〈数字〉{〈数字〉} 〈变量说明部分〉∷=VAR〈标识符〉{,〈标识符〉}; 〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉} 〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉}; 〈过程首部〉∷=PROCEDURE〈标识符〉; 〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈当型循环语句〉|〈过程调用语句〉| 〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉; 〈赋值语句〉∷=〈标识符〉∶=〈表达式〉

实验一 PL0编译程序

编译原理上机实验一 1.软件准备 (1)、pl/0编译程序:pl0 .exe (2)、pl/0编译程序源代码程序(PASCAL程序):pl0.pas (或pl0pl0.pas) (3)、pl/0程序实例(文本文件): text.pl0, text1.pl0, test2.pl0, … text9.pl0共10个例子 2.实验要求: (1)阅读pl/0源程序实例(text.pl0,test1.pl0,………text9.pl0共10个例子)理解每个PL0程序的功能;熟悉并掌握pl/0语言相关规则。 (2)用pl/0编译程序,对提供的10个例子逐一进行编译并运行。熟悉pl/0编译程序使用操作方法。通过理解每个实例程序的功能,编程思想, 进一步理解PL/0语言的语法及其语义;提高阅读程序的能力,应用 程序设计语言的编程能力;增强程序语言语法、语义意识。 (3)用pl/0语言编写以下程序,进一步熟悉PL/0语言: a、由三角形的三条边长计算三角形面积。 b、编写一个PL0过程,计算以a为直径的圆的面积。用主程序确定圆 的直径,输出计算结果。 c、编写递归程序,计算n!。 d、计算1000之内的所有素数,并输出结果。求出1000之内所有素数之 和。(要求编写3个以上的pl/0过程实现) 3.文件(软件)使用说明 (1)、打开文件目录“PL0编译…”,运行PL/0编译程序(pl0.exe),按提示要求输入PL0源程序文件名(如test1.pl0),┉ (2)、打开Fa2.txt文件,可看到当前经过编译并运行后的pl/0程序的目标代码及其执行结果。 (3)、打开out1.txt或out2.txt、┉或out9.txt文件,可看到各个pl/0程序实例的编译、运行、操作过程结果。 4.提交实验报告及要求 (1)、简述test4.pl0 …test7.pl0各程序语法含义,执行结果。 (2)、提交实验要求编写的4个PL/0源程序及其执行结果。 (3)、简写本次实验的收获与体会。

ANDROID 源码编译 流程

Android源码编译调试流程 by mengke 1编译流程 sudo apt-get install build-essential sudo apt-get install make sudo apt-get install gcc sudo apt-get install g++ sudo apt-get install libc6-dev sudo apt-get install patch sudo apt-get install texinfo sudo apt-get install libncurses-dev sudo apt-get install git-core gnupg sudo apt-get install flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl sudo apt-get install ncurses-dev sudo apt-get install zlib1g-dev sudo apt-get install valgrind sudo apt-get install python2.5 安装java环境 sudo apt-get install sun-java6-jre sun-java6-plugin sun-java6-fonts sun-java6-jdk sudo apt-get install sun-java5-jdk(ubuntu910估计会有一些问题) (注:官方文档说如果用sun-java6-jdk可出问题,得要用sun-java5-jdk。经测试发现,如果仅仅make(make不包括make sdk),用sun-java6-jdk是没有问题的。而make sdk,就会有问题,严格来说是在make doc出问题,它需要的javadoc版本为1.5。 因此,我们安装完sun-java6-jdk后最好再安装sun-java5-jdk,或者只安装sun-java5-jdk。这里sun-java6-jdk和sun-java5-jdk都安装,并只修改javadoc.1.gz和javadoc。因为只有这两个是make sdk用到的。这样的话,除了javadoc工具是用1.5版本,其它均用1.6版本: sudo apt-get install sun-java5-jdk) cd/etc/alternatives sudo rm javadoc.1.gz sudo ln-s/usr/lib/jvm/java-1.5.0-sun/man/man1/javadoc.1.gz javadoc.1.gz sudo rm javadoc sudo ln-s/usr/lib/jvm/java-1.5.0-sun/bin/javadoc javadoc 假设源代码的目录为mydroid root@mk-desktop:~/mydroid#ls Makefile build development frameworks out sdk bionic cts device hardware packages system bootable dalvik external ndk prebuilt vendor

PL0+语言编译器分析实验

编译原理实验报告 课题名称:PL/0 语言编译器分析实验 学院: 专业: 姓名: 学号: 指导老师: 完成时间:

一、实验目的 通过阅读与解析一个实际编译器(PL/0语言编译器)的源代码,加深对编译阶段(包括词法分析、语法分析、语义分析、中间代码生成等)和编译系统软件结构的理解,并达到提高学生学习兴趣的目的。 二、实验要求 (1)要求掌握基本的程序设计技巧(C语言)和阅读较大规模程序源代码的能力; (2)理解并掌握编译过程的逻辑阶段及各逻辑阶段的功能; (3)要求能把握整个系统(PL/0语言编译器)的体系结构,各功能模块的功能,各模块之间的接口; (4)要求能总结出实现编译过程各逻辑阶段功能采用的具体算法与技术。 三、实验原理

四、实验报告 pl/0语言是pascal语言的一个子集,我们这里分析的pl/0的编译程序包括了对pl/0语言源程序进行分析处理、编译生成类pcode代码,并在虚拟机上解释运行生成的类pcode代码的功能。 pl/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。词法分析和代码生成作为独立的子程序供语法分析程序调用。语法分析的同时,提供了出

错报告和出错恢复的功能。在源程序没有错误编译通过的情况下,调用类pcode 解释程序解释执行生成的类pcode代码。 词法分析子程序分析: 词法分析子程序名为getsym,功能是从源程序中读出一个单词符号(token),把它的信息放入全局变量sym、id和num中,语法分析器需要单词时,直接从这三个变量中获得。(注意!语法分析器每次用完这三个变量的值就立即调用getsym 子程序获取新的单词供下一次使用。而不是在需要新单词时才调用getsym过程。)getsym过程通过反复调用getch子过程从源程序过获取字符,并把它们拼成单词。getch过程中使用了行缓冲区技术以提高程序运行效率。 词法分析器的分析过程: 调用getsym时,它通过getch过程从源程序中获得一个字符。如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把sym变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把sym 置为ident,把这个单词存入id变量。查保留字表时使用了二分法查找以提高效率。如果getch获得的字符是数字,则继续用getch获取数字,并把它们拼成一个整数,然后把sym置为number,并把拼成的数值放入num变量。如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把sym则成相应的类型。如果遇到不合法的字符,把sym置成nul。 语法分析子程序分析: 语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语意生成相应的代码,并提供了出错处理的机制。语法分析主要由分程序分析过程(block)、常量定义分析过程(constdeclaration)、变量定义分析过程(vardeclaration)、语句分析过程(statement)、表达式处理过程(expression)、项处理过程(term)、因子处理过程(factor)和条件处理过程(condition)构成。这些过程在结构上构成一个嵌套的层次结构。除此之外,还有出错报告过程(error)、代码生成过程(gen)、测试单词合法性及出错恢复过程(test)、登录名字表过程(enter)、查询名字表函数(position)以及列出类pcode代码过程(listcode)作过语法分析的辅助过程。 由pl/0的语法图可知:一个完整的pl/0程序是由分程序和句号构成的。因此,本编译程序在运行的时候,通过主程序中调用分程序处理过程block来分析分程序部分(分程序分析过程中还可能会递归调用block过程),然后,判断最后读入的符号是否为句号。如果是句号且分程序分析中未出错,则是一个合法的pl/0程序,可以运行生成的代码,否则就说明源pl/0程序是不合法的,输出出错提示即可。 语法单元分析: 1、分程序处理过程: 语法分析开始后,首先调用分程序处理过程(block)处理分程序。过程入口参数置为:0层、符号表位置0、出错恢复单词集合为句号、声明符或语句开始符。进入block过程后,首先把局部数据段分配指针设为3,准备分配3个单元供

相关文档
最新文档