如何看懂源代码--(分析源代码方法)

如何看懂源代码--(分析源代码方法)
如何看懂源代码--(分析源代码方法)

如何看懂源代码--(分析源代码方法)

4

由于今日计划着要看Struts 开源框架的源代码

昨天看了一个小时稍微有点头绪,可是这个速度本人表示非常不满意,先去找了下资

料, 觉得不错...

摘自(繁体中文

Traditional Chinese):http://203.208.39.132/translate_c?hl=zh-CN&sl=en&tl=zh-CN&u=http://ww https://www.360docs.net/doc/346748471.html,/itadm/article.php%3Fc%3D47717&prev=hp&rurl=https://www.360docs.net/doc/346748471.html,&usg=AL kJrhh4NPO-l6S3OZZlc5hOcEQGQ0nwKA 下文为经过Google翻译过的简体中文版:

我们在写程式时,有不少时间都是在看别人的代码。

例如看小组的代码,看小组整合的守则,若一开始没规划怎么看,就会“噜看噜苦(台语)”不管是参考也好,从开源抓下来研究也好,为了了解箇中含意,在有限的时间下,不免会对庞大的源代码解读感到压力。网路上有一篇关于分析看代码的方法,做为程式设计师的您,不妨参考看看,换个角度来分析。也能更有效率的解读你想要的程式码片段。

六个章节:

( 1 )读懂程式码,使心法皆为我所用。( 2 )摸清架构,便可轻松掌握全貌。( 3 )优质工具在手,读懂程式非难事。( 4 )望文生义,进而推敲组件的作用。( 5 )找到程式入口,再由上而下抽丝剥茧。( 6 )阅读的乐趣,透过程式码认识作者。

程式码是别人写的,只有原作者才真的了解程式码的用途及涵义。许多程式人心里都有一种不自觉的恐惧感,深怕被迫去碰触其他人所写的程式码。但是,与其抗拒接收别人的程式码,不如彻底了解相关的语言和惯例,当成是培养自我实力的基石。

对大多数的程式人来说,撰写程式码或许是令人开心的一件事情,但我相信,有更多人视阅读他人所写成的程式码为畏途。许多人宁可自己重新写过一遍程式码,也不愿意接收别人的程式码,进而修正错误,维护它们,甚至加强功能。

这其中的关键究竟在何处呢?若是一语道破,其实也很简单,程式码是别人写的,只有原作者才真的了解程式码的用途及涵义。许多程式人心里都有一种不自觉的恐惧感,深怕被迫去碰触其他人所写的程式码。这是来自于人类内心深处对于陌生事物的原始恐惧。

读懂别人写的程式码,让你收获满满

不过,基于许多现实的原因,程式人时常受迫要去接收别人的程式码。例如,同事离职了,必须接手他遗留下来的工作,也有可能你是刚进部门的菜鸟,而同事经验值够了,升级了,风水轮流转,一代菜鸟换菜鸟。甚至,你的公司所承接的专案,必须接手或是整合客户前一个厂商所遗留下来的系统,你们手上只有那套系统的原始码(运气好时,还有数量不等的文件)。

诸如此类的故事,其实时常在程式人身边或身上持续上演着。许多程式人都将接手他人的程式码,当做一件悲惨的事情。每个人都不想接手别人所撰写的程式码,因为不想花时间去探索,宁可将生产力花在产生新的程式码,而不是耗费在了解这些程式码上。

很遗憾的是,上述的情况对程式人来说很难避免。我们总是必须碰触到其他人所写成的程式码,甚至必须了解它,加以修改。对于这项需求,在现今开放原始码的风气如此盛行的今日,正如之前的“程式设计2.0 ”文中所提到的,你可以透过开放原始码学习到新的技术,学习到高手的架构设计,大幅提高学习的效率及效果。你甚至可以直接自开放原始码专案中抽取,提炼出自己所需的程式码,站在巨人的肩膀上,直接由彼端获得所需的生产力。从这个观点来看,读懂别人所写的程式码,就不再只是从负面观点的“被迫接收”,而是极具正面价值的“汲取养份。”

先了解系统架构与行为模式,再细读

倘若撰写程式码是程式人的重要技艺之一,那么读懂别人的程式码,接着加以修改,也势必是另一个重要的技艺。

如果你不能熟悉这项工作,不仅在遭逢你所不愿面对的局面时,无法解决眼前接手他人程式码的难题,更重要的是,当你看着眼前现成的程式码,却不知如何从中撷取自己所需,导致最后只能入宝山空手回,望之兴叹。

接触他人的程式码,大致上可以分为三种程度:一,了解,二,修改,扩充,三,抽取,提炼。了解别人的程式码是最基础的工作,倘若不能了解自己要处理的程式码,就甭论修改或扩充,更不可能去芜存菁,从中萃取出自己所需,回收再利用别人所撰写的程式码。虽说是“阅读”,但程式码并不像文章或小说一样,透过这种做法,便能够获得一定程度的了解。阅读文章或小说时,几乎都是循序地阅读,你只消翻开第一页,一行行阅读下去即可。但是,有许多程式人在试着阅读其他人的程式码时,却往往有不知如何读起的困难。

或许找到系统的第一页(也就是程式码执行的启始点)并不难,但是复杂度高的系统,有时十分庞大,有时千头万绪。

从程式码的启始点开始读起,一来要循序读完所有的程式码旷日费时,二来透过这种方式来了解系统,很难在脑中构建出系统的面貌,进而了解到系统真正的行为。所以,阅读程式码的重点,不在于读完每一行程式码,而是在于有效率地透过探索及阅读,从而了解系统的架构及行为模式。以便在你需要了解任何片段的细节实作时,能够很快在脑上对映到具体的

