SlideShare a Scribd company logo
JastAdd	
  &	
  JastAddJ	
  
             クイックチュートリアル


                              武⼭山  ⽂文信	
  

                 CSG	
  勉強会	
  2012年年7⽉月31⽇日




2012/07/31         JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル   1 /26	
  
はじめに
 JastAdd	
  の概念念を中⼼心に紹介	
  
     — 細かい実装⽅方法は	
  JastAdd	
  のサンプルやチュートリアルを	
  

 前提知識識	
  
     — コンパイラの基礎(構⽂文・字句句解析,	
  BNF)	
  
     — Java	
  とクラス設計技法(Composite	
  パターン)	
  
     — AspectJ	
  

     — 参考図書	
  
         •  2週間でできる!	
  スクリプト⾔言語の作り⽅方	
  
         •  アスペクト指向⼊入⾨門	
  



2012/07/31             JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル   2 /26	
  
JastAdd	
  とは
 AOP	
  を活⽤用して⾔言語処理理系を実装できる	
  
     — アスペクトを追加して既存の⾔言語処理理系を容易易に拡張	
  
         •  Feature-­‐oriented	
  programming	
  /	
  soFware	
  product	
  lines	
  
     — ⾔言語処理理系:	
  コンパイラ・インタプリタ	
  
         •  出⼒力力がコンパイルされたコードか計算結果かの違い	
  

 hKp://jastadd.org/	
  
     — 論論⽂文は	
  OOPSLA	
  の  “The	
  jastadd	
  extensible	
  java	
  compiler”	
  
     — ググっても情報は出てこない	
  
     — 現在は  Görel	
  Hedin	
  (Lund	
  University,	
  Sweden)	
  の	
  
        チームが開発



2012/07/31                           JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル            3 /26	
  
JastAddJ	
  とは
 JastAdd	
  を使って実装された	
  Java	
  コンパイラ	
  
     — 現在は	
  1.7	
  までサポートされていることになっている	
  

 Java	
  の⾔言語拡張の実装に使える	
  
     — Java	
  コンパイラ部分を再利利⽤用	
  
     — 使⽤用例例:	
  GluonJ,	
  Aspect	
  bench	
  compiler	
  (AspectJ)	
  




2012/07/31                     JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル      4 /26	
  
⼀一般的なインタプリタの実装	
  1/2
 ソースコードを構⽂文解析して	
  AST	
  を作る	
  
     — flex	
  とか  yacc	
  を使う	
  
                                                                                                     3⾏行行⽬目以降降省省略略


                                                                                           Program

    env	
  x	
  =	
  3,	
  y	
  =	
  1;	
  
    x	
  *	
  y	
  +	
  10;	
                                            x	
  =	
  3	
  
                                                                                                     +
    x	
  *	
  x	
  *	
  y;                                               y	
  =	
  1



    13	
                                                                                      *             10
    9
                                                                              x                      y


2012/07/31                           JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                                     5 /26	
  
⼀一般的なインタプリタの実装	
  2/2
 評価を⾏行行うメソッドを実装



                                                                                           Program
class	
  Program	
  extends	
  ASTNode	
  {	
  
 	
  void	
  run()	
  {	
                                       getEnv()                             getExprs()
 	
   	
  System.out.println(	
  
 	
   	
   	
  getExprs(0).eval());	
                                    x	
  =	
  3	
  
                                                                                                     +
}}                                                                       y	
  =	
  1

class	
  Plus	
  extends	
  Expr	
  {	
  
 	
  int	
  eval()	
  {	
  
                                                                                              *             10
 	
   	
  return	
  
 	
   	
   	
  getLeft.eval()	
  +	
  getRight.eval();	
  
}}
                                                                              x                      y


2012/07/31                           JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                                      6 /26	
  
JastAdd	
  は何をしてくれるのか・くれないのか

 JastAdd	
  の⽣生成物はコンパイラのソースコード	
  
     — Java	
  で出⼒力力される	
  
     — 出⼒力力されたコードを⾒見見ることは⼤大切切	
  

 AST	
  のクラス定義の⾃自動化	
  

 属性を実装する⾔言語機構の提供	
  

 構⽂文解析・字句句解析のサポートはあまりない	
  
     — yacc,	
  flex	
  の代わりに、Beaver	
  と  JFlex	
  を内部で使⽤用	
  
         •  C	
  ではなく	
  Java	
  ⾵風に書ける	
  
         •  JavaCC	
  などもサポート	
  


2012/07/31                      JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル   7 /26	
  
AST	
  クラスの定義
 AST	
  の定義からクラスを⾃自動⽣生成	
  
     — class_name:	
  super	
  ::=	
  child_name:class	
  …;	
  
         •  child_name:	
  は省省略略するとクラス名がそのまま使われる	
  
     — *.ast	
  ファイルに書く
ASTNode;	
  
abstract	
  Expr:	
  ASTNode;	
  
Env:	
  ASTNode;	
  
Program:	
  ASTNode	
  ::=	
  [Env]	
  Expr*;	
  
                                                                          ASTNode
Plus:	
  Expr	
  ::=	
  Left:Expr	
  Right:Expr;	
  
