打字猴:1.700436648e+09
1700436648 史蒂夫本人使用Yacc创建了一个新的“可移植C语言编译器”(portable C compiler,PCC),该编译器有用于解析语言的共用前端和用于生成不同计算机体系架构代码的独立后端。如6.5节所述,史蒂夫和丹尼斯在为Interdata 8/32实现Unix时使用了PCC。
1700436649
1700436650 PCC也有其他用户。史蒂夫回忆说:
1700436651
1700436652 “PCC有个意想不到的副产品:Lint程序。它读取程序,标出不可移植或有错的地方,如调用函数时搞错参数数量、使用了与定义不一致的长度等。由于C语言编译器每次只能处理单个源文件,所以Lint很快就成为编写多文件程序时的有用工具。我们将第7版改写为可移植版本时,Lint也有助于强制执行标准,如寻找错误返回为-1 (第6版)而不是null (第7版)的系统调用。许多检查,甚至是可移植性检查,最终都为C语言所吸收。Lint是新功能的有用测试平台。”
1700436653
1700436654 Lint这个名字来自从衣服上捡拾绒毛(lint)的情景。虽然其功能已多被纳入C语言编译器,但其概念体现到了其他语言的类似工具中。
1700436655
1700436656 在之后的多年里,Yacc在1127中心开发的几种语言中发挥了重要作用,其中一些语言将在接下来的几节中介绍。洛琳达·彻丽和我将它用于数学排版语言Eqn。在之后的多年里,我还将Yacc用于文档编制预处理器Pic和Grap(后者与乔恩·本特利合作,图5-2),用于AMPL建模语言,用于至少一个版本的Ratfor,以及其他只短暂存在过的语言。Yacc还被用在第一个Fortran 77编译器f77、本贾尼·斯特劳斯特鲁普的C++预处理器cfront、awk脚本语言(稍后介绍)以及其他各种语言。
1700436657
1700436658
1700436659
1700436660
1700436661 图5-2 乔恩·本特利,约1981年(杰勒德·霍尔兹曼供图)
1700436662
1700436663 Yacc结合了先进的解析技术、极高的效率和方便的用户界面,成为早期语法分析器生成软件中的仅存硕果。今天,除了以完整的独立软件形式出现,它还在其他软件(如由它衍生出来的Bison)中存在,并且在另外几种编程语言中得以重新实现、继续发挥作用。
1700436664
1700436665 2. Lex
1700436666
1700436667
1700436668
1700436669
1700436670
1700436671 1975年,迈克尔·莱斯克(图5-3)写出词法分析器生成软件Lex,它与Yacc交相辉映。Lex程序由一连串的模式(正则表达式)组成,这些模式定义了要识别的“词元”(lexical token)。对于编程语言来说,这些标记是保留字、变量名、运算符、标点符号等元素。与Yacc一样,Lex可以给每个指定标记附加用C语言编写的语义操作。由此,Lex生成C语言程序,该程序读取字符流,识别它找到的标记,并执行相关的语义操作。
1700436672
1700436673
1700436674
1700436675
1700436676 图5-3 迈克尔·莱斯克,约1981年(杰勒德·霍尔兹曼供图)
1700436677
1700436678 迈克[4]写了Lex的第1版。1976年夏天,一位刚从普林斯顿大学毕业的实习生很快对它做了修改。迈克回忆说:
1700436679
1700436680 “埃里克·施密特(Eric Schmidt)在暑期实习时几乎重写了Lex。我之前的版本采用非确定性分析器,无法处理超过16个状态的规则。阿尔·阿霍很不爽,给我找了个暑期生来修复。埃里克适逢其会。”
1700436681
1700436682 埃里克后来在伯克利分校获得博士学位,并于2001年至2011年担任谷歌公司首席执行官一职。
1700436683
1700436684 Yacc和Lex紧密协同。解析过程中,Yacc会反复调用Lex,Lex每次读取足够多的输入来构造完整词元,并将其传回给Yacc。Yacc/Lex组合将编译器的前端组件机械化,能够同时处理复杂的语法和词法结构。例如,有些编程语言的运算符长达两三个字符,如C语言中的++运算符,当词法分析器看到符号+的时候,要接着看,才能知道待处理的运算符是++还是普通的+。手工写这种代码并不算难,但若有人代劳就尤其方便。使用Lex,人们只需要写
1700436685
1700436686 “++” { return PLUSPLUS; }“+”  { return PLUS; }
1700436687
1700436688
1700436689
1700436690
1700436691
1700436692 就能区别开上述两种情形。(PLUS和PLUSPLUS是数学符号的名称,这样C语言代码就比较容易处理。)
1700436693
1700436694 图5-4展示了在创建C语言程序时如何使用Yacc和Lex。该程序是某种语言的编译器。Yacc为语法分析器生成一个C语言文件,Lex为词法分析器生成另一个C语言文件。这两个C语言文件与其他包含语义的C语言文件组合在一起,由C语言编译器编译成可执行程序。这张图是用Pic程序制作的,Pic的结构也正是如此。
1700436695
1700436696
1700436697
[ 上一页 ]  [ :1.700436648e+09 ]  [ 下一页 ]