长期使用别人设计的程序语言来写程序,你是否曾有念头想过要自己设计一个语言?或许是因为对目前某些语言的某些特性不满,想动手改造,或许是因为想给自己一个有趣的挑战。不管目的为何,我相信有过这样念头的人不少,但实际动手的人却不多,因为设计一个新语言所必经的前几道关卡,其实就是不小的障碍。过去有 YACC(Yet Another Compiler Compiler)等工具可以用来帮助设计新程序语言,但是我发现 XML 可以是另一个选择,甚至有可能是比 YACC 更好的选择,因为你可以很快上手。毕竟 XML 是一般性的工具,用途很广,很可能你们公司已经用 XML 在做计划了,而你也因此对 XML 有一定程度的认知。这使得你不需要花太多时间学习 XML,就可以利用 XML 动手实做出你的程序语言了。
有些人可能会怀疑我的说法,认为以 XML 应用(XML application)的方式来定义程序语言很奇怪,长久以来的经验,使得我们一看到夹杂一堆 tag 的档案就会直觉地认定它是文件,不是程序代码。不要让这种先入为主的观念蒙蔽了你所使用 XML 的应用领域,XML 的用途很广,套句广告词「the only limitation is your imagination(你的想象力是唯一的限制)」。我认为,用 XML 来当程序语言的 meta language 非但可行,甚至很适合。
XML 和程序语言之间都有树状结构化的要求,以下面的 Java 程序为例:
public class Test {
public static void main(String[] args) {
for (int x=0; x<10; x++) {
// do something
}
}
}
如果改用 XML 来表示,可以如下:
<class public=”true”>
<method public=”true” static=”true” return=”void” name=”main”>
<argument_list>
<argument>
<type>String[]</type><name>args</name>
</argument>
</argument_list>
<body>
<for>
<pre>int x=0</pre>
<judgement>x<10<judgement>
<step>x++</step>
<body>
<!-- do something -->
</body>
</for>
</body>
</method>
</class>
你一定会觉得这样变得更凌乱,原始码更长 ......。其实,现在有许多商业或免费的 XML 的编辑软件可以让我们轻易地克服这点,不但可以轻松地编辑,还可以搭配不同的 XSL 产生不同的外观。你还可以搭配 DTD 来使用这些功能强大的 XML 编辑软件,那么程序中出现的错误就会被自动挑出来,等于是在帮你做语法检查。不用你自己设计编辑软件,你的程序语言就可以拥有专业的编辑软件可用。
当然,使用 XML 来设计程序语言,绝对不是只为了上述的那么一点编辑时的好处罢了。设计程序代码剖析器(parser)时,你的程序如果是 XML 格式,你可以只花不到十分钟就写出一个 parser,而别人需要花十天以上。DOM 和 SAX 是很普遍的 XML parser API,不管你选用 IBM 的 XML4J 或 Sun 的 JAXP(当然,还有许多其它公司的产品),它们都支持 DOM 和 SAX,你只消把资料喂过去给这些 API,parse tree「莫名其妙地」就产生出来了。我估计使用 DOM/SAX API 的程序花不到十行就可以剖析 XML 文件,你不会认为需要花上十分钟来写这十行程序吧!
上述编辑和剖析时的好处还不算什么,更大的好处是 XML 可以让你不用写程序就拥有编译器,只要你将将编译所需的 template 写成 XSLT 的格式即可。现在有许多商业或免费的 XSL 程序可以让我们轻易地将某 XML 文件遵照某 XSLT 的规则来转换成另一个。编译出来的结果是另一个 XML 格式(等于是汇编语言),虽然不是 target code,但是和 target code 之间有直接对应的关系。你只要写一个小程序(组译程序)就可以将它转成 target code。大功告成!
所以,只要准备好:
1. 原始语言的 DTD(原始语言的定义)
2. 汇编语言的 DTD(汇编语言的定义)
3. 原始语言转汇编语言的 XSLT
4. 组译程序
你就具有一个实际可用的程序语言了。上述的两个 DTD 和一个 XSLT 都是 XML 文件档。只有组译程序是真的要用 Java 写,但是这个程序通常很短,我估计只需要一百多或几百行程序代码就差不多了,如果你把汇编语言的 DTD 定义得很好的话,甚至会不到一百行。基本上这个组译程序只是在进行 tree traversal,只需要几个 method,就可以一直递回(recursive)呼叫,程序代码当然短。
这篇文章是否引起你实作一个语言的兴趣了?如果是的话,在你开始规划你的程序语言前,我要先给你几个建议:
编译的速度通常会比较慢(虽然你不见得感觉得到),毕竟你用的是一般性的 XSLT 程序,而不是自行开发的编译程序。
如果你拿不定主意要设计一个什么样的语言,而且不想搞得太复杂,你可以拿 Java 语言为模板,再去掉一些功能,定义出一个 Java 语言的 subset,我看这个语言就叫做 Javlet(小 Java)好了。
如果你拿不定主意要设计一个什么样的语言,而且想作出一个华丽的语言,你可以拿 Java 语言为模板,再加上一些功能,定义出一个 Java 语言的 superset,我看这个语言就叫做 JavaDialect(Java 方言)好了。
我必须善尽告知的义务:这个 XSLT 档可能不好设计,毕竟它等于是编译器 : (
你必须选择一个 target code 的平台。我不认为 x86 是好选择,因为执行档架构太复杂,虽然 PPC 可能比 x86 好一点,但还是很复杂。我建议你的 target 平台使用 Java Virtual Machine(Java 虚拟机器),因为 Java Bytecode 架构简单清楚,而且你的程序语言还可以继续使用 Java 的所有 API。Java Bytecode 正是树状架构,组译程序很好写。如果你需要 Java 虚拟机器的知识,可以参考我的「Java 虚拟机器」一书(欧莱礼出版)。
如果真有人做出来了,可别忘了寄一份到 jerry@oreilly.com.tw 给我们瞧瞧。