XJ: 一个扩展Java语言的方案

介绍一种扩展Java的方法-XJ,允许用户定义新的语法结构,如Select语法接口,用于从集合中选择符合条件的对象。
(请奠基左边广告支持哈)
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. }  
import language mylang.Select; public Person getChild(Vector<Person> people) {   @Select Person p from people where p.age < 18 {     return p;    }   else { return null; } }


这个新的语法接口可以叫做"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. }  
public Person getChild(Vector<Person> people) {    for(int i = 0; i < people.size(); i++) {       Person p = people.elementAt(i);       if(p.age < 18)           return p;    }    return null; }


同理,通过 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. }  
package mylang; import language java.syntax.Grammar; import java.syntax.AST; import java.syntax.Block; import java.syntax.Context; import java.syntax.Statement; import java.syntax.Sugar; import java.syntax.Type; import java.syntax.Var; public class Select extends Sugar {     private Type type;     private Var var;    private AST collection;     private AST test;     private Block body;     private Block otherwise;     public Select(Type T,String n,AST c,AST t,Block b,Block o){     type = T;         var = new Var(n);         collection = c;         test = t;         body = b;         otherwise = o;     }     // Select Grammar definition     @Grammar extends Statement {         Select ::=             T = Type             n = Name             'from' c = Exp             'when' t = Exp             b = Block             o = ('else' Block | { return new Block(); })             { return new Select(T,n,c,t,b,o); }.  }      // Desugar to produce an abstract syntax tree      public AST desugar(Context context) {      Class<T> cType = context.getType(collection);          if(isVector(cType))              return desugarVector(cType,contect);          else // More cases...      }       public AST desugarVector(Class<T> cType,Context context) {      Var done = context.newVar();          Var coll = context.newVar();          return           [| boolean <done> = false;                        <cType> coll = <collection>;                        for(int i = 0; i < <coll>.size(); i++) {                             <underlyingType(cType)> <var> = <coll>.elementAt(i);                            if(<test>) {                                <done> = true;               <body>;                          }          }                        if(!<done>)                <otherwise>;                    |];       } }


从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语言的计划
 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值