Mult:	
  Expr	
  ::=	
  Left:Expr	
  Right:Expr;	
  
Var:	
  Expr	
  ::=	
  <ID:String>;	
  
Literal:	
  Expr	
  ::=	
  <Value:Int>;            Program                 Expr           Env



                                                 Plus             Mult              Var         Literal
2012/07/31                      JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                              8 /26	
  
例例:	
  Plus	
  クラス  
 コンストラクタ、geKer,	
  seKer	
  が定義される	
  
     — 指定した名前があれば使われる	
  

 Plus:	
  Expr	
  ::=	
  Left:Expr	
  Right:Expr;	
  

                 class	
  Plus	
  extends	
  Expr	
  {	
  
                 	
  Expr(Expr	
  p0,	
  Expr	
  p1)	
  {	
  
                 	
   	
  setChild(p0,	
  0);	
  
                 	
   	
  setChild(p1,	
  1);	
  
                 	
  }	
  
                 	
  Expr	
  getLeft()	
  {	
  return	
  (Expr)getChild(p0,	
  0);	
  }	
  
                 	
  void	
  setLeft()	
  {	
  …	
  }	
  
                 	
  Expr	
  getRight()	
  {	
  …	
  }	
  
                 	
  void	
  setRight()	
  {	
  …	
  }	
  
                 	
  ASTNode	
  getParent()	
  {	
  …	
  }	
  
                 }

2012/07/31               JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                         9 /26	
  
例例:	
  Program	
  クラス
 省省略略可能なノード([X]),	
  リスト	
  Y*	
  も指定できる	
  
     — hasX()	
  
     — getNumY(),	
  getNumY(),	
  getYs()	
  

 Program:	
  ASTNode	
  ::=	
  [Env]	
  Expr*;	
  

                                             class	
  Program	
  extends	
  ASTNode	
  {	
  
                                              	
  boolean	
  hasEnv()	
  {	
  …	
  }	
  
                                              	
  Env	
  getEnv()	
  {	
  …	
  }	
  
                                              	
  int	
  getNumExpr()	
  {	
  …	
  }	
  
                                              	
  Expr	
  getExprs(int	
  i)	
  {	
  …	
  }	
  
                                             	
  
                                              	
  //	
  setter	
  他省省略略   	
  	
  
                                             }

2012/07/31                    JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                       10 /26	
  
属性
 AST	
  が持つ情報	
  
     — JastAdd	
  ではメソッドのように⾒見見える	
  
     — eval()	
  は属性として定義できる	
  
     — syn	
  と  inh	
  の	
  2種類	
  

 属性の定義はアスペクトに記述	
  
     — すべてのクラスの  eval()	
  は  Eval	
  アスペクトに	
  
     — すべてのクラスの	
  print()	
  は	
  Print	
  アスペクトに	
  
     — 分けないと各クラスのコードがごちゃごちゃに…




2012/07/31             JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル   11 /26	
  
syn	
  属性	
  1/2	
  
 super	
  クラスの属性をメソッドのように上書き可	
  
     — 通常のメソッドと概念念的には同じ	
  

 AspectJ	
  のような⽂文法	
  
                  aspect	
  Eval	
  {	
  
                    	
  syn	
  int	
  Expr.eval();	
  //	
  Expr	
  クラスの  eval()	
  属性の宣⾔言	
  
                  	
  
                    	
  //	
  Expr	
  クラスの属性を上書き	
  
                    	
  eq	
  Plus.eval()	
  =	
  getLeft().eval()	
  +	
  getRight().eval();	
  
                  	
  
                    	
  //	
  メソッド⾵風にもかける	
  
                    	
  eq	
  Mult.eval()	
  =	
  {	
  
                    	
   	
  return	
  getLeft().eval()	
  *	
  getRight().eval();	
  
                    	
  }	
  
                    	
  eq	
  Literal.eval()	
  =	
  getValue();	
  
                    	
  eq	
  Var.eval()	
  =	
  ここは後で!;	
  
                  }

2012/07/31              JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                             12 /26	
  
syn	
  属性	
  2/2
 syn	
  属性は下から上の順番で値が決まる



                                                                         Program


                                                                                13
                                                       x	
  =	
  3	
  
                                                                                      +
                                                       y	
  =	
  1
                                                                                 eval()
                                                                  3
                                                                            *             10
                                                    eval()
                                                3                           1
                                                            x                         y


2012/07/31         JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                                     13 /26	
  
変数の値はどうやって?
 変数アクセスのノードから値はすぐに分からない	
  

 Java	
  で頑張ると…
     class	
  Var	
  extends	
  Expr	
  {	
                                                  Program
       	
  int	
  eval()	
  {	
  
       	
   	
  //	
  ID	
  は変数名	
  
       	
   	
  return	
  lookup(getID());	
  
       	
  }	
                                                             x	
  =	
  3	
  
                                                                                                       +
     	
                                                                    y	
  =	
  1
       	
  int	
  lookUp(String	
  id)	
  {	
  
     	
  
     	
  
                                                                                                *          10
     	
  
     	
  
       	
   	
  	
  
       	
  }	
  
                                                                                x                      y
     }

2012/07/31                             JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                                  14 /26	
  
