大多数程序设计语言都支持case或switch语句。无论是C语言的switch,还是Pascal的case,两者都是作为多路分支结构存在的。先来看看Pascal的case语句文法。
【文法5-6】
与C语言的switch语句相比,标准Pascal的case语句主要有两个特点:
(1)除了“case”分支外,标准Pascal不支持包括“default”分支在内的其他任何形式的分支。不过,由于C语言“default“分支的应用还是非常广泛的,因此,有些商用Pascal编译器提供了“else”分支,即用于表示case语句的默认分支,以满足用户的需要。
(2)分支是不允许贯穿的。而在C语言中,除非显式使用break语句,否则case分支默认是贯穿的。
了解了case语句的特点后,就来看看如何翻译case语句。与先前讨论的语句结构不同,case语句的翻译方案并不是唯一的。在现代编译技术中,有三种比较成熟的翻译方案可供选择。下面简单介绍一下各翻译方案及其评价。
最直观的翻译方案就是将case结构转换成一系列条件跳转语句。这种方案是最简单、最易于理解与实现的。不过,该方案生成的IR或者汇编代码不够精简,尤其是翻译C语言的switch语句时,可能会产生许多冗余的跳转及标号。
第二种是散列表方式。散列表方式并不是一种通用的case语句翻译方案,将其推广为任意形式的case语句的翻译并不容易。散列表方式就是通过构造一个散列表,将分支语句的标号存储在散列表内,以分支值作为关键字进行检索。虽然这是一种比较高效的实现方法,但是以分支值为关键字构造散列表却并不简单。(www.daowen.com)
最后也是应用最广泛的一种翻译方案就是跳转表。跳转表方案的基本思想与散列表方式比较类似,都是通过构造分支值与分支标号的关系,以实现分支跳转的目的。然而,主要的区别在于跳转表方案生成的目标代码以顺序检索方式扫描跳转表,匹配分支值并实现跳转。在实际编译器设计中,这种翻译方案的应用非常广泛,包括Delphi、VC++等商用编译器都无一例外。不过,各种商用编译器的具体的实现方案还是存在一定差异的。由于Neo Pascal也是应用跳转表实现case语句翻译的,故本节将着重阐述跳转表翻译方案的实现。下面,就来看一种应用跳转表实现的标准翻译方案,见表5-10。
表5-10 跳转表的翻译方案
注:有些书籍将case语句中的<表达式>称为“选择子”,本书也将沿用这个名词。
关于跳转表方式的说明如下:
(1)应用跳转表处理case分支贯穿的问题(例如,C语言的switch语句)也是非常容易的,只需将执行语句部分中的JMP省略即可。
(2)跳转表的具体形式可能存在差异。有时,跳转表也使用JZ或者其他指令描述。用JZ指令描述跳转表稍复杂,必须将分支值按升(降)序排列,逐一应用加(减)运算及判零实现分支跳转。
(3)跳转表的位置并不一定处于执行语句体的上部,有时可能是处于执行语句体的下部,通常视具体的实现而定。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。