1700436599
UNIX传奇:历史与回忆 5.2 Yacc,Lex,Make
1700436600
1700436601
我们使用语言进行交流,更好的语言可以帮助我们更有效地进行交流。对于用来与计算机交流的人工语言来说,尤其如此。我们希望只说一句“干吧”,计算机就能照办。但为了完成某些工作,我们却只能不厌其烦地说明细节。优秀的编程语言能降低人类与计算机沟通的成本。计算机领域的大量研究都关乎如何创造富有表达能力的语言。
1700436602
1700436603
第7版Unix提供了多种基于语言的工具,其中一些相当新颖。可以说,如果没有Yacc等工具让非专家也能很容易地创造新语言,这些语言中的大多数都不会存在。本节将介绍语言构建工具。总的来说,Unix工具促进了新语言的创造,从而带来了与计算机交流的更好方式。读者可以放心地跳过细节描述,但领会工具促进语言的概念很重要。
1700436604
1700436605
计算机语言的特点主要有两个方面,语法和语义。语法规定了语言是怎样的,什么符合语法,什么不符合语法。语法还定义了语句和函数如何写,算术和逻辑运算符是什么,它们如何组合成表达式,什么名称是合规的,哪些词是保留字,文本字符串和数字如何表达,程序如何格式化等规则。
1700436606
1700436607
语义是指合规语法被赋予的意义:合乎语法的构造的含义或作用是什么。对于第2章中的面积计算程序:
1700436608
1700436609
void main() { float length, width, area; scanf(“%f %f”, &length, &width); area = length * width; printf(“area = %f\n”, area); }
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
[
上一页 ]
[ :1.700436598e+09 ]
[
下一页 ]