変数の値はどうやって?
 変数アクセスのノードから値はすぐに分からない	
  

 Java	
  で頑張ると…
     class	
  Var	
  extends	
  Expr	
  {	
                                                    Program
       	
  int	
  eval()	
  {	
  
       	
   	
  //	
  ID	
  は変数名	
  
       	
   	
  return	
  lookup(getID());	
  
       	
  }	
                                                               x	
  =	
  3	
  
                                                                                                         +
     	
                                                                      y	
  =	
  1
       	
  int	
  lookUp(String	
  id)	
  {	
  
       	
   	
  n	
  =	
  this;	
  
       	
   	
  for	
  (;;)	
  {	
  
                                                                                                  *          10
       	
   	
   	
  n	
  =	
  n.getParent();	
  
       	
   	
   	
  if	
  (n	
  instanceof	
  Program)	
  {	
  
       	
   	
   	
   	
  Program	
  p	
  =	
  (Program)n;	
  
       	
   	
   	
   	
  return	
  p.getEnv().value(id);	
  
                                                                                  x                      y
     }}}}

2012/07/31                               JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                                  15 /26	
  
inh	
  属性
 指定したサブツリーが持つ属性の値を	
  
 上から下へ値を伝播	
  
     — 実際にやっていることは1つ前のコードと同じ	
  
aspect	
  LookUp	
  {	
  
  	
  //	
  変数アクセスは  lookUp	
  属性を持つ	
                                             Program
  	
  inh	
  int	
  Var.lookUp(String	
  id);	
  
	
  
                                                                                             getExprs()
  	
  //	
  Program	
  の  Expr	
  以下のすべての  lookUp	
  
                                                                   x	
  =	
  3	
  
  	
  //	
  属性の値を決める	
                                                                       +
                                                                   y	
  =	
  1
  	
  eq	
  Program.getExpr().lookUp(String	
  id)	
  =	
  
  	
   	
  //	
  this	
  は	
  Program	
  のオブジェクト	
  
  	
   	
  this.getEnv().value(id);	
  
}                                                           lookUp("x")	
  =	
  3	
   *           10
                                                              lookUp("y")	
  =	
  1	
  
aspect	
  Eval	
  {	
  
 	
  :	
  略略	
  :	
  
 	
  eq	
  Var.eval()	
  =	
  lookUp(getID());	
                             x               y
}
2012/07/31                           JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                           16 /26	
  
おまけ
 lazy	
  を付けると属性値の計算をキャッシュ	
  
     — ただし、ノードの状態が変化したかどうかの判定に	
  
        バグがあるような…	
  




              aspect	
  LookUp	
  {	
  
              	
  
               	
  //	
  id	
  の値に対する戻り値をキャッシュ	
  
               	
  lazy	
  inh	
  int	
  Var.lookUp(String	
  id);	
  
              	
  
               	
  eq	
  Program.getExpr().lookUp(String	
  id)	
  =	
  
               	
   	
  this.getEnv().value(id);	
  
              }

2012/07/31      JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル              17 /26	
  
注意:	
  2種類の⽊木
 syn	
  属性	
  
     — AST	
  を表現するクラスのサブクラスに属性が継承される	
  

 inh	
  属性	
  
                                                                                            Program
     — AST	
  そのものの親から⼦子へ	
  
        属性値を伝播
                                                                          x	
  =	
  3	
  
                                                                                                      +
                                                                          y	
  =	
  1
                              ASTNode


                                                                                               *          10
             Program           Expr             Env


                                                                               x                      y
     Plus              Mult             Var            Literal
2012/07/31                            JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                                  18 /26	
  
ここまでのまとめ
 JastAdd	
  は	
  AST	
  クラスの実装のサポート	
  
     — クラス階層	
  
     — 親⼦子関係の定義	
  
     — geKer,	
  seKer	
  の定義	
  

 属性のための⾔言語機構	
  
     — inh:	
  通常のメソッドでは⾯面倒な親ノードからの値取得も	
  




2012/07/31                    JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル   19 /26	
  
AST	
  の書き換え
 ⾔言語拡張が簡単にできることが多い	
  
     — ⾔言語拡張から既存の形へ変換	
  
     — 属性の追加・変更更も必要	
  

 JastAdd	
  は書き換えのための⾔言語機構も提供	
  

 Java	
  に	
  loop	
  ⽂文の追加	
  
     — 条件を指定しないループ	
  
                                                  loop	
  {	
  
                                                        	
  l	
  =	
  System.in.readln();	
  
                                                        	
  if	
  (l	
  ==	
  null)	
  break;	
  
                                                        	
  System.out.println(l);	
  
                                                  }	
  

2012/07/31              JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                             20 /26	
  
JastAddJ	
  の拡張
 NullCheck	
  などサンプルのファイルを変更更するのがや
 りやすい	
  
     — ant,	
  Java	
  のクラスパスの知識識が必要	
  

 ステップ1:	
  AST	
  の定義	
  
     — JastAddJ	
  が提供する	
  *.ast	
  ファイルと	
  ant	
  で連結する	
  
         •  他の	
  AST	
  がどのように定義されているか⾒見見ると良良い	
  


      LoopStmt:	
  Stmt	
  ::=	
  Body:Stmt;




