Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1531090
  • 博文数量: 3500
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 43870
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-03 20:31
文章分类

全部博文(3500)

文章存档

2008年(3500)

我的朋友

分类:

2008-05-04 23:10:36

一起学习
Java历来是一种以不变应万变的语言。在Java 5中,annotation的引入使得Java在某些特殊的应用场合(如企业应用)中能够进行定制。Annotations 可被看作是用Java核心技术来定义的"领域特定语言"(Domain Specific Languages,DSLs)。

Annotation本质上是一种 name-value 形式的绑定,仅限于它们所能表达的意义。它们不能定义新的语法结构,例如为collection增加个"select"。事实上annotations的存在揭示了Java本身需要DSL的兼容,但是却缺乏能够完全实现DSL所必要的丰富性。

在这里我们为使Java能够支持自定义语义给出了一些建议和方案。如果能够进行一些适当的"扩展"(extension),在不与现有的语法冲突的情况下并且保留向后兼容。例如:用一些语法定义类来产生新的语法结构,姑且称之为 "语义类",这样就能够以现有方式在程序中得以实现。我们把这个方案称之:XJ (eXtensible Java,可扩展Java)

XJ给Java带来了这个所谓的"语义类"。一个语义类也是一个有通常语法的的Java类,当Java解析器遇到由语义类定义的语法结构,那么就用语义类中定义的语法来处理这些输入信息。如果解析成功,那这些语法可以合成为一个Java抽象语法树(AST:abstract syntax tree )。一个抽象语法树可以有一个标准接口被Java编译器所使用当处理语法的时候。AST的新类型可以通过实现合适的接口来进行创建。

考虑到JAVA中的一个简单语言结构:依据某些条件从一个collection中选一个元素出来。一个使用新结构的例子如下所示:

Java代码复制代码
  1. import language mylang.Select;
  2. public Person getChild(Vector people) {
  3. @Select Person p from people where p.age < 18 {
  4. return p;
  5. }
  6. else { return null; }
  7. }


这个新的语法接口可以叫做"Select",用"@"符号定义在语法类饮用的的前缀。定义了一个Vector从中选出条件为年纪小于18岁的人群。最后返回满足条件的值,或者返回空值。Select的语法定义如下。

Java代码复制代码
  1. public Person getChild(Vector people) {
  2. for(int i = 0; i < people.size(); i ) {
  3. Person p = people.elementAt(i);
  4. if(p.age < 18)
  5. return p;
  6. }
  7. return null;
  8. }


同理,通过XJ,一个新的语法接口通过定义语义类来定义。一个语义类包括语法由Java解析器来处理具体的程序语法并且返回一个AST。一旦一个语义类被定义,它就能通过在语义定义符号"@"后定义从而在程序代码中被使用。select的结构定义如下:

Java代码复制代码
  1. package mylang;
  2. import language java.syntax.Grammar;
  3. import java.syntax.AST;
  4. import java.syntax.Block;
  5. import java.syntax.Context;
  6. import java.syntax.Statement;
  7. import java.syntax.Sugar;
  8. import java.syntax.Type;
  9. import java.syntax.Var;
  10. public class Select extends Sugar {
  11. private Type type;
  12. private Var var;
  13. private AST collection;
  14. private AST test;
  15. private Block body;
  16. private Block otherwise;
  17. public Select(Type T,String n,AST c,AST t,Block b,Block o){
  18. type = T;
  19. var = new Var(n);
  20. collection = c;
  21. test = t;
  22. body = b;
  23. otherwise = o;
  24. }
  25. // Select Grammar definition
  26. @Grammar extends Statement {
  27. Select ::=
  28. T = Type
  29. n = Name
  30. 'from' c = Exp
  31. 'when' t = Exp
  32. b = Block
  33. o = ('else' Block | { return new Block(); })
  34. { return new Select(T,n,c,t,b,o); }. }
  35. // Desugar to produce an abstract syntax tree
  36. public AST desugar(Context context) {
  37. Class cType = context.getType(collection);
  38. if(isVector(cType))
  39. return desugarVector(cType,contect);
  40. else // More cases...
  41. }
  42. public AST desugarVector(Class cType,Context context) {
  43. Var done = context.newVar();
  44. Var coll = context.newVar();
  45. return
  46. [| boolean = false;
  47. coll = ;
  48. for(int i = 0; i < .size(); i ) {
  49. = .elementAt(i);
  50. if() {
  51. = true;
  52. ;
  53. }
  54. }
  55. if(!)
  56. ;
  57. |];
  58. }
  59. }


从Select的语法规则定义可以看到一个良好格式的语句是通过一个名称,关键字"from"及其表达式,关键字"when"及其表达式,以及定义select块的正文。在正文后,还可以定义if-else之类的可选关键字。在select规则中的每个case中,解析元素产生一个可以和名称可选关联的值。例如,和名称为"T"相关联的类型。另外,解析规则也包含返回值的Java语句。这些包含在{and}中,而且可以引用任何在后面定义的名称。由Select rule返回最终结果是Select类的一个实例。

由语法所决定的返回值必须是java.syntax.AST类的一个实例。如果返回值是标准Java AST类的实例,那在语法类中不需要做特殊处理。如果返回值是自定义语法类的实例,那么这个类必须实现AST接口,来由编译器翻译成Java VM识别的代码。更简单易行的办法是用户自定义语义类从java.syntax.Sugar继承,而java.syntax.Sugar通过desugar方法实现了AST接口。desugar方法负责把输入的信息解释为接口中已经定义的AST(抽象语法树),

在这篇短文中我们介绍了Java的扩展(XJ),主要是通过定义新的Java语法来对Java语言本身进行扩展。虽然XJ还没有在Java中实现,但是它是XMF语言的主要特征。XMF语言已经在商业工具(XMF-Mosaic)中被使用并在2008年开源。关于本文更多的细节和例子可以参照这篇文章:超越Annotations:可扩展Java语言的计划

TAG: java Java extensible

下载本文示例代码


XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案XJ: 一个扩展Java语言的方案
阅读(187) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~