程式码位置,直到那一刻,才是细读的时机。

熟悉沟通语言与惯例用语

不论如何,有些基本的准备,是阅读他人程式码时必须要有的。

首先,你最好得了解程式码写成的程式语言。想要读懂法文写成的小说,总不能连法文都不懂吧。有些情况则很特殊。我们虽然不懂该程式码撰写所用的语言,但是因为现代语言的高阶化,而且流行的程式语言多半都是血统相近,所以即使不那么熟悉,有时也可勉力为之。除了认识所用语言之外,再来就是要先确认程式码所用的命名惯例(命名惯例)。了解命名惯例很重要,不同的程式人或开发团队,差异可能很大。

这命名惯例涵盖的范围通常包括了变数的名称,函式的名称,类别(如果是物件导向的话)的名称,原始码档案,甚至是专案建构目录的名称。倘若使用了像设计模式之类的方法,这些名称更有一些具体的表述方式。

命名惯例有点像是程式人在程式语言之上,另行建构的一组沟通行话。程式人会透过共通约束,遵守的命名惯例,来表达一些较高阶的概念。例如,有名的匈牙利式命名法,便将变数名称以属性,型别,说明合并在一起描述。对程式人来说,这种方式能够提供更丰富的资讯,以了解该变数的作用及性质。

对程式码阅读来说,熟悉这个做法之所以重要,是因为当你了解整个系统所采用的惯例时,

你便能试着以他们所共同操用的语汇来进行理解。倘若,不能了解其所用的惯例,那么这些额外提供的资讯,就无法为你所用。像以设计模式写成的程式码,同样处处充满着模式的名称,诸如:工厂,门面,代理等等。以这些名称指涉的类别,也直接透过名称,表达了它们自身的作用。对于懂得这命名惯例的读者来说,不需要深入探索,也能很快捕捉到这些类别的意义。

当你拿到一套必须阅读的程式码时,最好先取得命名惯例的说明文件。然而,并不是每套程式码都附有此类的说明文件。另一个方式,就是自己到程式码中,大略浏览一遍,有经验的程式人可以轻易发掘出该系统所用的命名惯例。

常见的命名方式不脱那几类,这时候经验就很重要,倘若你知道的惯例越多,就越能轻易识别他人所用的惯例。如果运气很糟,程式码所用的惯例是前所未见的,那么你也得花点时间归纳,凭自己的力量找出这程式码命名上的规则。

掌握程式码撰写者的心态与习惯

大多数的程式码,基本上都依循一致的命名惯例。不过运气更差的时候,一套系统中可能会充斥着多套命名惯例。这有可能是因为开发团队由多组人马所构成,每组人马都有不同的文化,而在专案开发管理又没有管控得宜所造成。最糟的情况,程式码完全没有明显的惯例可言,这时候阅读的难度就更高了。

想要阅读程式码,得先试着体会程式码作者的“心”。想要这么做,就得多了解对方所使用的语言,以及惯常运用的语汇。在下一回中,我们将继续探讨阅读程式码的相关议题。阅读他人的程式码( 2 ) -摸清架构,便可轻松掌握全貌

在本文中,我们的重点放在:要了解一个系统,最好是采取由上至下的方式。先试着捕捉系统架构性的观念,不要过早钻进细节,因为那通常对于你了解全貌,没有多大的帮助。阅读程式码不需要从第一行读起,我们的目的并不是在于读遍每一段程式码。

基于许多原因,程式人需要阅读其他人所写成的程式码。而对程式设计2.0时代的程式人来说,最正面的价值在于,能读懂别人程式的人,才有能力从中萃取自己所需的程式,借以提高生产力。

Android源代码结构分析

目录 一、源代码结构 (2) 第一层次目录 (2) bionic目录 (3) bootloader目录 (5) build目录 (7) dalvik目录 (9) development目录 (9) external目录 (13) frameworks目录 (19) Hardware (20) Out (22) Kernel (22) packages目录 (22) prebuilt目录 (27) SDK (28) system目录 (28) Vendor (32)