2012/07/31                   JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル   21 /26	
  
JastAddJ	
  の拡張
 字句句解析のためのキーワードを追加	
  (*.flex	
  ファイル)	
  

         <YYINITIAL>	
  {	
  
     	
  	
  	
  ”loop"	
  	
  	
  	
  	
  	
  	
  	
  	
  {	
  return	
  sym(Terminals.LOOP);	
  }	
  
         }




2012/07/31                              JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                           22 /26	
  
JastAddJ	
  の拡張
 構⽂文解析のルールを追加	
  (*.parser	
  ファイル)	
  
     — statement.s	
  
        statement	
  をパースして、作られたノードを	
  s	
  で受け取る	
  
     — while_stetement	
  を参考に書いた
    Stmt	
  statement	
  =	
  
          	
  loop_statement.l	
  	
  	
  {:	
  return	
  l;	
  :}	
  
          	
  ;	
  
    Stmt	
  statement_no_short_if	
  =	
  
    	
  	
  loop_statement_no_short_if.l	
  	
  	
  	
  	
  	
  {:	
  return	
  l;	
  :}	
  
          	
  ;	
  
    	
  
    LoopStmt	
  loop_statement	
  =	
  
          	
  LOOP	
  statement.s	
  {: 	
  return	
  new	
  LoopStmt(s);	
  :}	
  
    	
  	
  ;	
  
    LoopStmt	
  loop_statement_no_short_if	
  =	
  
          	
  LOOP	
  statement_no_short_if.s	
  {: 	
  return	
  new	
  LoopStmt(s);	
  :}	
  
    	
  	
  ;	
  
2012/07/31                          JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                       23 /26	
  
Rewriter	
  で⽊木を書き換え
 loop	
  を  while	
  に書き換えてしまう	
  
     — 意味解析などは	
  while	
  のコードがそのまま使われる	
  
     — when	
  節で書き換える条件も書ける	
  
         •  JastAddJ	
  の中でどのように使われているか⾒見見ると⾯面⽩白い

                                                                                    Loop
     aspect	
  LoopToWhile	
  {	
  
      	
  rewrite	
  LoopStmt	
  {	
                                                Block
      	
   	
  to	
  WhileStmt	
  {	
  
      	
   	
   	
  Expr	
  cond	
  =	
  new	
  BooleanLiteral(true);	
  
      	
   	
   	
  Stmt	
  body	
  =	
  getBody();	
  
      	
   	
   	
  return	
  new	
  WhileStmt(cond,	
  body);	
  
     }}}                                                                            While


                                                                             true           Block
2012/07/31                         JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                     24 /26	
  
Rewrite	
  中の注意
 ⽣生成中のノードからは  inh	
  属性を呼べない	
  	
  
     — 厳密には⽣生成中のノードより親から伝播されるもの	
  
     — NullPointerExcepkon	
  になる

                             rewrite	
  中	
  
             before                                                    aFer
                        parent	
  がまだ無い!
  aKr
              Block                                                    Block

                                     While
              Loop                                                     While

              Block         true              Block             true           Block



2012/07/31            JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル                      25 /26	
  
後半のまとめ
 拡張部分の構⽂文解析と	
  AST	
  は⽤用意する	
  

 既存の	
  Java	
  の	
  AST	
  に変換して既存のコードを再利利⽤用	
  
     — loop	
  の例例では、意味解析やコード⽣生成を再利利⽤用	
  

 追加の属性が必要な場合	
  
     — 前半と同じようにアスペクトを実装する




2012/07/31         JastAdd	
  &	
  JastAddJ	
  クイックチュートリアル   26 /26	
  

More Related Content

PDF
PFDS 10.2.1 lists with efficient catenation
PDF
Scala with DDD
KEY
Actor&stm
PPTX
Chapter 6: Computing on the language (R Language Definition)
PDF
Granger因果による 時系列データの因果推定(因果フェス2015)
PDF
プログラミング言語Scala
PDF
Deep learning _linear_algebra___probablity___information
PDF
Cvpr2011 reading-tsubosaka
PFDS 10.2.1 lists with efficient catenation
Scala with DDD
Actor&stm
Chapter 6: Computing on the language (R Language Definition)
Granger因果による 時系列データの因果推定(因果フェス2015)
プログラミング言語Scala
Deep learning _linear_algebra___probablity___information
Cvpr2011 reading-tsubosaka

What's hot (20)

