理论教育 编译器设计之路:实现语法分析

编译器设计之路:实现语法分析

时间:2023-11-04 理论教育 版权反馈
【摘要】:图3-4 语法分析在编译器中的地位语法分析器的输入就是词法分析器输出的单词流。语法分析器没有统一的形式输出形式。事实上,很多编译器将语法分析器作为一个主控模块,由语法分析器驱动语义分析器的方式完成语义分析及中间代码生成。在这种情况下,语法分析器并没有显式的输出。这一观点的提出主要是由于基于归约方式的语法分析器通常借助于语法树描述整个输入源程序的语法层次。这两类语法分析法各有优缺点。

编译器设计之路:实现语法分析

语法分析是编译过程的第二阶段,也是整个编译过程的核心阶段。语法分析的任务就是在词法分析识别得到单词流的基础上,分析并判定程序的语法结构是否符合预定义的文法。语法分析在编译器中的地位如图3-4所示。

978-7-111-32164-4-Chapter03-20.jpg

图3-4 语法分析在编译器中的地位

语法分析器的输入就是词法分析器输出的单词流。当然,读者应该已经明确了词法分析既可以作为独立阶段,也可以作为独立的一遍处理。如果词法分析作为独立的阶段,那么词法分析器将由语法分析器调用,每次调用获得一个单词。如果词法分析作为独立的一遍,那么词法分析器将识别完成所有单词并以单词流的方式传输出至语法分析器。(www.daowen.com)

语法分析器没有统一的形式输出形式。事实上,很多编译器将语法分析器作为一个主控模块,由语法分析器驱动语义分析器的方式完成语义分析及中间代码生成。在这种情况下,语法分析器并没有显式的输出。图3-3中描述的语法树只是经典编译器设计中一种较为常用的输出形式。这一观点的提出主要是由于基于归约方式的语法分析器通常借助于语法树描述整个输入源程序的语法层次。不过,一些现代编译器设计的观点认为基于推导方式的语法分析器并非一定要显式构造语法树,更偏向于在语法分析过程中直接驱动语义分析子程序,而整个驱动语义分析子程序的过程正是一个遍历语法树的过程。这种观点比较适用于基于推导的语法分析法,对于基于归约的语法分析法则稍难实现。当然,是否显式构造语法树并不是完全依赖于编译器设计者的个人意志的,有时,也必须考虑程序设计语言本身的因素。关于显式构造语法树的利弊,“龙书”的描述相对比较权威,有兴趣的读者可以参阅。

前面,笔者已经引入了推导与归约两种分析方法。读者自然会问,是否可以模仿推导或归约方式设计语法分析器呢?答案是肯定的。

主流的语法分析法可以分为两类:一种是基于推导的语法分析法,另一种是基于归约的语法分析法。这两种分析法构造语法树的过程正好相反,前者的构造是从树根开始逐步向树叶发展,而后者是从树叶开始最终生成树根。因此,习惯上将前者称为自上而下的语法分析法(top-down parse),将后者称为自下而上的语法分析法(bottom-up parse)。这两类语法分析法各有优缺点。前者比较轻巧,但对程序设计语言的文法要求较高,适用于手工构造。后者比较完备,但较复杂,一般适用于工具自动生成。实际上,无论是自上而下还是自下而上的语法分析法对程序设计语言的文法都有一定的要求。尤其是自上而下的语法分析法对文法的要求比较高,对于不符合要求的文法是不能使用自上而下的语法分析法的。而自下而上的语法分析法对文法也有一定要求,虽然绝大多数程序设计语言都可以满足此要求,但还是不具有真正的通用性。除了这两类语法分析法,还有一些通用语法分析法(如Earley Parsing)。虽然这些通用语法分析法可以构造适用于任何文法的语法分析器,但是,它们的算法复杂度过高且效率较低,故一般情况下不作考虑。相对于自下而上的语法分析算法而言,自上而下的语法分析算法似乎更受到经典编译器设计者的青睐。笔者分析了一些主流编译器后,发现大多数编译器都是采用自上而下的语法分析算法的,其中最著名的就是GCC与lcc。虽然Stallman最初设计的GCC是使用yacc实现的,但最新的GCC 4.x版本都是采用了自上而下的语法分析算法。Neo Pascal也是应用自上而下的语法分析法实现的。下面将介绍自上而下的语法分析法及其实现。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