一、源代码结构 第一层次目录 Google提供的Android包含了原始Android的目标机代码,主机编译工具、仿真环境,代码包经过解压缩后,第一级别的目录和文件如下所示: . |-- Makefile (全局的Makefile) |-- bionic (Bionic含义为仿生,这里面是一些基础的库的源代码) |-- bootloader (引导加载器),我们的是bootable, |-- build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具) |-- dalvik (JAVA虚拟机) |-- development (程序开发所需要的模板和工具) |-- external (目标机器使用的一些库) |-- frameworks (应用程序的框架层) |-- hardware (与硬件相关的库) |-- kernel (Linux2.6的源代码) |-- packages (Android的各种应用程序) |-- prebuilt (Android在各种平台下编译的预置脚本) |-- recovery (与目标的恢复功能相关) `-- system (Android的底层的一些库)

词法分析器实验报告及源代码

数学与软件科学学院实验报告 学期:13至14__ 第_2 学期 2014年3月17 日 课程名称:编译原理专业:2011级5_班 实验编号:01 实验项目:词法分析器指导教师_王开端 姓名:张世镪学号: 2011060566 实验成绩: 一、目的 学习编译原理,词法分析是编译的第一个阶段,其任务是从左至右挨个字符地对源程序进行扫描,产生一个个单词符号,把字符串形式的源程序改造成单词符号串形式的中间程序。执行词法分析的程序称为词法分析程序,也称为词法分析器或扫描器。词法分析器的功能是输入源程序,输出单词符号 做一个关于C的词法分析器,C++实现 二、任务及要求 1.词法分析器产生下述C的单词序列 这个C的所有的单词符号,以及它们的种别编码和内部值如下表: -* / & <<=>>===!= && || , : ; { } [ ] ( ) ID和NUM的正规定义式为: ID→letter(letter | didit)* NUM→digit digit* letter→a | … | z | A | … | Z

digit→ 0 | … | 9 如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。空格由空白、制表符和换行符组成。 三、大概设计 1. 设计原理 词法分析的任务:从左至右逐个字符地对源程序进行扫描,产生一个个单词符号。 理论基础:有限自动机、正规文法、正规式 词法分析器又称扫描器:执行词法分析的程序 2. 词法分析器的功能和输出形式 功能:输入源程序、输出单词符号 程序语言的单词符号一般分为以下五种:关键字、标识符、常数、运算符、界符。3. 输出的单词符号的表示形式: (单词种别,单词符号的属性值) 单词种别用整数编码,关键字一字一种,标识符统归为一种,常数一种,各种符号各一种。 4. 状态转换图实现

yaffs2文件系统制作

交叉编译器ARM-Linux-gcc4.1.2 开发板TX2440A Busybox-1.15.1.tar.bz2(在Linux中被称为瑞士军刀) mkyaffs2image工具 首先创建一个名字为root_2.6.31的文件夹,在其中创建如下文件夹 etc bin var dev home lib mnt proc root sbin sys tmp usr opt共14个文件夹 解压Busybox tar xjvf busybox 进入源目录,修改Makefile 第164行,CROSS_COMPILE=arm-linux- 第190行,ARCH=arm 执行#make men onfig进行配置 配置选项大部分都是保持默认的,只需要注意选择以下这几个选项,其他的选项都不用动:Busybox Setting---> Build Options---> [*]Build Busybox as a static binary(no shared libs) [*]Build with Large File Support(for accessing files>2GB) Installation Options--->

(./_install)Busybox installation prefix 进入这个选项,输入busybox的安装路径,如:../rootfs Busybox Library Tuning---> [*]vi-style line editing commands [*]Fancy shell prompts 要选择这个选项:“Fancy shell prompts”,否则挂载文件系统后,无法正常显示命令提示符:“[\u@\h\W]#” 配置完成以后 执行#make #make install 然后就会在上一级目录下生成rootfs文件夹,里面包含几个文件夹/bin/sbin/usr linuxrc 把这些文件全部复制到刚建好的root_2.6.31目录下, #cp–rf*../root_2.6.31 在dev目录下,创建两个设备节点: #mknod console c51 #mknod null c13 然后进入自己建立的etc目录 拷贝Busybox-1.15.2/examples/bootfloopy/etc/*到当前目录下。 #cp-r../../busybox-1.15.2/examples/bootfloopy/etc/*./ 包括文件:fstab init.d inittab profile

语法分析器源代码

#include #include #include #define HIGHER 1 #define LOWER -1 #define EQUAL 0 #define TRUE 1 #define FALSE 0 #define OPER_NUM 50 //默认算符数目 #define VN_NUM 50 //默认非终结符数目#define MAX_BUFFER 128 //每行输入行最大长度 #define MAX_GRA_NUM 20 //最大文法数目#define EMPTY -2 //算符优先表初始值,表示这对算符没有优先关系 #define STACK_SIZE 64 typedef struct { char c; //非终极符符号 int firstvt[OPER_NUM]; //firstvt集,保存算符在oper_list中的下标 int fir_n,last_n; int lastvt[OPER_NUM]; }vn_t; int prior_table[OPER_NUM][OPER_NUM]; char oper_list[OPER_NUM]; int oper_num = 0; vn_t vn_list[VN_NUM]; int vn_num = 0; char *grammar[MAX_GRA_NUM][2]; int gra_num = 0; char start_vn; char stack[STACK_SIZE]; int top = 0; void get_input(char *buf); int buf_deal(char* buf); void get_FIRVT_LASTVT(int vn_n);

linux-2.6.18移植

Linux-2.6.18移植 有了我们的交叉编译环境和我们先前学的内核基础知识,下面我们就开始我们的内核移植了,我们所用的是博创的 S3C2410 。 关于 linux-2.6.18.tar.bz2 的下载网站先前我们说过,我们要先到该官方网站上去下载一个全新的内核。 [root@Binnary ~ ]# tar –jxvf linux-2.6.18.tar.bz2 [root@Binnary ~ ]# make mrproper 如果你是新下载的内核,那这一步就不用了。但如果你用的是别人移植好的内核,那最好在编译内核之前先清除一下中间文件,因为你们用来编译内核的交叉编译工具可能不同。 第一步:修改Makefile文件 将 改为 第二步:修改分区设置信息 我们要先在BootLoader中查看相应的分区信息 vivi>help 然后修改内核源码中的分区信息。分区信息文件在 a rch/arm/mach-s3c2410/common-smdk.c 将其中的

改为如下内容:

第三步:内核通过 BootLoader把数据写入NAND Flash,而vivi的ECC效验算法和内核的不同,内核的效验码是由NAND Flash控制器产生的,所以在此必须禁用NAND Flash ECC。所以我们就要修改 drivers/mtd/nand/s3c2410.c 这个文件。将 中的 chip->ecc.mode = NAND_ECC_SOFT ,改为如下 chip->ecc.mode = NAND_ECC_NONE。

只此一处。 第四步:下面是devfs的问题,因为2.6.12内核以后取消了devfs的配置选项,缺少了它内核会找不到mtdblock设备。所以我们需要修改 fs/Kconfig 文件,或者是从2.6.12的fs/Kconfig中拷贝下面几项到2.6.18的fs/Kconfig中去,我们采用修改的方法来完成。 修改 fs/Kconfig支持devfs 。 在Pseudo filesystems 主菜单的最后添加我们所要的内容。 第五步:文件系统的支持 Yaffs 文件系统 YAFFS文件系统简介 YAFFS,Yet Another Flash File System,是一种类似于JFFS/JFFS2的专门为Flash设计 的嵌入式文件系统。与JFFS相比,它减少了一些功能,因此速度更快、占用内存更少。 YAFFS和JFFS都提供了写均衡,垃圾收集等底层操作。它们的不同之处在于: (1)、JFFS是一种日志文件系统,通过日志机制保证文件系统的稳定性。YAFFS仅仅 借鉴了日志系统的思想,不提供日志机能,所以稳定性不如JAFFS,但是资源占用少。 (2)、JFFS中使用多级链表管理需要回收的脏块,并且使用系统生成伪随机变量决定 要回收的块,通过这种方法能提供较好的写均衡,在YAFFS中是从头到尾对块搜索, 所以在垃圾收集上JFFS的速度慢,但是能延长NAND的寿命。 (3)、JFFS支持文件压缩,适合存储容量较小的系统;YAFFS不支持压缩,更适合存 储容量大的系统。 YAFFS还带有NAND芯片驱动,并为嵌入式系统提供了直接访问文件系统的API,用 户可以不使用Linux中的MTD和VFS,直接对文件进行操作。NAND Flash大多采用 MTD+YAFFS的模式。MTD( Memory Technology Devices,内存技术设备)是对Flash 操作的接口,提供了一系列的标准函数,将硬件驱动设计和系统程序设计分开。 Yaffs 文件系统内核没有集成,可以对其主页下载: https://www.360docs.net/doc/346748471.html,/cgi-bin/viewcvs.cgi/#dirlist

编译原理课程设计-词法分析器(附含源代码)

编译原理-词法分析器的设计 一.设计说明及设计要求 一般来说,编译程序的整个过程可以划分为五个阶段:词法分析、语法分析、中间代码生成、优化和目标代码生成。本课程设计即为词法分析阶段。词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。如保留字(关键字或基本字)、标志符、常数、算符和界符等等。 二.设计中相关关键字说明 1.基本字:也称关键字,如C语言中的 if , else , while , do ,for,case,break, return 等。 2.标志符:用来表示各种名字,如常量名、变量名和过程名等。 3.常数:各种类型的常数,如12,6.88,和“ABC” 等。 4.运算符:如 + ,- , * , / ,%, < , > ,<= , >= 等。5.界符,如逗点,冒号,分号,括号,# ,〈〈,〉〉等。 三、程序分析 词法分析是编译的第一个阶段,它的主要任务是从左到右逐个字符地对源 程序进行 扫描,产生一个个单词序列,用以语法分析。词法分析工作可以是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。然而,更一般的情况,常将

词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则 调用该子程序。词法分析程序每得到一次调用,便从源程序文件中读入一 些字符,直到识别出一个单词,或说直到下一个单词的第一个字符为止。 四、模块设计 下面是程序的流程图 五、程序介绍 在程序当前目录里建立一个文本文档,取名为infile.txt,所有需要分析的程序都写在此文本文档里,程序的结尾必须以“@”标志符结束。程序结果输出在同一个目录下,文件名为outfile.txt,此文件为自动生成。本程序所输出的单词符号采用以下二元式表示:(单词种别,单词自身的值)如程序输出结果(57,"#")(33,"include")(52,"<")(33,"iostream") 等。 程序的功能:(1)能识别C语言中所有关键字(共32个)(单词种别分别为1 — 32 ,详情见程序代码相关部分,下同) (2)能识别C语言中自定义的标示符(单词种别为 33) (3)能识别C语言中的常数(单词种别为0) (4)能识别C语言中几乎所有运算符(单词种别分别为41 — 54) (5)能识别C语言中绝大多数界符(单词种别分别为 55 — 66)六、运行结果 输入文件infile.txt 运行结果(输出文件 outfile.txt)

Yaffs2文件系统中对NAND Flash磨损均衡的改进

Yaffs2文件系统中对NAND Flash磨损均衡的改进 摘要:针对以NAND Flash为存储介质时Yaffs2文件系统存在磨损均衡的缺陷,通过改进回收块选择机制,并在数据更新中引入冷热数据分离策略,从而改善NAND Flash的磨损均衡性能。实验借助Qemu软件建立Linux嵌入式仿真平台,从总擦除次数、最大最小擦除次数差值和块擦除次数标准差等方面进行对比。实验结果表明,在改进后的Yaffs2文件系统下NAND Flash的磨损均衡效果有明显提升,这有益于延长NAND Flash的使用寿命。 关键词: Yaffs2文件系统;NAND Flash;垃圾回收;冷热数据 0 引言 NAND Flash存储设备与传统机械磁盘相比,具有体积小、存储密度高、随机存储和读写能力强、抗震抗摔、功耗低等特点[1]。它被广泛用于智能手机、车载智能中心、平板电脑等智能终端中。近年来,以NAND Flash为存储介质的固态硬盘也得到越来越多的应用。目前Yaffs2文件系统(Yet Another Flash File System Two,Yaffs2)[1]是使用最多、可移植性最好的专用文件系统,在安卓、阿里云OS、Linux等嵌入式系统中都有使用。在Yaffs2文件系统下以NAND Flash为存储介质时存在磨损均衡的缺陷,可通过对回收块选择机制作改进和引入冷热数据分离策略来提高磨损均衡的效果。 1 Yaffs2和Nand Flash关系 这里以使用最多的Linux操作系统为实践,将Yaffs2文件系统移植到Linux操作系统中。Linux系统通常可以分为3层:应用层、内核层和设备层,其中支持NAND Flash设备的Yaffs2文件系统属于内核层,。 最上层用户应用程序通过VFS(Virtual File System)提供的统一接口,将数据更新等文件操作传递给Yaffs2。VFS代表虚拟文件系统,它为上层应用提供统一的接口。有了这些接口,应用程序只用遵循抽象后的访问规则,而不必理会底层文件系统和物理构成上的差异。然后Yaffs2通过MTD(Memory Technology Device)提供的统一访问接口对NAND Flash进行读、写和擦除操作,从而完成数据的更新或者存储操作。MTD代表内存技术设备,它为存储设备提供统一访问的接口。最终,在NAND Flash上以怎样的格式组织和存储数据由Yaffs2文件系统决定。 NAND Flash由若干块(block)组成,每个块又是由若干页(page)组成,页中含有数据区和附加区。NAND Flash的页根据状态不同,可以分为有效页、脏页、空闲页。有效页中存放有效数据,脏页中存放无效数据,空闲页是经过擦除后可以直接用于写入数据的页。NAND Flash在写入数据前需要执行擦除操作,因此数据不能直接在相同的位置更新。当一个页中数据需要更新时,必须将该页中有效数据拷贝到其他空闲页上再更新,并将原来页上的数据置为无效。随着时间的推移,许多无效页累积在存储器中使得空闲页逐渐减少。当存储器中的空闲空间不足时,启动垃圾回收操作,利用回收块选择机制从待回收块中选取满足要求的块来擦除,从而得到足够的空闲空间。NAND Flash中块的擦除次数有限,通常为10 000次~100 000次[2]。当某个块的擦除次数超过使用寿命时,该块将无法正常用于数据存储。因此,垃圾回收应利用合理的回收块选择机制,从待回收块中找到回收后能产生良好磨损均衡效果且付出较少额外代价的块来回收,从而获得足够的空闲空间用于数据更新操作。 2 Yaffs2在磨损均衡方面的缺陷 Yaffs2中回收块的选择机制[3]是从待回收块中找到有效数据最少的块来回收。回收过程中,Yaffs2能够减少有效数据的额外读和写操作。当数据更新处于均匀分布的情况下,Yaffs2表现出较好的磨损均衡效果。 但是,通常情况下数据的更新频率不同,有些数据经常更新,而有些数据很少更新。经

2-Linux

Linux-2.6.32.2内核在mini2440上的移植(二)---yaffs2文件系统移植 移植环境(红色粗字体字为修改后内容,蓝色粗体字为特别注意内容) 2.1, yaffs2文件系统移植 【1】获取yaffs2 源代码 现在大部分开发板都可以支持yaffs2 文件系统,它是专门针对嵌入式设备,特别是使用nand flash 作为存储器的嵌入式设备而创建的一种文件系统,早先的yaffs 仅支持小页(512byte/page)的nand flash,现在的开发板大都配备了更大容量的nand flash,它们一般是大页模式的(2K/page),使用yaffs2 就可以支持大页的nand flash,下面是yaffs2 的移植详细步骤。 在https://www.360docs.net/doc/346748471.html,/node/346可以下载到最新的yaffs2 源代码,需要使用git工具( 安装方法见Git版本控制软件安装与使用),在命令行输入: [root@localhost ~]# cd ./linux-test [root@localhost linux-test]# git clone git://https://www.360docs.net/doc/346748471.html,/ya ffs2 Cloning into yaffs2... remote: Counting objects: 6592, done. remote: Compressing objects: 100% (3881/3881), done. remote: Total 6592 (delta 5237), reused 3396 (delta 2642) Receiving objects: 100% (6592/6592), 3.34 MiB | 166 KiB/s, d one. Resolving deltas: 100% (5237/5237), done.

实验一、词法分析器(含源代码)

词法分析器实验报告 一、实验目的及要求 本次实验通过用C语言设计、编制、调试一个词法分析子程序,识别单词,实现一个C语言词法分析器,经过此过程可以加深对编译器解析单词流的过程的了解。 运行环境: 硬件:windows xp 软件:visual c++6.0 二、实验步骤 1.查询资料,了解词法分析器的工作过程与原理。 2.分析题目,整理出基本设计思路。 3.实践编码,将设计思想转换用c语言编码实现,编译运行。 4.测试功能,多次设置包含不同字符,关键字的待解析文件,仔细察看运行结果,检测该分析器的分析结果是否正确。通过最终的测试发现问题,逐渐完善代码中设置的分析对象与关键字表,拓宽分析范围提高分析能力。 三、实验内容 本实验中将c语言单词符号分成了四类:关键字key(特别的将main说明为主函数)、普通标示符、常数和界符。将关键字初始化在一个字符型指针数组*key[]中,将界符分别由程序中的case列出。在词法分析过程中,关键字表和case列出的界符的内容是固定不变的(由程序中的初始化确定),因此,从源文件字符串中识别出现的关键字,界符只能从其中选取。标识符、常数是在分析过程中不断形成的。 对于一个具体源程序而言,在扫描字符串时识别出一个单词,若这个单词的类型是关键字、普通标示符、常数或界符中之一,那么就将此单词以文字说明的形式输出.每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直到整个源程序全部扫描完毕,从而形成相应的单词串。 输出形式例如:void $关键字

流程图 、程序 流程图: 开始 输入源文件路径 路径是否有 效 是初始化文件指针 否 将字符加入字符数 组Word[] 是空格,空白或换 行吗 是字母吗是数字吗否否是界符吗否打开源文件 跳过该字符 是是 文件结束? 否 将字符加入字符数 组Word[] 否 将字符加入字符数组Word[] 是 指向下一字符识别指针内容 指向下一字符 是字母惑数字 吗 是 将word 与关键字表key 进行匹 配 否匹配?是输出word 为关键字 输出word 为普通标示符 否将字符加入字符数组Word[] 指向下一字符输出word 为常数 识别指针内容 回退 是数字吗 是 否输出word 为界符 指向下一字符 结束 是输出Word 内容为不可识别 将字符加入字符数组Word[]

词法分析器源代码

词法分析器源代码 #include #include #include #include /*单词种别码*/ #define _CHAR 1 #define _INT 2 #define _SHORT 3 #define _LONG 4 #define _SIGNED 5 #define _UNSIGNED 6 #define _FLOAT 7 #define _DOUBLE 8 #define _CONST 9 #define _VOID 10 #define _VOLATILE 11 #define _ENUM 12 #define _STRUCT 13 #define _UNION 14 #define _TYPEDEF 15 #define _AUTO 16 #define _EXTERN 17 #define _STATIC 18 #define _REGISTER 19 #define _IF 20 #define _ELSE 21 #define _SWITCH 22 #define _CASE 23 #define _DEFAULT 24 #define _WHILE 25 #define _DO 26 #define _FOR 27 #define _BREAK 28 #define _CONTINUE 29 #define _GOTO 30 #define _RETURN 31 #define _SIZEOF 32 #define _INCLUDE 33 #define _DEFINE 34 /* 以上为关键字的种别码 */ #define _ID 40 //标识符 #define _NUM 50 //数 #define _AS 51 //= #define _PLUS 52 //+ #define _SUB 53 //- #define _TIMES 54 // * #define _DIV 55 // / #define _LP 56 // ( #define _RP 57 // ) #define _LB1 58 // [ #define _RB1 59 // ] #define _LB2 60 // { #define _RB2 61 // } #define _COM 62 // , #define _COL 63 // : #define

使用yaffs2img工具制作Android刷机包教程

制作刷机包 打开‘yaffs2img浏览器’,点击左上角的‘选取yaffs2文件’选择你刚刚复制出来的 files文件夹里的system.img 先来认识一下这个软件 1.定制软件的提取(此部和制作刷机包没关系,可以不做,想用官方软件的同学可以 看看) 选择app,右键你想要提取软件,提取就可以了,我是把整个app文件夹提取出来了,不用 的软件直接删掉好了 2.定制软件的精简 在你不想要用的软件上直接右键,删除,就好了,你也可以右键添加你想要用的软件,得把

软件改成比较简短的英文名,否则有可能不能用 秀一下我精简后的列表,大家可以参照着精简 https://www.360docs.net/doc/346748471.html,uncher文件的替换 下载好你想要用的桌面软件,改名为‘Launcher’,删掉app中的‘Launcher2’,添加进去你改好名字的‘Launcher’就好了,我比较喜欢ADW,所以我把ADW的文件名改为 Launcher,替换掉原来的Launcher2就好了 4.破音问题的解决 在左边导航点选‘etc’,右键添加文件,把附件中的声音配置文件解压出来 ‘AudioFilter.csv’添加进去就好了 AudioFilter.rar (355 Bytes)

5.字体的更改 下载字体文件,中文字体库一律把名字改名为‘DroidSans Fallback.ttf’,英文字体改为‘DroidSans.ttf ’,加粗的英文字体改为‘DroidSans-Bold.ttf ’然后再左边导航栏点选‘fonts’,把之前自带的字体删除,然后把你改好名字的字体添加进去就好了把国产机皇的字体也分享给大家,中文+英文+英文加粗 6.开机音乐和照相机音乐的删除 在导航栏点选‘media’,在audio/ui文件夹下,删除‘Bootsound.mp3’(开机音乐)和

编译原理 LL(1)语法分析器java版 完整源代码

public class Accept2 { public static StringBuffer stack=new StringBuffer("#E"); public static StringBuffer stack2=new StringBuffer("i+i*#"); public static void main(String arts[]){ //stack2.deleteCharAt(0); System.out.print(accept(stack,stack2)); } public static boolean accept(StringBuffer stack,StringBuffer stack2){//判断识别与否 boolean result=true; outer:while (true) { System.out.format("%-9s",stack+""); System.out.format("%9s",stack2+"\n"); char c1 = stack.charAt(stack.length() - 1); char c2 = stack2.charAt(0); if(c1=='#'&&c2=='#') return true; switch (c1) {

case'E': if(!E(c2)) {result=false;break outer;} break; case'P': //P代表E’if(!P(c2)) {result=false;break outer;} break; case'T': if(!T(c2)) {result=false;break outer;} break; case'Q': //Q代表T’if(!Q(c2)) {result=false;break outer;} break; case'F': if(!F(c2)) {result=false;break outer;} break; default: {//终结符的时候 if(c2==c1){ stack.deleteCharAt(stack.length()-1); stack2.deleteCharAt(0); //System.out.println(); } else{

第2天 linux系统的编译及镜像文件的制作

第2天linux系统的编译及镜像文件的制作 一般来说,linux系统分为几个映像。 一:bootload :一般常用的是 U-boot 二:内核映像:主要是linux内核编译成的映像比如TQ210开发板使用的zImage.bin 三:文件系统:有很多格式,比如 下面根据TQ210说明书进行讲解,大部分参考官方手册。以后自己修改源码可以在此基础上进行修改,修改完以后按照此步骤进行编译,编译完成后进行下载到开发板进行运行 1编译bootloader 1.1光盘中的 u-boot 源码的解压 先将光盘中的 u-boot 源码 ( 在光盘的“ TQ210_CD\bootloader\ ” 目录下 , 名为 uboot_TQ210_1.3.4_V1.1.tar.bz2)拷贝到 PC 的linux系统的根目录(这里说的根目录是本手册编写者的操 作和截图所拷贝的地方, 实际操作可以拷贝到任意目录下) 下, 然后使用命令#tar xvfjuboot_TQ210_1.3.4_V1.1.tar.bz2 -C /,解压源码,如下图所示 源码解压后,会在“/opt/EmbedSky/TQ210/uboot_TQ210_1.3.4/”目录下得到刚刚解压的源码。 1.2 光盘中的u-boot源码的编译 解压完成后,使用命令#make TQ210_config,配置u-boot,如下图所示:

使用命令#make,编译u-boot。编译结束后,在/opt/EmbedSky/TQ210/uboot_TQ210_1.3.4/目录下会得 到一个名字u-boot.bin的镜像,将其拷贝到Windows 或者拷贝到TFTP 服务器发送文件指定的目录中,就 可以烧写到开发板上面进行测试了(或者制作成SD 启动卡也可以测试)。如下两图所示:

语法分析器(含完整源码)教学文稿

语法分析器(含完整源 码)

语法分析实验报告 一、实验目的: 1. 了解单词(内部编码)符号串中的短语句型结构形成规律。 2. 理解和掌握语法分析过程中语法分析思想(LL,LR)的智能算法化方法。 二、实验内容: 构造自己设计的小语言的语法分析器: 1. 小语言的语法描述(语法规则)的设计即文法的设计; 2. 把文法形式符号中所隐含的信息内容挖掘出来并用LL或LR 的资料形式(分析表)表示出来; 3. 语法分析的数据输入形式和输出形式的确定; 4. 语法分析程序各个模块的设计与调试。 主要设备和材料:电脑、winxp操作系统、VC语言系统 三、实验分工:

081 四、实验步骤: 1、语法规则 ①<程序>::= {<变量定义语句>|<赋值语句>|<条件语句> |<循环语句> } ②<变量定义语句>::=var 变量{,变量}; ③<赋值语句>::=变量:= <表达式>; ④<表达式>::=标识符{运算符标识符}; ⑤<标识符>::=变量|常量 ⑥<运算符>::=+ | - | * | / | >= | <= ⑦<条件语句>::=[] ⑧::= if(表达式) then[begin] {赋值语句|条件语句| 循环语句}[end] ⑨::= [begin] {赋值语句|条件语句| 循环语句} [end] ⑩<循环语句>::=while(表达式) [begin] {赋值语句| 条件语句| 循环语句} [end] <输出语句>::=prn 表达式 --注1:若if语句、else语句、循环语句中出现begin,后面的end必须出现,即begin与end同对出现 --注2:if、while后的"(",")"表示终结符,而不是定义成分优先的说明符号

C++语言实现词法分析器设计例题参考

给同学们的一段话 《编译原理》计算机软件专业的一门重要专业课程。该课程系统地向学生介绍编译程序的结构、工作流程及编译程序各组成部分的设计原理和实现技术。由于该课程理论性和实践性都比较强,内容较为抽象复杂,涉及到大量的软件设计算法,因此,一直是一门比较难学的课程。为了使学生更好地理解和掌握编译技术的基本概念、基本原理和实现方法,实践环节非常重要,只有通过上机进行程序设计,才能使学生对比较抽象的教学内容产生具体的感性认识,增强学生综合分析问题、解决问题的能力,并对提高学生软件设计水平大有益处。 编译原理涉及词法分析,语法分析,语义分析及优化设计等各方面。词法分析阶段是编译过程的第一个阶段,是编译的基础。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。从左到右逐个字符对构成源程序的字符串进行扫描,依据词法规则,识别出一个一个的标记(token),把源程序变为等价的标记串序列。执行词法分析的程序称为词法分析器,也称为扫描器。本例题是一个词法分析的设计,采用C++代码实现。 希望大家复习回顾以前学习的《C++程序设计》课程相关知识。 一、设计内容和要求 1、设计内容 对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。 2、设计要求 利用该词法分析器完成对源程序字符串的词法分析。输出形式是源程序的单词符号二元式的代码,并保存到文件中。 (1) 假设该语言中的单词符号及种别编码如下表所示。 单词符号及种别编码 单词符号种别编码单词符号种别编码 main 1 [ 28 int 2 ] 29 char 3 { 30

S3C2440的Linux内核移植和yaffs2文件系统制作

L i n u x内核移植和根文件系统制作 第一章移植内核 (2) 1.1 Linux内核基础知识 (2) 1.1.1 Linux版本 (2) 1.1.2 什么是标准内核 (2) 1.1.3 Linux操作系统的分类 (3) 1.1.4 linux内核的选择 (4) 1.2 Linux内核启动过程概述 (5) 1.2.1 Bootloader启动过程 (5) 1.2.2 Linux启动过程 (7) 1.3 Linux内核移植 (10) 1.3.1 移植内核和根文件系统准备工作 (10) 1.3.2 修改Linux源码中参数 (11) 1.3.3 配置Linux内核 (15) 1.3.4、编译内核 (17) 第二章制作根文件系统 (19) 2.1 根文件系统预备知识 (19) 2.2、构建根文件按系统 (19) 2.2.1、建立根文件系统目录 (19) 2.2.2、建立动态链接库 (21) 2.2.3 交叉编译Bosybox (21) 2.2.4 建立etc目录下的配置文件 (24) 2.2.5 制作根文件系统映像文件 (26) 第三章启动系统 (27) 第四章总结 (34)

第一章移植内核 1.1 Linux内核基础知识 在动手进行Linux内核移植之前,非常有必要对Linux内核进行一定的了解,下面从Linux内核的版本和分类说起。 1.1.1 Linux版本 Linux内核的版本号可以从源代码的顶层目录下的Makefile中看到,比如2.6.29.1内核的Makefile中: VERSION = 2 PA TCHLEVEL = 6 SUBLEVEL = 29 EXTRA VERSION = .1 其中的“VERSION”和“PA TCHLEVEL”组成主版本号,比如 2.4、2.5、2.6等,稳定版本的德主版本号用偶数表示(比如2.6的内核),开发中的版本号用奇数表示(比如2.5),它是下一个稳定版本内核的前身。“SUBLEVEL”称为次版本号,它不分奇偶,顺序递增,每隔1~2个月发布一个稳定版本。“EXTRA VERSION”称为扩展版本号,它不分奇偶,顺序递增,每周发布几次扩展本版号。 1.1.2 什么是标准内核 按照资料上的习惯说法,标准内核(或称基础内核)就是指主要在https://www.360docs.net/doc/346748471.html,/维护和获取的内核,实际上它也有平台属性的。这些linux 内核并不总是适用于所有linux支持的体系结构。实际上,这些内核版本很多时候并不是为一些流行的嵌入式linux系统开发的,也很少运行于这些嵌入式linux 系统上,这个站点上的内核首先确保的是在Intel X86体系结构上可以正常运行,它是基于X86处理器的内核,如对linux-2.4.18.tar.bz2的配置make menuconfig 时就可以看到,Processor type and features--->中只有386、486、586/K5/5x86/6x86/6x86MX、Pentium-Classic、Pentium-MMX、Pentium-Pro/Celeron/Pentium-II、Pentium-III/Celeron(Coppermine)、Pentium-4、K6/K6-II/K6-III 、Athlon/Duron/K7 、Elan 、Crusoe、Winchip-C6 、Winchip-2 、

词法分析器(含完整源码)

词法分析实验报告 一、实验目的与要求: 1、了解字符串编码组成的词的涵,感觉一下字符串编码的方法和解读 2、了解和掌握自动机理论和正规式理论在词法分析程序和控制理论中的应用 二、实验容: 构造一个自己设计的小语言的词法分析器: 1、这个小语言能说明一些简单的变量 识别诸如begin,end,if,while等保留字;识别非保留字的一般标识符(有下划线、字符、数字,且第一个字符不能是数字)。识别数字序列(整数和小数);识别:=,<=,>=之类的特殊符号以及;,(,)等界符。 2、相关过程(函数): Scanner()词法扫描程序,提取标识符并填入display表中 3、这个小语言有顺序结构的语句 4、这个小语言能表达分支结构的语句 5、这个小语言能够输出结果 总之这个小语言词法分析器能提供以上所说明到的语法描述的功能…… 三、实验步骤: 1、测试评价 (1)、测试1:能说明一些简单的变量,如关键字、一般标识符、界符等; (2)、测试2:能输出结果:单词符号(码形式)、各种信息表(如符号表、常量表等);(3)、测试程序: var x,y,z; begin x:=2; y:=3; if (x+5>=y*y) then begin z:=y*y-x; z:=z+x*x; end else z:=x+y;

prn z; end. (4)、结果: ①、从键盘读入; 部分结果如下:

(类型:该标识符所属的类型,如关键字,变量等;下标:该标识符所对应表(如变量标识符表,常量标识符表等)中其相应的位置,下同) ②、从文件读入,输出到文件; 部分结果如下:

其他测试及结果如下:

(课程总结)

《嵌入式系统案例分析与设计》 课程实验报告 班级: 学号: 姓名: 指导老师: 成绩:

嵌入式系统案例分析与设计课程实验报告 一、开发环境的构建 1. 交叉工具链arm-linux-gcc安装与设置 (1)首先在家目录下创建一个文件夹,然后继续在该文件夹目录下创建一个test文件夹,如下图所示: (2)将交叉编译工具链Linux4.6.1拷到test目录下并解压 解压: tar -xvf arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz (3)添加环境变量 PATH 决定了shell将到哪些目录中寻找命令或程序 配置编译环境路径在控制台下输入vim /etc/profile 在文件最后一行添加下面语句:export PATH=$PATH:/opt/FriendlyARM/toolschain/4.5.1/bin (4)保存关闭后,重启,用root账号重新登录系统,刚刚添加的环境变量生效,在控制台输入:arm-linux-gcc -v 如果安装成功将会输出arm-linux-gcc的版本号。如下图所示,显示gcc version 4.5.1 ,表示交叉编译工具链安装成功。

2. 设置TFTP服务器 (1)运行下面的命令,安装TFTP服务器和客户端# apt-get install tftpd-hpa tftp-hpa (2)运行下面的命令,重启TFTP服务器 # service tftpd-hpa restart

(3)新建一个文件,并将其移动到TFTP服务器的默认上传下载目录 (4)从服务器上下载test.txt文件,并退出tftp程序 (5)运行如下命令,确认下载的文件内容正确 3. 设置NFS服务器 (1)安装NFS服务器 # apt-get install nfs-kernel-server (2)运行下面的命令,创建一个目录,并在该目录下创建一个文件mkdir /nfs chown root /nfs chgrp root /nfs mkdir /nfs/rootfs echo "nfs test" > /nfs/rootfs/test.txt (3)编辑/ect/exports配置文件。 gedit /etc/exports

编译原理词法分析器实验报告

北华航天工业学院 《编译原理》课程实验报告 课程实验题目:词法分析器实验 作者所在系部:计算机科学与工程系作者所在专业:计算机科学与技术 作者所在班级:B08512 作者学号:18 作者姓名:李桂丁 指导教师姓名:李建义 完成时间:2010年3月26日

一、实验目的 了解词法分析程序的两种设计方法:1.根据状态转换图直接编程的方式;2.利用DFA 编写通用的词法分析程序。 二、实验内容及要求 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 2.能对任何S语言源程序进行分析 在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。 3.能检查并处理某些词法分析错误 词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。 4. 本实验要求处理以下两种错误(编号分别为1,2): 1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。 2:源程序文件结束而注释未结束。注释格式为:/* …… */

相关文档
最新文档