PDF
Xtend - Javaの未来を今すぐ使う
PDF
たのしい高階関数
PDF
Scala の関数型プログラミングを支える技術
PDF
オンライン凸最適化と線形識別モデル学習の最前線_IBIS2011
PDF
ユニットテストの保守性を作りこむ, xpjugkansai2011
PPT
ジェネリクスの基礎と クラス設計への応用
PDF
JavaのGenericsとは?
PPTX
機械学習
PDF
講座Java入門
PDF
Topic model
PDF
今から始める Lens/Prism
PPTX
Java Puzzlers JJUG CCC 2016
PPTX
Feature Selection with R / in JP
PDF
Scalaのオブジェクトの話
PDF
BOF1-Scala02.pdf
PPTX
Python opt
PDF
PFDS 11.2 catenable double ended queue
PDF
Pythonで始めるDropboxAPI
PPTX
Javaプログラミング入門【第2回】
PDF
東京都市大学 データ解析入門 8 クラスタリングと分類分析 1
Xtend - Javaの未来を今すぐ使う
たのしい高階関数
Scala の関数型プログラミングを支える技術
オンライン凸最適化と線形識別モデル学習の最前線_IBIS2011
ユニットテストの保守性を作りこむ, xpjugkansai2011
ジェネリクスの基礎と クラス設計への応用
JavaのGenericsとは?
機械学習
講座Java入門
Topic model
今から始める Lens/Prism
Java Puzzlers JJUG CCC 2016
Feature Selection with R / in JP
Scalaのオブジェクトの話
BOF1-Scala02.pdf
Python opt
PFDS 11.2 catenable double ended queue
Pythonで始めるDropboxAPI
Javaプログラミング入門【第2回】
東京都市大学 データ解析入門 8 クラスタリングと分類分析 1
Ad

Viewers also liked (20)

PDF
20120907 osc-lt-docja
PDF
Linux ディストリビューション開発者になる4つの理由
PDF
Plasma 5 を翻訳しよう!
PDF
インプットメソッドメンテナーの日常
PDF
第1回 Open Build Service 道場
PDF
クラウドインフラのゲスト OS は openSUSE で—今までの&新しい openSUSE 活用法の紹介
PDF
Redesigning Input-Method Launcher and Management System
PDF
openSUSE におけるパッケージ管理入門
PDF
openSUSE で創作活動!イラストから本格的な印刷物作成まで
PDF
コミュニティ主導Linux ディストリビューションと関わっていくには?
PDF
A Closer Look at Fonts and Font Rendering System on openSUSE
PDF
覚えておきたい! zypper コマンドの使い方
PDF
サーバーでもデスクトップでもOK! YaSTを使ってLinuxをらくらく設定
PDF
openSUSE Leap 42.1 とは?
PDF
OSS に貢献しよう!―OSS の明るい未来のために!―
PPS
La mort des_abeilles
PPS
Incas chaf copie
PDF
LTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみる
PDF
サーバーだけじゃない! Linux デスクトップを使い倒そう! その1
PDF
YaST を使って Linux をらくらく設定―Btrfs を活用したファイルサーバー構築 & OS インストールの自動化
20120907 osc-lt-docja
Linux ディストリビューション開発者になる4つの理由
Plasma 5 を翻訳しよう!
インプットメソッドメンテナーの日常
第1回 Open Build Service 道場
クラウドインフラのゲスト OS は openSUSE で—今までの&新しい openSUSE 活用法の紹介
Redesigning Input-Method Launcher and Management System
openSUSE におけるパッケージ管理入門
openSUSE で創作活動!イラストから本格的な印刷物作成まで
コミュニティ主導Linux ディストリビューションと関わっていくには?
A Closer Look at Fonts and Font Rendering System on openSUSE
覚えておきたい! zypper コマンドの使い方
サーバーでもデスクトップでもOK! YaSTを使ってLinuxをらくらく設定
openSUSE Leap 42.1 とは?
OSS に貢献しよう!―OSS の明るい未来のために!―
La mort des_abeilles
Incas chaf copie
LTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみる
サーバーだけじゃない! Linux デスクトップを使い倒そう! その1
YaST を使って Linux をらくらく設定―Btrfs を活用したファイルサーバー構築 & OS インストールの自動化
Ad

Similar to JastAdd & JastAddJ クリックチュートリアル (20)

PPTX
Junit4
PDF
ECMAScript 6 Features(PDF 版)
PDF
JavaScript/CSS 2015 Autumn
PDF
Introduction Xtend
PDF
Xtend30分クッキング やきに駆動
PDF
Xtend30分クッキング
PDF
たのしい関数型
PDF
例外設計における大罪
PDF
KETpic できれいな図を書こう
PDF
PDF
Javaセキュアコーディングセミナー東京第4回講義
PDF
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
ODP
F#とC#で見る関数志向プログラミング
PDF
Deep Learning を実装する
PDF
初めてのHaskell (表)
PDF
フラグを愛でる
PDF
Qunit再入門 (Version 1.10.0 編)
PDF
東京大学工学部計数工学科応用音響学 D2 Clustering
KEY
Java基礎
PDF
Rで計量時系列分析~CRANパッケージ総ざらい~
Junit4
ECMAScript 6 Features(PDF 版)
JavaScript/CSS 2015 Autumn
Introduction Xtend
Xtend30分クッキング やきに駆動
Xtend30分クッキング
たのしい関数型
例外設計における大罪
KETpic できれいな図を書こう
Javaセキュアコーディングセミナー東京第4回講義
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
F#とC#で見る関数志向プログラミング
Deep Learning を実装する
初めてのHaskell (表)
フラグを愛でる
Qunit再入門 (Version 1.10.0 編)
東京大学工学部計数工学科応用音響学 D2 Clustering
Java基礎
Rで計量時系列分析~CRANパッケージ総ざらい~

