作者:不详 来源:JavaEye   酷勤网收集 2008-04-16

摘要
  本文我们介绍了Java的扩展(XJ),主要是通过定义新的Java语法来对Java语言本身进行扩展。虽然XJ还没有在Java中实现,但是它是XMF语言的主要特征。XMF语言已经在商业工具(XMF-Mosaic)中被使用并在2008年开源。

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<Person> 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<Person> 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<T> cType = context.getType(collection);       
  38.      if(isVector(cType))         
  39.        return desugarVector(cType,contect);       
  40.      else // More cases...     
  41.    }     
  42.   
  43.    public AST desugarVector(Class<T> cType,Context context) {   
  44.      Var done = context.newVar();       
  45.      Var coll = context.newVar();       
  46.      return    
  47.          [| boolean <done> = false;                 
  48.          <cType> coll = <collection>;                 
  49.          for(int i = 0; i < <coll>.size(); i++) {                   
  50.             <underlyingType(cType)> <var> = <coll>.elementAt(i);                   
  51.            if(<test>) {                     
  52.              <done> = true;    
  53.              <body>;                 
  54.            }   
  55.          }                 
  56.          if(!<done>)     
  57.              <otherwise>;             
  58.          |];     
  59.     }   
  60. }  


从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语言的计划

来自:http://www.javaeye.com/news/1924

分类: Java技术 中间件技术 应用服务器

上一篇:利用GWT开发高性能Ajax应用   下一篇:实时Java——为企业级市场热身