|
|
编辑器
ChinaUnix
在GNU Debian/Linux 下搭建Wiki服务 - Leo Cao的专栏 - CSDNBlog
blog.csdn.net/leo_cao/archive/2007/07/25/1708048.a... 这两天,为了team中同事之间交流方便,PM让我搭建一个wiki站,我之前都是用现成的,还没有自己搭建过,so,先去google一下,发现一个“只需十分钟 Linux环境下快速搭建wiki站”的文档,地址如下:http://www.i-boy.net/boynet/content/view/989/117/1/1/。
结果,我发现其中所说的完全过时了,其中建立mysql数据库那一段,mysql的命令还是错误的。哎~~。 所以,我还是花了一点时间,自己去看文档,找到了比较简便的方式去建立一个Wiki服务。如下所述: 首先是软硬件条件:Intel(R) Pentium(R) D CPU 3.20GHz 先安装软件 1, 首先从一般用户切换到root(你不会就是用root用Debian的吧, 8-) ),apt-get update 2,apt-get install mediawiki mediawiki mediawiki-{math,extensions} memcached php5-memcache php5-gd 3, 有一点,安装上面的软件时,提示的”recommended”的软件也要安装,“suggested”的可以忽略,我就不细写了。
软件安装结束,下面开始配置。(根本不像上面那个链接上说的那样繁琐) 1,请注意/usr/share/mediawiki1.9/下的目录,其中LocaleSettings.php是指向一个空的链接,跟踪下去,你会发现这个文件应该是在/etc/mediawiki1.9/下面的,它现在还并不存在。 2,接着我们到/etc/apache2/conf.d/,就会发现有一个mediawiki1.9.conf的链接文件,需要编辑它: #Alias /mediawiki1.9 /var/lib/mediawiki1.9 改为 Alias /wiki /var/lib/mediawiki1.9 //去掉注释,改名,我改成wiki,你随便 3,运行apache2ctl restart 4,根本不用配置mysql,自己去添加数据库,mediawiki自己的设置过程,会提示的。另外,如果需要重新设置mysql 的root密码,可以运行“dpkg-reconfigure mysql-server-5.0”。 5,打开iceweasel,ctrl+L,输入localhost/wiki/,自动补上http://,然后就进入了mediawiki1.9的设置界面,ok, get in. 6,我无需给出完整详细的配置说明,大家都是很聪明的人。只有一些小点,上面那个链接中用mm cache加速php,实际上,用memcached就好了。 7,当填好了表,最后点一下那个“Install MediaWiki”的按钮,就会在/var/lib/mediawiki1.9/config/下生成LocalSettings.php,将它拷贝到/etc/mediawiki1.9/下,然后重启apache2。 8,OK,现在已经搭建好了一个基本的wiki站,用5里面的地址就可以打开主页了。 另外,还可以安装clamav,增强安全性。 Top-Down设计流程如图2所示,其核心是采用HDL语言进行功能描述,由逻辑综合(Logic Synthesis)把行为(功能)描述转换成某一特定FPGA/EPLD的工艺网表,送到厂商的布局布线器完成物理实现。在设计过程的每一个环节,仿真器的功能验证和门级仿真技术保证设计功能和时序的正确性。
![]() FPGA/EPLDTop-Down 设计工具的黄金组合 Mentor Graphics公司提供一整套基于UNIX平台和Windows 95/NT 平台的FPGA/EPLD Top-Down设计工具:Renoir/ModelSim 和Exemplar,如图2所示。两种平台的工具具有相同的用户界面,并保证数据库的完全统一。目前,在FPGA/EPLD Top-Down设计方法全球市场上,Mentor已拥有42%的市场份额,远远领先于其他任何一个厂家。 采用Top-Down设计方法进行FPGA/EPLD设计,其设计结果的优劣与否取决于三个重要的因素:描述手段(即HDL语言)、设计方法(Style)和设计工具。描述手段是基础,设计方法需要工程经验,而设计工具则是Top-Down设计的关键。一套完整、强大、性能卓越的设计工具,可帮助设计工工程师最大限度的发挥其设计能力。 1. 图形化输入工具-Renoir ----设计工程师采用Top-Down方法进行FPGA/EPLD设计所面临到的第一个问题就是HDL语言的学习。语言的学习过程和应用能力直接影响设计产品的完成及其性能。但是设计师进行产品设计的最初并不是考虑如何去写语言,而是习惯于画出设计的框图,并采用图形化方法(流程图、状态图、真值表等)把它描述出来。Renoir这一图形化输入工具,不仅可以帮助设计师完成产品的功能描述,更可以自动生成HDL语言,为逻辑综合提供必要的输入数据。 ---- 采用图形化输入方法主要优点体现在: 提供框图、流程图、状态图、真值表等图形输入方法,使设计工程师从纯文本的设计方法理解脱出来,设计手段更贴近于设计师的思维过程: 便于工程师之间进行设计的相互交流以及对前人/他人设计结果的理解与再利用; 便于初学者学习HDL语言; 便于设计成果的存档,以便设计交流与再利用。 ---- Renoir作为新一代的图形化输入工具更具有以下诸多优点: 自动生成高效的HDL语言描述,生成结果可进行功能验证及逻辑综合;完全支持VHDL和Verilog两种国际标准,并完全支持VHDL/Verilog的混合描述;支持UNIX和Win95/NT两种平台,具有相同界面和数据库。Win95/NT平台采用标准的Windows界面,易学易用;支持框图/流程图的动画(Animation)仿真、调试过程便于设计的调试;即插即用(plug and play),与多种仿真器、综合器及软硬件协同验证工具有完善的接口,组成各种设计流程;在线查错功能(On line checking),进行语法和可综合性检查;语言到图形的转换,可以把VHDL、Verilog或混合HDL语言描述换成框图、流程图或状态图,并保持原设计的层次结构;支持OLE(Object Liking and Embedding)标准,可把Renoir中的任何图形设计形式连接或嵌入到任一支持OLE的应用程序中,如Word、Powerpoint等,以便用户建立设计文档;支持在图形输入中加入注释、属性(pragma, attribute)、并可自动加到所产生的HDL源码中;支持IP调用,并可自动生成相应符号,以使IP嵌入到所设计的系统中;完善的设计管理,支持设计项目管理、设计层次管理、设计小组管理及设计数据版本管理等;通过需求与设计可跟踪(Requirement & Tracebility)管理,不仅保证设计正确,而且保证正确设计(Design thing Right and Design Right thing)。 2. 逻辑综合工具-Exemplar ---- 逻辑综合工具是通过映射和优化过程,把设计功能描述转换成与物理实现密切相关的工艺网表。在转换过程中,不仅需要确保每一功能映射正确,还需保证尽量采用较少的硬件开销,满足设计的时序要求。因此,逻辑综合工具是FPGA/EPLD Top-Down设计过程的关键。 Exemplar的主要特点: 完全支持VHDL/Verilog两种国际标准;针对不同结构的FPGA/EPLD器件,采用不同的综合优化算法,以保证结果的最优化;支持不同类型器件的重映射,设计师可直接从一种器件的工艺网表映射到另一种器件的工艺网表,无需重新设计;支持各厂商器件网表的不同格式输入与输出。如:XNF,EDIF等:支持布局、布线后设计的反标注,产生后仿真所需功能网表(HDL)及延时网表(SDF);持静态时序分析;支持综合结果的图形输出,设计师可通过图形输出跟踪分析关键路径(Critical Path);支持广泛的FPGA厂商及其最新芯片型号,包括采用深亚微米技术的器件。厂商包括:Actel、Altera、Atmel、Cypress、Lattice、Lucent、Motorola、Quicklogic、Xilinx等;FPGA/EPLD设计到ASIC设计可实现无缝升级,保证设计数据的兼容性及可再利用性;即插即用,可与各种前端/后端工具结合使用,设计数据无虚人为干预/修改;持UNIX平台和Win95/NT平台,不同平台工具具有相同的用户界面、功能、并完全保证设计数据的兼容性。 3. 功能仿真与时序验证-ModelSim ---- 在FPGA/EPLD Top-Down设计流程中,设计仿真包含在设计过程的每一环节中,以保证设计的正确性。 ModelSim不仅可以完成设计的功能验证(RTL级),也可实现逻辑综合后的门级仿真以及布局布线后的功能和时序验证。 ---- ModelSim的主要特点: 完全支持VHDL和Verilog标准;采用直接编辑技术(Direct-Compiled),大大提高HDL编译和仿真速度;唯一支持VHDL和Verilog混合描述的仿真工具;支持RTL级和门级验证,支持VITAL,SDF等;具有友好的用户界面,仿真器包括主控窗口、源码窗口、仿真波形窗口、列表窗口、数据流窗口、设计结构/层次窗口、过程管理窗口等;支持单步调试,断点设置,批命令处理方式,帮助设计师快速完成设计调试和验证;可与Renoir协同工作,完成状态图和流程图的动画调试 ;即插即用,可与其它工具结合,完成各种流程;支持UNIX和Window 95/NT平台,不同平台间具有相同的用户界面和数据库。 GTK+GNOME 2.20 uses version 2.12 of the GTK+ UI toolkit API, which adds new features and important bug-fixes. The largest changes are:
See also the list of new functions in GTK+ 2.12. Full details are in a series (see 1, 2, 3, 4) of emails from Matthias Clasen /var 這個目錄也很重要,也是 FHS 規範的第二層目錄內容。他主要放置的是針對系統執行過程中, 常態性變動的檔案放置的目錄。舉例來說,例如快取檔案 (cache) 或者是隨時變更的登錄檔 (log file) 都是放在這個目錄中的。此外,某些軟體執行過程中會寫入的資料庫檔案, 例如 MySQL 資料庫,也都寫入在這個目錄中!很重要吧!他底下的重要目錄有:
* /var/cache:程式檔案在運作過程當中的一些暫存檔; * /var/lib:程式本身執行的過程中,需要使用到的資料檔案放置的目錄, 舉例來說, locate 這個資料庫與 MySQL 及 rpm 等資料庫系統,都寫在這個目錄內。 * /var/log:登錄檔放置的目錄。很重要啊!例如 /var/log/messages 就是總管所有登錄檔的一個檔案! * /var/lock:某些裝置具有一次性寫入的特性,例如 tab (磁帶機), 此時,為了擔心被其他人干擾而破壞正在運作的動作,因此,會將該裝置 lock (鎖住)起來, 以確定該裝置只能被單一個程序所使用啊! * /var/run:某些程式或者是服務啟動後,會將他們的 PID 放置在這個目錄下喔! * /var/spool:是一些佇列資料存放的地方。舉例來說,主機收到電子郵件後, 就會放置到 /var/spool/mail 當中,若信件暫時發不出去,就會放置到 /var/spool/mqueue 目錄下, 使用者工作排程 (cron) 則是放置在 /var/spool/cron 當中! Alan Cox on open-source development vs. proprietary development | The Open Road - The Business and
blogs.cnet.com/8301-13505_1-9803919-16.html When you release a free software project, you do things in a different order. Firstly, you get some code. Hopefully, it just about works. And you document it as "Needs fixing, needs this, needs that." But most free software code, to get other people involved in the project, it has to work. It doesn't matter if it's hard to compile. It doesn't matter if it only works on one machine in five. And it doesn't matter if it eats the data file every so often. So long as sometimes, the right results happen, people will start to pick up the project and use it. They start to use it, and then they have to fix it. You have marketing. Marketing is important in free software. This is why all free software projects nowadays have web sites. The goal is different. The goal in most conventional marketing is to get users, because users are the people who pay you money to improve the product, and the more users you get, the more you can charge for it because the harder it is to go somewhere else. In the free software world, you do the marketing first, because the website initially is not targeted at the people who will use the software. What you are trying to do is to get developers interested in the actual application. So you're hoping you can find people who see a use for this software who are also programmers, or documentors, or artists, even website designers. It's not uncommon for someone to put up a website for a project, someone will start using the code and say "Well, it's nice code, but I can't program -- but your website is awful" [Laughter] And so you'll find web designers and all sorts of people this way. [Added paragraphs for ease of reading.] 用 Linux 下的网络基本配置命令 ifconfig 就可以完成,假设你的网卡是 eth0:
ifconfig eth0 down
ifconfig eth0 hw ether 12:34:56:78:ab:cd ifconfig eth0 up 把高亮部分替换成你想要改成的 MAC 地址即可,成功的话程序没有任何输出 让 LaTeX Symbols Selector 帮你写 TeX 公式 - LinuxGem
www.linuxgem.org/tip/use-lss-help-you-writer-tex-m... LaTeX Symbols Selector (简称 LSS),是一款写 TeX 数学公式时的辅助软件,TeX 中众多的数学符号名称和常量名称,想要全部记住可不是件容易的事情,忘记的时候,可以让 LSS 来帮你。 LSS 有以下特点:
如果你想要 LSS 与 gVIM 交互,需要在你的 ~/.vimrc 中加入下面的配置:
autocmd BufWinEnter *.tex imap <F8> <Esc>:silent !lss &<cr>a
LSS 的主页: 我心目中的 Linux Distribution這篇 blog entry 主要是源自我過去在 Sayya BBS 個人板發表的札記,略作整理而成,必須聲明的是,每個人的喜好不同,這是單純是我個人的見解與需求,如得罪處,還請多包涵。至於整理發表的動機為何?主要是 Jan 15, 2005 參加 GOT 使用者聚會時,lloyd 前輩分享在賽陽 300 MHz 的筆記型電腦安裝 Gentoo,從零到 X Window System 安裝到好,前後耗費兩個月時間的經驗談,讓我有很大的震撼,當然啦,這樣的等待是值得的,因為整體效能因為針對 i586/MMX 以及許多自訂的 USE flags 而有所改進。 問題是,為何我們要花這麼多時間準備一個套件 (bootstraping) 呢?能否從 binary package 提供一勞永逸的解決方案?能否兼具便利與效能呢?... 種種的疑惑再度盤據於我心,於是,我試著分析現有 Linux Distributions 的特性,以及我的心得。 我玩過的 Linux Distro 有: 如果說推薦,我會說 Debian,但是真正欣賞的是 Linux Mandrake 與 Peanut Linux,特別是後者,讓我愛不釋手。就務實的角度來說,Debian 作得相當不錯,彈性相當大,也有相當驚人的開發者數量,但是,對我來說,還是欠缺了一種感覺,一種引人入勝的方式。 Debian 許多 policy 都是非常值得參考的,前瞻性也相當夠,但是卻也犧牲了許多特性,讓人覺得難以親近。有一度很沈迷 Debian 時,曾以成為 DebianDeveloper 為目標,但是現在卻完全不會有此念頭,這是因為現在的 Debian 已經不是我心目中的 Debian。與其說我厭倦 Debian,還不如說我一直在尋求 "The Better Debian",ubuntu 剛推出時,吸引我頗多目光,大抵符合我的需求,但實際體驗後,發現還是有若干特徵沒有實作出來。 Linux Mandrake 有著令人驚豔的外觀與整合性工具,幾乎大項目都有 *Drake 的 toolset 可協助設定與處理,比方說 localedrake 這隻小程式功能很少,但是非常貼心,放眼看其他 Linux distro,卻很少有提出類似的設計。但是 Linux Mandrake 在我的感覺還是不夠嚴謹,當然,我的認知只到 MDK 9.2,後續的版本我沒有接觸過,或許有改觀。Linux Mandrake 在跨越 major release 的 upgrade 處理很糟,也一直沒有提出良好的解法,這幾乎是致命傷。 我心目中的 Linux Distribution 至少需要具備以下特徵:
查看 Linux 启动时的信息 处理文件名内含有特殊字符的文件 /proc这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这 扩展ext2使用ext2文件系统上的只添加和不可变这两种文件属性可以进一步提高 HOST的乐趣: Host能够用来查询域名,然而它可以得到更多的信息。host -t mx linux.com可以查询出Linux.com的MX记录,以及处理Mail的Host的名字。Host -l linux.com会返回所有注册在linux.com下的域名。host -a linux.com则会显示这个主机的所有域名信息。 找到命令需要的文件,也许你希望搞清楚一个命令它到底使用到了什么其他相关文件和命令?试试ldd就可以了。如ldd traceroute,返回结果会是libc.so.6,lid-linux.so.2 在使用less 或 more时,直接启动编辑器:在less中打入v键,会立即启动vi或其他你在环境变量中指明的编辑器,但是more只能使用vi 压缩可执行文件 把 man 或 info 的信息存为文本文件 aMule + VeryCD.com under Ubuntu EdgySunday, 25. February 2007, 13:44:49 1,安装aMule sudo apt-get install amule amule-utils2,设置服务器 在aMule的主页面的Server栏中添加:http://www.emule.org.cn/server.met,这个就是verycd.com对应的服务器列表。完成后在“设置”中将aMule的昵称设置为[CHN][VeryCD]yourname,yourname随便设一个即可。 3,设置firefox与aMule关联 首先,在aMule的“设置”中将Browser Selection选择为Mozilla Firefox,并将“连接”便签下的上传速率调高至10kb/s以上,否则用电螺时下载速度会受限制(准确地说是几乎为0)。然后,设置Firefox的键值。在Firefox的地址栏中键入about:config,即可打开键值的配置页面。 (1) 新建一个boolean类型network.protocol-handler.external.ed2k,值为true表示处理ed2k的协议其中/usr/bin/ed2k是你的系统中ed2k命令所在的路径。可以用 whereis ed2k查看。经过这样的设置后,重启Firefox和aMule,进入verycd.com选择中意的种子,点击后就会弹出选定ed2k程序的对话框,确定即可。 另外,aMule的其他设置我都没有改动,端口号分别为Tcp:4662,Udp:4672。 编译原理学习导论
大学课程为什么要开设编译原理呢?这门课程关注的是编译器方面的产生原理和技术问题,似乎和计算机的基础领域不沾边,可是编译原理却一直作为大学本科的必修课程,同时也成为了研究生入学考试的必考内容。编译原理及技术从本质上来讲就是一个算法问题而已,当然由于这个问题十分复杂,其解决算法也相对复杂。我们学的数据结构与算法分析也是讲算法的,不过讲的基础算法,换句话说讲的是算法导论,而编译原理这门课程讲的就是比较专注解决一种的算法了。在20世纪50年代,编译器的编写一直被认为是十分困难的事情,第一Fortran的编译器据说花了18年的时间才完成。在人们尝试编写编译器的同时,诞生了许多跟编译相关的理论和技术,而这些理论和技术比一个实际的编译器本身价值更大。就犹如数学家们在解决著名的哥德巴赫猜想一样,虽然没有最终解决问题,但是其间诞生不少名著的相关数论。
推荐参考书 虽然编译理论发展到今天,已经有了比较成熟的部分,但是作为一个大学生来说,要自己写出一个像Turboc C,Java那样的编译器来说还是太难了。不仅写编译器困难,学习编译原理这门课程也比较困难。 正是因为编译原理学习相对困难,那么就要求有好的教师和好的教材。教师方面不是我们能自己更改的,而在教材方面我们却可以按自己的意愿来阅读。我下面推荐几本好的编译原理的教材。我推荐的书籍都是国外的经典教材,因为在国内的教材中,确实还没发现什么让人满意的。
第一本书的原名叫《Compilers Principles,Techniques,and Tools》,另外一个响亮的名字就是龙书。原因是这本书的封面上有条红色的龙,也因为这本书在编译原理基础领域确实太有名气了,所以很多国外的学者都直接取名为龙书。最近机械工业出版社已经出版了此书的中文版,名字就叫《编译原理》。该书出的比较早,大概是在85或86年编写完成的,作者之一还是著名的贝尔实验室的科学家。里面讲解的核心编译原理至今都没有变过,所以一直到今天,它的价值都非凡。这本书最大的特点就是一开始就通过一个实际的小例子,把编译原理的大致内容罗列出来,让很多编译原理的初学者很快心里有了个底,也知道为什么会有这些理论,怎么运用这些理论。而这一点是我感觉国内的教材缺乏的东西,所以国内的教材都不是写给愿意自学的读者,总之让人看了半天,却不知道里面的东西有什么用。 第二本书的原名叫《Modern Compiler Design》,中文名字叫做《现代编译程序设计》。该书由人民邮电出版社所出。此书比较关注的是编译原理的实践,书中给出了不少的实际程序代码,还有很多实际的编译技术问题等等。此书另外一个特点就是其“现代”而字。在传统的编译原理教材中,你是不可能看到如同Java中的“垃圾回收”等算法的。因为Java这样的解释执行语言是在近几年才流行起来的东西。如果你想深入学习编译原理的理论知识,那么你肯定得看前面那本龙书,如果你想自己动手做一个先进的编译器,那么你得看这本《现代编译程序设计》。 第三本书就是很多国内的编译原理学者都推荐的那本《编译原理及实践》。或许是这本书引入国内比较早吧,我记得我是在高中就买了这本书,不过也是在前段时间才把整本书看完。此书作为入门教程也的确是个不错的选择。书中给出的编译原理讲解也相当细致,虽然不如前面的龙书那么深入,但是很多地方都是点到为止,作为大学本科教学已经是十分深入了。该书的特点就是注重实践,不过感觉还不如前面那本《现代编译程序设计》的实践味道更重。此书的重点还是在原理上的实践,而非前面那本那样的技术实践。《编译原理及实践》在讲解编译原理的各个部分的同时,也在逐步实践一个现代的编译器Tiny C.等你把整本书看完,差不多自己也可以写一个Tiny C了。作者还对Lex和Yacc这两个常用的编译相关的工具进行了很详细的说明,这一点也是很难在国内的教材中看到的。
推荐了这三本教材,都有英文版和中文版的。很多英文好的同学只喜欢看原版的书,不我的感觉是这三本书的翻译都很不错,没有必要特别去买英文版的。理解理论的实质比理解表面的文字更为重要。
编译原理的实质 前面已经说过,学习编译原理其实也就是学习算法而已,没什么特别的。只不过这些算法的产生已经形成了一套理论。下面我来看看编译原理里面到底有什么高深的理论吧。
几乎每本编译原理的教材都是分成词法分析,语法分析(LL算法,递归下降算法,LR算法),语义分析,运行时环境,中间代码,代码生成,代码优化这些部分。其实现在很多编译原理的教材都是按照85,86出版的那本龙书来安排教学内容的,所以那本龙书的内容格式几乎成了现在编译原理教材的定式,包括国内的教材也是如此。一般来说,大学里面的本科教学是不可能把上面的所有部分都认真讲完的,而是比较偏重于前面几个部分。像代码优化那部分东西,就像个无底洞一样,如果要认真讲,就是单独开一个学期的课也不可能讲得清楚。所以,一般对于本科生,对词法分析和语法分析掌握要求就相对要高一点了。
词法分析相对来说比较简单。可能是词法分析程序本身实现起来很简单吧,很多没有学过编译原理的人也同样可以写出各种各样的词法分析程序。不过编译原理在讲解词法分析的时候,重点把正则表达式和自动机原理加了进来,然后以一种十分标准的方式来讲解词法分析程序的产生。这样的做法道理很明显,就是要让词法分析从程序上升到理论的地步。
语法分析部分就比较麻烦一点了。现在一般有两种语法分析算法,LL自顶向下算法和LR自底向上算法。LL算法还好说,到了LR算法的时候,困难就来了。很多自学编译原理的都是遇到LR算法的理解成问题后就放弃了自学。其实这些东西都是只要大家理解就可以了,又不是像词法分析那样非得自己写出来才算真正的会。像LR算法的语法分析器,一般都是用工具Yacc来生成,实践中完全没有比较自己来实现。对于LL算法中特殊的递归下降算法,因为其实践十分简单,那么就应该要求每个学生都能自己写。当然,现在也有不少好的LL算法的语法分析器,不过要是换在非C平台,比如Java,Delphi,你不能运用YACC工具了,那么你就只有自己来写语法分析器。
等学到词法分析和语法分析时候,你可能会出现这样的疑问:“词法分析和语法分析到底有什么?”就从编译器的角度来讲,编译器需要把程序员写的源程序转换成一种方便处理的数据结构(抽象语法树或语法树),那么这个转换的过程就是通过词法分析和语法分析的。其实词法分析并非一开始就被列入编译器的必备部分,只是我们为了简化语法分析的过程,就把词法分析这种繁琐的工作单独提取出来,就成了现在的词法分析部分。除了编译器部分,在其它地方,词法分析和语法分析也是有用的。比如我们在DOS,Unix,Linux下输入命令的时候,程序如何分析你输入的命令形式,这也是简单的应用。总之,这两部分的工作就是把不“规则”的文本信息转换成一种比较好分析好处理的数据结构。那么为什么编译原理的教程都最终把要分析的源分析转换成“树”这种数据结构呢?数据结构中有Stack, Line,List…这么多数据结构,各自都有各自的特点。但是Tree这种结构有很强的递归性,也就是说我们可以把Tree的任何结点Node提取出来后,它依旧是一颗完整的Tree。这一点符合我们现在编译原理分析的形式语言,比如我们在函数里面使用函树,循环中使用循环,条件中使用条件等等,那么就可以很直观地表示在Tree这种数据结构上。同样,我们在执行形式语言的程序的时候也是如此的递归性。在编译原理后面的代码生成的部分,就会介绍一种堆栈式的中间代码,我们可以根据分析出来的抽象语法树,很容易,很机械地运用递归遍历抽象语法树就可以生成这种指令代码。而这种代码其实也被广泛运用在其它的解释型语言中。像现在流行的Java,.NET,其底层的字节码bytecode,可以说就是这中基于堆栈的指令代码的。
关于语义分析,语法制导翻译,类型检查等等部分,其实都是一种完善前面得到的抽象语法树的过程。比如说,我们写C语言程序的时候,都知道,如果把一个浮点数直接赋值给一个整数,就会出现类型不匹配,那么C语言的编译器是怎么知道的呢?就是通过这一步的类型检查。像C++语言这中支持多态函数的语言,这部分要处理的问题就更多更复杂了。大部编译原理的教材在这部分都是讲解一些比较好的处理策略而已。因为新的问题总是在发生,旧的办法不见得足够解决。
本来说,作为一个编译器,起作用的部分就是用户输入的源程序到最终的代码生成。但是在讲解最终代码生成的时候,又不得不讲解机器运行环境等内容。因为如果你不知道机器是怎么执行最终代码的,那么你当然无法知道如何生成合适的最终代码。这部分内容我自我感觉其意义甚至超过了编译原理本身。因为它会把一个计算机的程序的运行过程都通通排在你面前,你将来可能不会从事编译器的开发工作,但是只要是和计算机软件开发相关的领域,都会涉及到程序的执行过程。运行时环境的讲解会让你更清楚一个计算机程序是怎么存储,怎么装载,怎么执行的。关于部分的内容,我强烈建议大家看看龙书上的讲解,作者从最基本的存储组织,存储分配策略,非局部名字的访问,参数传递,符号表到动态存储分配(malloc,new)都作了十分详细的说明。这些东西都是我们编写平常程序的时候经常要做的事情,但是我们却少去探求其内部是如何完成。
关于中间代码生成,代码生成,代码优化部分的内容就实在不好说了。国内很多教材到了这部分都会很简单地走马观花讲过去,学生听了也只是作为了解,不知道如何运用。不过这部分内容的东西如果要认真讲,单独开一学期的课程都讲不完。在《编译原理及实践》的书上,对于这部分的讲解就恰到好处。作者主要讲解的还是一种以堆栈为基础的指令代码,十分通俗易懂,让人看了后,很容易模仿,自己下来后就可以写自己的代码生成。当然,对于其它代码生成技术,代码优化技术的讲解就十分简单了。如果要仔细研究代码生成技术,其实另外还有本叫做《Advance Compiler Desgin and Implement》,那本书现在由机械工业出版社引进的,十分厚重,而且是英文原版。不过这本书我没有把它列为推荐书给大家,毕竟能把龙书的内容搞清楚,在中国已经就算很不错的高手了,到那个时候再看这本《Advance Compiler Desgin and Implement》也不迟。代码优化部分在大学本科教学中还是一个不太重要的部分,就是算是实践过程中,相信大家也不太运用得到。毕竟,自己做的编译器能正确生成执行代码已经很不错了,还谈什么优化呢?
关于实践 编译原理的课程毕竟还只是讲解原理的课程,不是专门的编译技术课程。这两门课程是有很大的区别的。编译技术更关注实际的编写编译器过程中运用到的技术,而原理的课关注讲解其基本理论。但是计算机科学本身就是一门实践性很强的课程,如果能够学以致用,那才叫真正的学会。李阳在讲解疯狂英语的时候就说到,只要当你会实际中运用一个单词一个词组的时候你才能叫学会了这个单词或者词组,而不是只是知道了它的拼写和意思。其实任何学习都是一样的,如果缺少了实践的结合,你不能算学会。
编译原理的课程主要就是讲解编译器产生的理论和原理,那么很简单,自己写个编译器就是最好的实践过程了。不过你得小心,编译系统可能是所有软件系统中最复杂的系统之一,不然为什么大学里面还会把编译器的编写开成一门叫做编译原理的课程来讲?我很佩服那些学了操作系统原理就开始自己写操作系统,学了编译原理就开始自己写编译器的人们,确实,在中国,敢这么做的学生太少了。且不管你这样做能不能做成功,至少有了这个尝试,会让你的程序设计,系统规划安排的功底增进不少。我下面给出一些关于实践过程中可能会遇到的困难,希望能够在你陷入困境的前帮你一把。
1. Lex和Yacc. 这两工具是作为词法分析很语法分析的工具。如果你自己写一个编译器,我十分不建议你连词法分析这种事情都亲手来写。Lex和Yacc应该是作为每本编译原理的教材的必备内容,可是在国内的教材中缺很少看到。这两个工具是Unix系统下的小东西,如果你要在Windows中运用,那么你最好去下在cygwin这个软件。它是个在Windows下模拟Unix的东东,里面就包含了flex.exe和bison.exe(yacc)这两个工具.这两个工具使用起来还挺麻烦的(其实unix 下的很多十分有用的工具都是这样), 不过在《编译原理与实践》这本书上对于这两个工具的讲解十分详细,还列举了不少实际的例子。 2. 做解释型语言比做生成机器代码的编译器简单。虽然说,做解释型的编译器,像Java那样的,你还得自己去写解释器,不过这样你就不必去查找机器代码的资料了。如果你做生成的最终机器代码编译器可能会遇到问题还有就是寄存器为基础的代码生成方法。前面说过,如果你生成的是以堆栈为基础的代码,那么其代码生成过程十分简单,需要考虑的东西也不多,如果你考虑最终的机器代码生成的话,你必须考虑机器的寄存器如何分配等麻烦的问题。 3. 考虑用别人已经生成的语法文件,尽量不要自己动手写词法文件和语法文件.以前一个朋友曾经说过,写出一个好的程序语言的语法定义,就几乎完成了一个编译器的一半.确实是这样,语法文件的编写是个很难的事情.现在网上到处都可以找到比如C语言,C++,Java, Tiny C,Minus C等语言的词法文件和语法文件,你完全可以自己下下来来用.
在《编译原理及实践》的书中,作者给出了一个Tiny C的全部代码.我自我感觉作者的这个编译器做得很不错,相对于其它php,perl等语言的源代码来说,简单得多,容易看懂,而且很清晰地展现了一个完成的编译系统的实现过程.其源代码可以在作者的网站上下载.
后话 编译原理的学习可能算是一个困难的历程,特别是对于那些不对编译系统感兴趣的同学来说.既然它已经作为了大学本科的必修课程,那么就说明的它引申出来的一套理论在整个计算机科学领域还是占有相对重要的地位. 如果我们考究一下历史,就会发现很多被称为程序设计大师的人都是编译领域的高手.写出第一个微型机上运行的Basic语言的比尔盖茨,设计出Delphi的Borland的”世界上最厉害的程序员”, Sun的JAVA之父, 贝尔实验室的C++之父… 本文以Redhat 6.0 Linux 2.2.19 for Alpha/AXP为平台,描述了从开机到登录的 Linux 启动全过程。该文对i386平台同样适用。 在Alpha/AXP平台上引导Linux通常有两种方法,一种是由MILO及其他类似的引导程序引 导,另一种是由Firmware直接引导。MILO功能与i386平台的LILO相近,但内置有基本的磁盘 驱动程序(如IDE、SCSI等),以及常见的文件系统驱动程序(如ext2,iso9660等), firmware有ARC、SRM两种形式,ARC具有类BIOS界面,甚至还有多重引导的设置;而SRM则具 有功能强大的命令行界面,用户可以在控制台上使用boot等命令引导系统。ARC有分区 (Partition)的概念,因此可以访问到分区的首扇区;而SRM只能将控制转给磁盘的首扇区。 两种firmware都可以通过引导MILO来引导Linux,也可以直接引导Linux的引导代码。 “arch/alpha/boot”下就是制作Linux Bootloader的文件。“head.S”文件提供了对 OSF PAL/1的调用入口,它将被编译后置于引导扇区(ARC的分区首扇区或SRM的磁盘0扇区), 得到控制后初始化一些数据结构,再将控制转给“main.c”中的start_kernel(), start_kernel()向控制台输出一些提示,调用pal_init()初始化PAL代码,调用openboot() 打开引导设备(通过读取Firmware环境),调用load()将核心代码加载到START_ADDR(见 “include/asm-alpha/system.h”),再将Firmware中的核心引导参数加载到ZERO_PAGE(0) 中,最后调用runkernel()将控制转给0x100000的kernel,bootloader部分结束。 Bootloader中使用的所有“srm_”函数在“arch/alpha/lib/”中定义。 以上这种Boot方式是一种最简单的方式,即不需其他工具就能引导Kernel,前提是按照 Makefile的指导,生成bootimage文件,内含以上提到的bootloader以及vmlinux,然后将 bootimage写入自磁盘引导扇区始的位置中。 当采用MILO这样的引导程序来引导Linux时,不需要上面所说的Bootloader,而只需要 vmlinux或vmlinux.gz,引导程序会主动解压加载内核到0x1000(小内核)或0x100000(大 内核),并直接进入内核引导部分,即本文的第二节。 对于I386平台 在“arch/i386/boot”目录下,bootsect.S是生成引导扇区的汇编源码,它首先将自己 拷贝到0x90000上,然后将紧接其后的setup部分(第二扇区)拷贝到0x90200,将真正的内核 代码拷贝到0x100000。以上这些拷贝动作都是以bootsect.S、setup.S以及vmlinux在磁盘上 连续存放为前提的,也就是说,我们的bzImage文件或者zImage文件是按照bootsect,setup, vmlinux这样的顺序组织,并存放于始于引导分区的首扇区的连续磁盘扇区之中。 bootsect.S完成加载动作后,就直接跳转到0x90200,这里正是setup.S的程序入口。 setup.S的主要功能就是将系统参数(包括内存、磁盘等,由BIOS返回)拷贝到 0x90000-0x901FF内存中,这个地方正是bootsect.S存放的地方,这时它将被系统参数覆盖。 以后这些参数将由保护模式下的代码来读取。 除此之外,setup.S还将video.S中的代码包含进来,检测和设置显示器和显示模式。最 后,setup.S将系统转换到保护模式,并跳转到0x100000(对于bzImage格式的大内核是 0x100000,对于zImage格式的是0x1000)的内核引导代码,Bootloader过程结束。 对于2.4.x版内核
对于I386平台 所不同的是,在i386系统中,当内核以bzImage的形式压缩,即大内核方式 (__BIG_KERNEL__)压缩时就需要预先处理bootsect.S和setup.S,按照大核模式使用$(CPP) 处理生成bbootsect.S和bsetup.S,然后再编译生成相应的.o文件,并使用 "arch/i386/boot/compressed/build.c"生成的build工具,将实际的内核(未压缩的,含 kernel中的head.S代码)与"arch/i386/boot/compressed"下的head.S和misc.c合成到一起,其中的head.S代替了"arch/i386/kernel/head.S"的位置,由Bootloader引导执行 (startup_32入口),然后它调用misc.c中定义的decompress_kernel()函数,使用 "lib/inflate.c"中定义的gunzip()将内核解压到0x100000,再转到其上执行 "arch/i386/kernel/head.S"中的startup_32代码。 对于2.4.x版内核
start_kernel()中调用了一系列初始化函数,以完成kernel本身的设置。 这些动作有的是公共的,有的则是需要配置的才会执行的。 在start_kernel()函数中,
对于I386平台 对于2.4.x版内核
init()函数作为核心线程,首先锁定内核(仅对SMP机器有效),然后调用 do_basic_setup()完成外设及其驱动程序的加载和初始化。过程如下:
init()函数到此结束,内核的引导部分也到此结束了,这个由start_kernel()创建的第一个线程已经成为一个用户模式下的进程了。此时系统中存在着六个运行实体:
对于I386平台 对于2.4.x版内核
init进程是系统所有进程的起点,内核在完成核内引导以后,即在本线程(进程)空 间内加载init程序,它的进程号是1。 init程序需要读取/etc/inittab文件作为其行为指针,inittab是以行为单位的描述性(非执行性)文本,每一个指令行都具有以下格式: id:runlevel:action:process其中id为入口标识符,runlevel为运行级别,action为动作代号,process为具体的执行程序。 id一般要求4个字符以内,对于getty或其他login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。 runlevel是init所处于的运行级别的标识,一般使用0-6以及S或s。0、1、6运行级别被系统保留,0作为shutdown动作,1作为重启至单用户模式,6为重启;S和s意义相同,表示单用户模式,且无需inittab文件,因此也不在inittab中出现,实际上,进入单用户模式时,init直接在控制台(/dev/console)上运行/sbin/sulogin。 在一般的系统实现中,都使用了2、3、4、5几个级别,在Redhat系统中,2表示无NFS支持的多用户模式,3表示完全多用户模式(也是最常用的级别),4保留给用户自定义,5表示XDM图形登录方式。7-9级别也是可以使用的,传统的Unix系统没有定义这几个级别。runlevel可以是并列的多个值,以匹配多个运行级别,对大多数action来说,仅当runlevel与当前运行级别匹配成功才会执行。 initdefault是一个特殊的action值,用于标识缺省的启动级别;当init由核心激活 以后,它将读取inittab中的initdefault项,取得其中的runlevel,并作为当前的运行级 别。如果没有inittab文件,或者其中没有initdefault项,init将在控制台上请求输入 runlevel。 sysinit、boot、bootwait等action将在系统启动时无条件运行,而忽略其中的runlevel,其余的action(不含initdefault)都与某个runlevel相关。各个action的定义在inittab的man手册中有详细的描述。 在Redhat系统中,一般情况下inittab都会有如下几项:
上一节已经提到init进程将启动运行rc脚本,这一节将介绍rc脚本具体的工作。 一般情况下,rc启动脚本都位于/etc/rc.d目录下,rc.sysinit中最常见的动作就是激活交换分区,检查磁盘,加载硬件模块,这些动作无论哪个运行级别都是需要优先执行的。仅当rc.sysinit执行完以后init才会执行其他的boot或bootwait动作。 如果没有其他boot、bootwait动作,在运行级别3下,/etc/rc.d/rc将会得到执行,命令行参数为3,即执行/etc/rc.d/rc3.d/目录下的所有文件。rc3.d下的文件都是指向/etc/rc.d/init.d/目录下各个Shell脚本的符号连接,而这些脚本一般能接受start、stop、restart、status等参数。rc脚本以start参数启动所有以S开头的脚本,在此之前,如果相应的脚本也存在K打头的链接,而且已经处于运行态了(以/var/lock/subsys/下的文件作为标志),则将首先启动K开头的脚本,以stop作为参数停止这些已经启动了的服务,然后再重新运行。显然,这样做的直接目的就是当init改变运行级别时,所有相关的服务都将重启,即使是同一个级别。 rc程序执行完毕后,系统环境已经设置好了,下面就该用户登录系统了。
在rc返回后,init将得到控制,并启动mingetty(见第五节)。mingetty是getty的简化,不能处理串口操作。getty的功能一般包括:
注:用于远程登录的提示信息位于/etc/issue.net中。 login程序在getty的同一个进程空间中运行,接受getty传来的用户名参数作为登录 的用户名。 如果用户名不是root,且存在/etc/nologin文件,login将输出nologin文件的内容, 然后退出。这通常用来系统维护时防止非root用户登录。 只有/etc/securetty中登记了的终端才允许root用户登录,如果不存在这个文件, 则root可以在任何终端上登录。/etc/usertty文件用于对用户作出附加访问限制,如果 不存在这个文件,则没有其他限制。 当用户登录通过了这些检查后,login将搜索/etc/passwd文件(必要时搜索 /etc/shadow文件)用于匹配密码、设置主目录和加载shell。如果没有指定主目录,将 默认为根目录;如果没有指定shell,将默认为/bin/sh。在将控制转交给shell以前, getty将输出/var/log/lastlog中记录的上次登录系统的信息,然后检查用户是否有新 邮件(/usr/spool/mail/{username})。在设置好shell的uid、gid,以及TERM,PATH 等环境变量以后,进程加载shell,login的任务也就完成了。
运行级别3下的用户login以后,将启动一个用户指定的shell,以下以/bin/bash为例继续我们的启动过程。 bash是Bourne Shell的GNU扩展,除了继承了sh的所有特点以外,还增加了很多特 性和功能。由login启动的bash是作为一个登录shell启动的,它继承了getty设置的TERM、PATH等环境变量,其中PATH对于普通用户为"/bin:/usr/bin:/usr/local/bin",对于root 为"/sbin:/bin:/usr/sbin:/usr/bin"。作为登录shell,它将首先寻找/etc/profile 脚本文件,并执行它;然后如果存在~/.bash_profile,则执行它,否则执行 ~/.bash_login,如果该文件也不存在,则执行~/.profile文件。然后bash将作为一个 交互式shell执行~/.bashrc文件(如果存在的话),很多系统中,~/.bashrc都将启动 /etc/bashrc作为系统范围内的配置文件。 当显示出命令行提示符的时候,整个启动过程就结束了。此时的系统,运行着内核, 运行着几个核心线程,运行着init进程,运行着一批由rc启动脚本激活的守护进程(如 inetd等),运行着一个bash作为用户的命令解释器。
如果缺省运行级别设为5,则系统中不光有1-6个getty监听着文本终端,还有启动了一个XDM的图形登录窗口。登录过程和文本方式差不多,也需要提供用户名和口令,XDM 的配置文件缺省为/usr/X11R6/lib/X11/xdm/xdm-config文件,其中指定了 /usr/X11R6/lib/X11/xdm/xsession作为XDM的会话描述脚本。登录成功后,XDM将执行这个脚本以运行一个会话管理器,比如gnome-session等。 除了XDM以外,不同的窗口管理系统(如KDE和GNOME)都提供了一个XDM的替代品,如gdm和kdm,这些程序的功能和XDM都差不多。 Selecting text
There are some handy mouse shortcuts for selecting text. As normal a left mouse button drag, selects text but some apps also allow the right mouse button to extend the selection. I.E. you can click or drag the right button to define the extent of the selection. Also in general double clicking selects a word, while triple clicking selects a line (try it now). Once text is selected X has 2 "clipboards" to put it in. The "selection buffer" and the "clipboard". The selection buffer This buffer is updated automatically when you select any text, and is generally the handiest buffer to use, as you can paste from it by clicking the middle mouse button at the required destination. I.E. by clicking the scroll button, or if you only have 2 mouse buttons you can click both simultaneously to emulate the middle mouse button. The clipboard This works much like the windows equivalent. In general apps use the same keys as in windows to control it. I.E. CtrlInsert or Ctrlc for copy, and ShiftInsert or Ctrlv for paste etc. These key combinations may conflict with the app so for example gnome-terminal uses ShiftCtrlc and ShiftCtrlv instead, so more generally one can select copy,cut,paste from the edit menu. Buffer storage Note it's the X application itself that maintains the storage for what it "puts" on the buffers, which makes a lot of sense when you think about it, especially considering X's network transparency. But that means when you close the application the content of the clipboard and selection buffer are lost. You can get around this behaviour by using an external application to manage the storage for the clipboard, the standard one being xclipboard. Note this is the reason why it's awkward to get a command line program to paste to the clipboard. It has to fork and run until no longer required (someone else pastes to the clipboard). Search for xsel for an example of this. command &
command 在子 shell 的 background 运行。后台任务让多成程序能够运行在一个 shell 里面。 ------------------------------------------------------------------ command1 | command2 command1 的标准输出被直接输入到 command2 的标准输入。两个命令都可能并行地运行。这个被称作pipeline。 ------------------------------------------------------------------ command1 ; command2 command1command2 被有序的执行。 ------------------------------------------------------------------ command1 && command2 command1 如果执行成功的话那么再执行 command2。只有当 command1并且command2 都运行成功的话上面的命令序列才会成功返回。 ------------------------------------------------------------------ command1 || command2 command1 被执行以后,如果不成功的话,command2 也会被执行。当 command1 或者command2 有一个执行成功的话,上面的序列就会返回真值。
X的配置命令是XConfig,可以配置显卡。 |