编译原理 Switch语句的分析
来源:互联网 发布:开源 学校网站 php 编辑:程序博客网 时间:2024/06/10 18:45
今天我的编译系统中所有类型的语句分析都完成了——但没有做优化——包括Switch语句,因为我的系统地语法是类似C++语言的所以实现的方式也类似于C++。在"C++、Pascal =(赋值),for,case语句,函数,变量空间的区别"中我已介绍过C++的switch和Pascal的case语句的区别。在这里复制一下其中的switch语句与if-goto语句的转换实例:
switch 语句
switch(a){
case 1:
a += 2;
default:
a += 16;
case 2:
a += 4;
break;
case 3:
a += 8;
}
等价的if-goto语句
if(a == 1)
goto a1;
if(a == 2)
goto a2;
if(a == 3)
goto a3;
goto df;
a1:
a += 2;
df:
a += 16;
a2:
a += 4;
goto end;
a3:
a += 8;
end:
这儿有一个重要的转变就是将case 语句都集中在一起并提前到switch语句的开头。要在编译时就做到这样是有点困难的,他必须要收集所有的case条件语句,然后建立一张跳转表格。C++编译其肯定是做到了,并且case语句达到一定数量时他还会在这些条件和跳转的目标之间建立一个合适的hash函数,而不是一个一个的if判断,从而使得switch语句更高效。(题外话:在pascal的case语句的条件值好像不能多于256个,不知道是出于什么目的,可能也是为了优化吧!)
在我做的编译系统中没有做任何的优化,但是和上面的在语义上是完全等价的,先将上面switch语句对应的四元式列举在下面,并作一定的解释:
0: JNE 5 a 1 // if(a!=1) goto 5 如果不等于1跳转到下一个判断
1: + a a 2 // a += 2
2: JMP 3 // goto 3 跳转到下 default 的内部
3: + a a 16 // a += 16
4: JMP 6 // goto 6 跳转到下一个case 的内部
5: JNE 9 a 2 // if(a!=2) goto 9 如果不等于2跳转到下一个判断
6: + a a 4 // a += 16
7: JMP 13 // goto 13 跳转到结束 对应break
8: JMP 10 // goto 10 跳转到下一个case 的内部
9: JNE 12 a 3 // if(a!=2) goto 12 如果不等于3跳转到下一个判断
10: + a a 8 // a += 16
11: JMP 13 // goto 13 跳转到结束
12: JMP 3 // goto 3 如果没有匹配的 跳转到 default
13: END // 结束
switch 语句
switch(a){
case 1:
a += 2;
default:
a += 16;
case 2:
a += 4;
break;
case 3:
a += 8;
}
等价的if-goto语句
if(a == 1)
goto a1;
if(a == 2)
goto a2;
if(a == 3)
goto a3;
goto df;
a1:
a += 2;
df:
a += 16;
a2:
a += 4;
goto end;
a3:
a += 8;
end:
这儿有一个重要的转变就是将case 语句都集中在一起并提前到switch语句的开头。要在编译时就做到这样是有点困难的,他必须要收集所有的case条件语句,然后建立一张跳转表格。C++编译其肯定是做到了,并且case语句达到一定数量时他还会在这些条件和跳转的目标之间建立一个合适的hash函数,而不是一个一个的if判断,从而使得switch语句更高效。(题外话:在pascal的case语句的条件值好像不能多于256个,不知道是出于什么目的,可能也是为了优化吧!)
在我做的编译系统中没有做任何的优化,但是和上面的在语义上是完全等价的,先将上面switch语句对应的四元式列举在下面,并作一定的解释:
0: JNE 5 a 1 // if(a!=1) goto 5 如果不等于1跳转到下一个判断
1: + a a 2 // a += 2
2: JMP 3 // goto 3 跳转到下 default 的内部
3: + a a 16 // a += 16
4: JMP 6 // goto 6 跳转到下一个case 的内部
5: JNE 9 a 2 // if(a!=2) goto 9 如果不等于2跳转到下一个判断
6: + a a 4 // a += 16
7: JMP 13 // goto 13 跳转到结束 对应break
8: JMP 10 // goto 10 跳转到下一个case 的内部
9: JNE 12 a 3 // if(a!=2) goto 12 如果不等于3跳转到下一个判断
10: + a a 8 // a += 16
11: JMP 13 // goto 13 跳转到结束
12: JMP 3 // goto 3 如果没有匹配的 跳转到 default
13: END // 结束
这样的编译其实有很多是可以做优化的,比如第2句是没有意义的,第8句是永远也运行不到的。当然能够像C++编译其那样优化才是最好的,等我什么时候有大片的时间再做这个优化吧。更希望看到这个文章并对这个感兴趣的人能够帮我做这个优化,如果您感兴趣请和我联系我会为你提供现在所有的源代码和我的设计思想。我期待作您!
原文地址:http://blog.sina.com.cn/s/blog_5526d40f0100orrc.html
- 编译原理 Switch语句的分析
- Clock switch 原理分析
- 通过汇编码理解switch语句的原理
- java switch语句缺少break跳转之后的算法原理
- 关于switch语句中使用String类型的实现原理
- switch语句反汇编分析
- C++中switch的问题(编译原理相关)
- 编译原理之DFA的实现,使用双重switch
- LCC编译器的源程序分析(35)switch语句
- [转载]LCC编译器的源程序分析(35)switch语句
- switch语句的几种反汇编结构及效率分析
- 奇怪的switch语句
- switch语句的应用
- switch语句的参数
- C#的switch语句
- switch语句的使用
- C++的switch语句
- 经典的switch语句
- DWR入门
- Oracle 11g can not exp table without rows
- 美院绘画考级北京办公室考点操作规程
- ubuntu 10.04 更新源
- 跟我一起写 Makefile(五)
- 编译原理 Switch语句的分析
- Delphi 三种气泡提示效果
- Hibernate各种主键生成策略与配置详解
- java.lang.OutOfMemoryError: Java heap space 的解决
- android 入门xml布局文件
- winfrom打开新窗口关闭旧窗口
- 国外开源的PACS服务器
- 让css动起来—-lesscss
- ZOJ Monthly, February 2012 - H Matrix (ZOJ 3578)