随笔-341  评论-2670  文章-0  trackbacks-0
    可扩展编译器架构的构想是最近几天在洗澡的时候才最终完成的。我在思考如何开发一个可以同时给C、Pascal、Basic、Fortran和未知的类似语言使用的前端+后端。这只是VL++3.0的其中一个小部分,我把语言归为几类,C一类,C#一类,Javascript一类,还有其他的等等。这些类型会分别提供不同的前端支持。在设计第一类的编译器期间遇到了点困难。

    第一个困难是语法树很难统一。其实这并不是说那些语言完全不同,而是在于我想让这N种语言的区别只有从字符串到语法树的部分,从语法树开始都执行相同的代码来编译。这就遇到了点麻烦。在语法分析的过程中,对于Pascal我不知道Name(Param)究竟是函数调用还是强制类型转换,对于Basic来说我不知道Name(Param)是函数调用还是数组下标。还有Pascal和Basic的and等操作符可以同时作用于整数和布尔型(C使用了&&和&,而且它们在实现上有巨大差别)。Pascal自己还扩展了一些类型譬如说set,Pascal和Basic还有字符串。所以在语法分析的时候很难构直接造出FunctionInvokeExpression、SubscribeExpression和TypeCastExpression。

    第二个困难是扩展的类型。上面提到了Pascal有自己的set,我如何让我的编译器从前端开始就可以应付一门类似的未知语言他自己的新东西。譬如说未知的set类型,他也有自己的操作符(连已经存在的操作符operator+也可以用的),代码生成的时候还有自己的方法。这不仅要求语法树是可扩展的,接下来的一切包括符号表、语义分析、代码生成等所有部分都需要可扩展的。

    第三个困难是C自己造成的,他有一个十分讨厌的地方。当我得到ABC*DEF;的时候,语义分析没开始,我不可能知道这是乘法还是定义一个变量。

    思考了许久,得出一个大概的方案:我先定义一门比较严格的语言,然后让C、Pascal、Basic和Fortran来定义自己与该语言的不同之处,从而尽可能复用编译器其余相同的部分。想到这里我得到一个比较奇怪的做法:

    第一个做法是在语义分析的时候修改语法树。对于C语言的ABC*DEF;,这是一个statement。我给出一个接口,这个接口在语义分析的过程中被调用。语义分析产生了大量的信息全部传递过去,然后再第一次接触到一个statement的时候,调用其中的ReplaceStatement函数。这个时候接口的ReplaceStatement可以通过语义分析的结果看看需不需要修改这个节点。如果上下文是int a,b;,那么a*b;就会被替换为乘法表达式。如果上下文是typedef int a;,那么a*b;保持不变(因为我默认是优先看成变量声明)。ReplaceStatement对于同一个statement只会调用一次。至于Pascal的集合操作也可以通过这个来完成。对于a+b,可以在ReplaceExpression里面查看a和b是不是集合类型,如果是的话替换成自己的PascalSetBinaryExpression。这个小技巧解决了语法分析的时候遇到的歧义问题。这也是没有办法的办法,因为这一次设计出来的结构的目的是为了让新的语言可以用很小的代价来实现。

    第二个做法是语法树的所有部分譬如Type、Expression、Statement和Declaration都存在一个ExtendedType、ExtendedExpression、ExtendedStatement和ExtendedDeclaration,语言可以通过继承这四个“扩展类”来提供未知的东西,当然这个时候就要连带提供所有操作了,譬如说根据语义分析的上下文来判断他自己的ExtendedExpression的返回类型啦。

    至于符号表的可扩展性,我设计了一个可以应付绝大多数情况的通用符号表,因此随时加入新的东西还是比较容易的。

    最新的代码可以在http://vlpp.codeplex.com/这里获得。
posted on 2010-01-31 00:13 陈梓瀚(vczh) 阅读(2443) 评论(5)  编辑 收藏 引用 所属分类: VL++3.0开发纪事

评论:
# re: Vczh Library++3.0之可扩展编译器架构 2010-01-31 07:29 | heixia108
gcc 就可以扩展 :)   回复  更多评论
  
# re: Vczh Library++3.0之可扩展编译器架构 2010-01-31 09:09 | 陈梓瀚(vczh)
@heixia108
扩展gcc的方法是重写整个前端,显然这不叫扩展,应该叫gcc提供了组件给你自己拼装成新编译器。  回复  更多评论
  
# re: Vczh Library++3.0之可扩展编译器架构 2010-02-01 04:50 | SOS
我发现很多人都在洗澡时得到有用的信息。  回复  更多评论
  
# re: Vczh Library++3.0之可扩展编译器架构 2010-02-01 21:22 | xxzh
@陈梓瀚(vczh)
Open Source 的LLVM,微软的Phoenix,应该和你想做编译器扩展差不多,或者更强大。  回复  更多评论
  
# re: Vczh Library++3.0之可扩展编译器架构 2010-02-02 00:35 | 陈梓瀚(vczh)
@xxzh
目的还是不同的,我是想让完全不同等级或范式的语言可以无缝协作。不过这个idea到底行不行还有待验证……  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理