More from Fuminobu Takeyama (20)

PDF
Btrfs + Snapper + Samba で作る「以前のバージョン」に戻せるファイルサーバー
PDF
Geeko Magazine: A Technical Magazine on openSUSE, edited on openSUSE―openSUSE...
PDF
SUSE Studio Express を使ってみた
PDF
Geeko Magazine: A Technical Magazine on openSUSE, editied on openSUSE
PDF
最近良く聞く Kubernetes を体験してみた イントロ + 活用編
PDF
Ruby でできていると言っても過言ではない Linux ディストリビューション―openSUSE
PDF
ここが違う! OSC Tokyo と台湾の COSCUP
PDF
トランザクショナルアップデート ― Btrfsを活用したパッケージ更新方法
PDF
What is necessary for the next input method framework?
PDF
Leap の初のメジャーアップデート! openSUSE Leap 15.0 リリース
PDF
Portus でプライベート Docker レジストリを構築してみよう(openSUSE の紹介パート)
PDF
Portus でプライベート Docker レジストリを構築してみよう ― 予告編 ―
PDF
Welcome to openSUSE.Asia Summit 2017
PDF
告知LT最終回! openSUSE.Asia Summit 2017 注目セッションのご紹介
PDF
今さら聞けない -Linux コマンドラインツールテクニック その1 rev. 4
PDF
【openSUSEの最新動向のみ】Solrで日本語全文検索システムの構築と応用
PDF
サーバーだけじゃない!Linux デスクトップを使い倒そう その3 ― 今話題の Kotlin から Ruby、C++ 1x…の開発環境を整える
PDF
今さら聞けない! Linux コマンドラインツールテクニック その1 rev. 3
PDF
今さら聞けない Linux コマンドラインツールテクニック その1 rev. 2
PDF
20161106 osc-tokyo-lt-asia-summit
Btrfs + Snapper + Samba で作る「以前のバージョン」に戻せるファイルサーバー
Geeko Magazine: A Technical Magazine on openSUSE, edited on openSUSE―openSUSE...
SUSE Studio Express を使ってみた
Geeko Magazine: A Technical Magazine on openSUSE, editied on openSUSE
最近良く聞く Kubernetes を体験してみた イントロ + 活用編
Ruby でできていると言っても過言ではない Linux ディストリビューション―openSUSE
ここが違う! OSC Tokyo と台湾の COSCUP
トランザクショナルアップデート ― Btrfsを活用したパッケージ更新方法
What is necessary for the next input method framework?
Leap の初のメジャーアップデート! openSUSE Leap 15.0 リリース
Portus でプライベート Docker レジストリを構築してみよう(openSUSE の紹介パート)
Portus でプライベート Docker レジストリを構築してみよう ― 予告編 ―
Welcome to openSUSE.Asia Summit 2017
告知LT最終回! openSUSE.Asia Summit 2017 注目セッションのご紹介
今さら聞けない -Linux コマンドラインツールテクニック その1 rev. 4
【openSUSEの最新動向のみ】Solrで日本語全文検索システムの構築と応用
サーバーだけじゃない!Linux デスクトップを使い倒そう その3 ― 今話題の Kotlin から Ruby、C++ 1x…の開発環境を整える
今さら聞けない! Linux コマンドラインツールテクニック その1 rev. 3
今さら聞けない Linux コマンドラインツールテクニック その1 rev. 2
20161106 osc-tokyo-lt-asia-summit

