打字猴:1.70043661e+09
1700436610
1700436611
1700436612
1700436613
1700436614
1700436615 其语义是,当调用函数main时,它会调用函数scanf,从标准输入中读取两个数据,计算面积,并调用printf输出area =、计算出的面积和换行符(\n)。
1700436616
1700436617 编译器是一种程序,它能将用一种语言编写的东西翻译成另一种语言中语义等同的东西。例如,像C和Fortran之类高级语言的编译器可能会将代码翻译成特定类型计算机的汇编语言;一些编译器将其他语言的代码翻译过来,例如将Ratfor代码翻译成Fortran代码。
1700436618
1700436619 编译过程的第一环节是对程序进行解析(parse),即通过识别名称、常量、函数定义、控制流、表达式等来确定程序的语法结构,以便在后续处理过程中附加合适的语义。
1700436620
1700436621 今天,为编程语言编写语法分析器的技术已相当成熟。但在20世纪70年代早期,它仍是活跃的研究领域,专注于创建程序,将一门语言的语法规则转换为该门语言的高效语法分析器。这种语法分析器生成程序也被称为“编译器-编译器”(compiler-compiler),因为有了它,就能为编译器自动生成语法分析器。编译器-编译器通常会生成语法分析器,还提供在解析过程中遇到特定语法结构时执行代码的能力。
1700436622
1700436623 1. Yacc
1700436624
1700436625
1700436626
1700436627
1700436628
1700436629 1973年,史蒂夫·约翰逊(图5-1)借鉴阿尔·阿霍的语言理论,创建了编译器-编译器YACC(下文写作Yacc)。这个名字源于杰夫·厄尔曼的评论意见,它代表“yet another compiler-compiler”(意为“又一个编译器-编译器”),说明它并不是第一个这种程序。
1700436630
1700436631
1700436632
1700436633
1700436634 图5-1 史蒂夫·约翰逊,约1981年(杰勒德·霍尔兹曼供图)
1700436635
1700436636 Yacc程序由语言的语法规则和附加在规则上的语义操作组成,在解析过程中检测到特定的语法结构时,程序执行相应的语义操作。例如,使用Yacc伪代码,算术表达式的部分语法可能是:
1700436637
1700436638 expression := expression + expression expression := expression * expression
1700436639
1700436640
1700436641
1700436642
1700436643
1700436644 相应的语义操作大概是生成代码,将两个表达式的结果相加或相乘,得到结果。Yacc将这条规则转换为C语言程序,接受和解析输入,执行语义操作。
1700436645
1700436646 乘法比加法具有更高的优先级(乘法在加法之前完成),通常编译器作者需要编写更复杂的规则来处理这类情况,但在Yacc中,运算符的优先级和关联性可以单独声明,而不必通过额外语法规则来指定,这对于非专业用户来说大大简化了。
1700436647
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
[ 上一页 ]  [ :1.70043661e+09 ]  [ 下一页 ]