JastAdd & JastAddJ クリックチュートリアル

  • 1. JastAdd  &  JastAddJ   クイックチュートリアル 武⼭山  ⽂文信   CSG  勉強会  2012年年7⽉月31⽇日 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 1 /26  
  • 2. はじめに  JastAdd  の概念念を中⼼心に紹介   — 細かい実装⽅方法は  JastAdd  のサンプルやチュートリアルを    前提知識識   — コンパイラの基礎(構⽂文・字句句解析,  BNF)   — Java  とクラス設計技法(Composite  パターン)   — AspectJ   — 参考図書   •  2週間でできる!  スクリプト⾔言語の作り⽅方   •  アスペクト指向⼊入⾨門   2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 2 /26  
  • 3. JastAdd  とは  AOP  を活⽤用して⾔言語処理理系を実装できる   — アスペクトを追加して既存の⾔言語処理理系を容易易に拡張   •  Feature-­‐oriented  programming  /  soFware  product  lines   — ⾔言語処理理系:  コンパイラ・インタプリタ   •  出⼒力力がコンパイルされたコードか計算結果かの違い    hKp://jastadd.org/   — 論論⽂文は  OOPSLA  の  “The  jastadd  extensible  java  compiler”   — ググっても情報は出てこない   — 現在は  Görel  Hedin  (Lund  University,  Sweden)  の   チームが開発 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 3 /26  
  • 4. JastAddJ  とは  JastAdd  を使って実装された  Java  コンパイラ   — 現在は  1.7  までサポートされていることになっている    Java  の⾔言語拡張の実装に使える   — Java  コンパイラ部分を再利利⽤用   — 使⽤用例例:  GluonJ,  Aspect  bench  compiler  (AspectJ)   2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 4 /26  
  • 5. ⼀一般的なインタプリタの実装  1/2  ソースコードを構⽂文解析して  AST  を作る   — flex  とか  yacc  を使う   3⾏行行⽬目以降降省省略略 Program env  x  =  3,  y  =  1;   x  *  y  +  10;   x  =  3   + x  *  x  *  y; y  =  1 13   * 10 9 x y 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 5 /26  
  • 6. ⼀一般的なインタプリタの実装  2/2  評価を⾏行行うメソッドを実装 Program class  Program  extends  ASTNode  {    void  run()  {   getEnv() getExprs()    System.out.println(        getExprs(0).eval());   x  =  3   + }} y  =  1 class  Plus  extends  Expr  {    int  eval()  {   * 10    return        getLeft.eval()  +  getRight.eval();   }} x y 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 6 /26  
  • 7. JastAdd  は何をしてくれるのか・くれないのか  JastAdd  の⽣生成物はコンパイラのソースコード   — Java  で出⼒力力される   — 出⼒力力されたコードを⾒見見ることは⼤大切切    AST  のクラス定義の⾃自動化    属性を実装する⾔言語機構の提供    構⽂文解析・字句句解析のサポートはあまりない   — yacc,  flex  の代わりに、Beaver  と  JFlex  を内部で使⽤用   •  C  ではなく  Java  ⾵風に書ける   •  JavaCC  などもサポート   2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 7 /26  
  • 8. AST  クラスの定義  AST  の定義からクラスを⾃自動⽣生成   — class_name:  super  ::=  child_name:class  …;   •  child_name:  は省省略略するとクラス名がそのまま使われる   — *.ast  ファイルに書く ASTNode;   abstract  Expr:  ASTNode;   Env:  ASTNode;   Program:  ASTNode  ::=  [Env]  Expr*;   ASTNode Plus:  Expr  ::=  Left:Expr  Right:Expr;   Mult:  Expr  ::=  Left:Expr  Right:Expr;   Var:  Expr  ::=  <ID:String>;   Literal:  Expr  ::=  <Value:Int>; Program Expr Env Plus Mult Var Literal 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 8 /26  
  • 9. 例例:  Plus  クラス    コンストラクタ、geKer,  seKer  が定義される   — 指定した名前があれば使われる    Plus:  Expr  ::=  Left:Expr  Right:Expr;   class  Plus  extends  Expr  {    Expr(Expr  p0,  Expr  p1)  {      setChild(p0,  0);      setChild(p1,  1);    }    Expr  getLeft()  {  return  (Expr)getChild(p0,  0);  }    void  setLeft()  {  …  }    Expr  getRight()  {  …  }    void  setRight()  {  …  }    ASTNode  getParent()  {  …  }   } 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 9 /26  
  • 10. 例例:  Program  クラス  省省略略可能なノード([X]),  リスト  Y*  も指定できる   — hasX()   — getNumY(),  getNumY(),  getYs()    Program:  ASTNode  ::=  [Env]  Expr*;   class  Program  extends  ASTNode  {    boolean  hasEnv()  {  …  }    Env  getEnv()  {  …  }    int  getNumExpr()  {  …  }    Expr  getExprs(int  i)  {  …  }      //  setter  他省省略略     } 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 10 /26  
  • 11. 属性  AST  が持つ情報   — JastAdd  ではメソッドのように⾒見見える   — eval()  は属性として定義できる   — syn  と  inh  の  2種類    属性の定義はアスペクトに記述   — すべてのクラスの  eval()  は  Eval  アスペクトに   — すべてのクラスの  print()  は  Print  アスペクトに   — 分けないと各クラスのコードがごちゃごちゃに… 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 11 /26  
  • 12. syn  属性  1/2    super  クラスの属性をメソッドのように上書き可   — 通常のメソッドと概念念的には同じ    AspectJ  のような⽂文法   aspect  Eval  {    syn  int  Expr.eval();  //  Expr  クラスの  eval()  属性の宣⾔言      //  Expr  クラスの属性を上書き    eq  Plus.eval()  =  getLeft().eval()  +  getRight().eval();      //  メソッド⾵風にもかける    eq  Mult.eval()  =  {      return  getLeft().eval()  *  getRight().eval();    }    eq  Literal.eval()  =  getValue();    eq  Var.eval()  =  ここは後で!;   } 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 12 /26  
  • 13. syn  属性  2/2  syn  属性は下から上の順番で値が決まる Program 13 x  =  3   + y  =  1 eval() 3 * 10 eval() 3 1 x y 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 13 /26  
  • 14. 変数の値はどうやって?  変数アクセスのノードから値はすぐに分からない    Java  で頑張ると… class  Var  extends  Expr  {   Program  int  eval()  {      //  ID  は変数名      return  lookup(getID());    }   x  =  3   +   y  =  1  int  lookUp(String  id)  {       * 10            }   x y } 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 14 /26  
  • 15. 変数の値はどうやって?  変数アクセスのノードから値はすぐに分からない    Java  で頑張ると… class  Var  extends  Expr  {   Program  int  eval()  {      //  ID  は変数名      return  lookup(getID());    }   x  =  3   +   y  =  1  int  lookUp(String  id)  {      n  =  this;      for  (;;)  {   * 10      n  =  n.getParent();        if  (n  instanceof  Program)  {          Program  p  =  (Program)n;          return  p.getEnv().value(id);   x y }}}} 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 15 /26  
  • 16. inh  属性  指定したサブツリーが持つ属性の値を   上から下へ値を伝播   — 実際にやっていることは1つ前のコードと同じ   aspect  LookUp  {    //  変数アクセスは  lookUp  属性を持つ   Program  inh  int  Var.lookUp(String  id);     getExprs()  //  Program  の  Expr  以下のすべての  lookUp   x  =  3    //  属性の値を決める   + y  =  1  eq  Program.getExpr().lookUp(String  id)  =      //  this  は  Program  のオブジェクト      this.getEnv().value(id);   } lookUp("x")  =  3   * 10 lookUp("y")  =  1   aspect  Eval  {    :  略略  :    eq  Var.eval()  =  lookUp(getID());   x y } 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 16 /26  
  • 17. おまけ  lazy  を付けると属性値の計算をキャッシュ   — ただし、ノードの状態が変化したかどうかの判定に   バグがあるような…   aspect  LookUp  {      //  id  の値に対する戻り値をキャッシュ    lazy  inh  int  Var.lookUp(String  id);      eq  Program.getExpr().lookUp(String  id)  =      this.getEnv().value(id);   } 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 17 /26  
  • 18. 注意:  2種類の⽊木  syn  属性   — AST  を表現するクラスのサブクラスに属性が継承される    inh  属性   Program — AST  そのものの親から⼦子へ   属性値を伝播 x  =  3   + y  =  1 ASTNode * 10 Program Expr Env x y Plus Mult Var Literal 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 18 /26  
  • 19. ここまでのまとめ  JastAdd  は  AST  クラスの実装のサポート   — クラス階層   — 親⼦子関係の定義   — geKer,  seKer  の定義    属性のための⾔言語機構   — inh:  通常のメソッドでは⾯面倒な親ノードからの値取得も   2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 19 /26  
  • 20. AST  の書き換え  ⾔言語拡張が簡単にできることが多い   — ⾔言語拡張から既存の形へ変換   — 属性の追加・変更更も必要    JastAdd  は書き換えのための⾔言語機構も提供    Java  に  loop  ⽂文の追加   — 条件を指定しないループ   loop  {    l  =  System.in.readln();    if  (l  ==  null)  break;    System.out.println(l);   }   2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 20 /26  
  • 21. JastAddJ  の拡張  NullCheck  などサンプルのファイルを変更更するのがや りやすい   — ant,  Java  のクラスパスの知識識が必要    ステップ1:  AST  の定義   — JastAddJ  が提供する  *.ast  ファイルと  ant  で連結する   •  他の  AST  がどのように定義されているか⾒見見ると良良い   LoopStmt:  Stmt  ::=  Body:Stmt; 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 21 /26  
  • 22. JastAddJ  の拡張  字句句解析のためのキーワードを追加  (*.flex  ファイル)   <YYINITIAL>  {        ”loop"                  {  return  sym(Terminals.LOOP);  }   } 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 22 /26  
  • 23. JastAddJ  の拡張  構⽂文解析のルールを追加  (*.parser  ファイル)   — statement.s   statement  をパースして、作られたノードを  s  で受け取る   — while_stetement  を参考に書いた Stmt  statement  =    loop_statement.l      {:  return  l;  :}    ;   Stmt  statement_no_short_if  =      loop_statement_no_short_if.l            {:  return  l;  :}    ;     LoopStmt  loop_statement  =    LOOP  statement.s  {:  return  new  LoopStmt(s);  :}      ;   LoopStmt  loop_statement_no_short_if  =    LOOP  statement_no_short_if.s  {:  return  new  LoopStmt(s);  :}      ;   2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 23 /26  
  • 24. Rewriter  で⽊木を書き換え  loop  を  while  に書き換えてしまう   — 意味解析などは  while  のコードがそのまま使われる   — when  節で書き換える条件も書ける   •  JastAddJ  の中でどのように使われているか⾒見見ると⾯面⽩白い Loop aspect  LoopToWhile  {    rewrite  LoopStmt  {   Block    to  WhileStmt  {        Expr  cond  =  new  BooleanLiteral(true);        Stmt  body  =  getBody();        return  new  WhileStmt(cond,  body);   }}} While true Block 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 24 /26  
  • 25. Rewrite  中の注意  ⽣生成中のノードからは  inh  属性を呼べない     — 厳密には⽣生成中のノードより親から伝播されるもの   — NullPointerExcepkon  になる rewrite  中   before aFer parent  がまだ無い! aKr Block Block While Loop While Block true Block true Block 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 25 /26  
  • 26. 後半のまとめ  拡張部分の構⽂文解析と  AST  は⽤用意する    既存の  Java  の  AST  に変換して既存のコードを再利利⽤用   — loop  の例例では、意味解析やコード⽣生成を再利利⽤用    追加の属性が必要な場合   — 前半と同じようにアスペクトを実装する 2012/07/31 JastAdd  &  JastAddJ  クイックチュートリアル 26 /26