All Packages  Class Hierarchy  This Package  Previous  Next  Index

Class epp.Tree

java.lang.Object
   |
   +----epp.Tree

public class Tree
extends Object
implements Cloneable, Serializable
Tree は、抽象構文木のノードを表現するためのクラスです。.

例えば、 if 文は EPP の内部では (if condition then else ) という抽象構文木で表現されます。 このノードは、 new Tree(:if, condition, then, else) というインスタンス生成式で生成することができます。 ノードの種類を表す部分(この場合は :if)を tag 、 ノードのすべて subtree (この場合は condition, then, else)を args と呼びます。

Tree は immutable object です。 tag や args を変更することはできません。 (プログラマーは、メソッド呼び出し tree.args() が返す Tree の配列の中身を うっかり書き換えないように注意する必要があります。 万一書き換えてしまうと、非常に見つけにくいバグの原因になります。)

Tree のサブクラスに、 Identifier と LiteralTree があります。 すべての抽象構文木のノードは、 Tree, Identifier, LiteralTree の3つのいずれかで 表現されます。 plug-in は、構文を拡張して新たな種類のノードを導入できますが、 その場合でもノードを3つのクラスのいずれかで表現しなければなりません。

クラス Tree のインスタンス tree に対して tree.print() という メソッド呼び出しをすることで、抽象構文木をS式の形で 出力することができます。 例えば、

	if (x == 0) System.out.println("Hello!");
というプログラムを構文解析した結果の抽象構文木は、
      (if
       (==
        (id x)
        (literalTree int "0"))
       (expressionStatement
        (invokeLong
         (name
          (id System)
          (id out))
         (id println)
         (argumentList
          (literalTree string "Hello!"))))
       (emptyStatement))
と print されます。

LiteralTree と Identifier に関しては、 tree.args() は 常に長さ0の配列を返します。 このような仕掛けになっているため、 tree に対する再帰的処理は 非常に簡単になります。例えば、 tree の中に if 文が現れる数を数える メソッドは、

int countIf(Tree tree){
  int c = 0;
  if (tree.tag() == :if) c++;
  Tree[] args = tree.args();
  for (int i = 0; i < args.length; i++){
    c += countIf(args[i]);
  }
  return c;
}
ですむことになります。

クラス Tree は、 tag と args の他にも行番号情報などの付加情報を 持っています。 これらの情報を保存したまま、 args の値だけを変更した tree を 生成したい時には、 "modifyArgs" というメソッドを使います。

	Tree[] newArgs = {...};
	Tree newTree = tree.modifyArgs(newArgs);
これは、次のプログラムとほとんど同じですが、 tree が持っている 行番号などの情報が newTree にもコピーされる点が異なります。
	Tree[] newArgs = {...};
	Tree newTree = new Tree(tree.tag(), newArgs);

大きい Tree を生成するコードを簡単に書くために、 BackQuote plug-in が提供されています。 詳しくは、../BackQuote.html を見て下さい。 tree.print() あるいは epp の -tree オプションによって出力された抽象構文木は、 カットアンドペーストして、 BackQuote マクロにそのまま使うことができます。

Tree の可変長配列を使うことがよくあるので、クラス TreeVec が用意されています。 キャストが不要なので java.lang.Vector より便利です。

See Also:
Identifier, LiteralTree, TreeVec

Constructor Index

 o Tree(Symbol)
 o Tree(Symbol, Tree)
 o Tree(Symbol, Tree, Tree)
 o Tree(Symbol, Tree, Tree, Tree)
 o Tree(Symbol, Tree, Tree, Tree, Tree)
 o Tree(Symbol, Tree, Tree, Tree, Tree, Tree)
 o Tree(Symbol, Tree, Tree, Tree, Tree, Tree, Tree)
 o Tree(Symbol, Tree, Tree, Tree, Tree, Tree, Tree, Tree)
 o Tree(Symbol, Tree[])
 o Tree(Symbol, TreeVec)

Method Index

 o args()
抽象構文木の subtree を取り出します。
 o beginningPoint()
このノードの開始位置の point を返します。.
 o endPoint()
このノードの終了位置の point を返します。.
 o idName()
このノードが Identifier ならば、その名前を返します。.
 o isTyped()
このメソッドが型情報を持っていれば true 、そうでなければ false を 返します。
 o lineNumber()
このノードの行番号情報を返します。.
 o literalToken()
このノードが LiteralTree ならば、その中身を表す LiteralToken を返します。.
 o main(String[])
テスト用のメソッドです。
 o modifyArgs(Tree[])
このノードの args のみを変更した Tree を作って返します。.
 o modifyBeginningPoint(int)
 o modifyEndPoint(int)
 o modifyLineNumber(int)
 o modifyProperty(Symbol, Object)
このノードのプロパティを変更した Tree を作って返します。.
 o modifyTypeAndArgs(Type, Tree[])
このノードの type と args のみを変更した Tree を作って返します。.
 o nameEqual(Tree, Tree)
:name をタグに持つ Tree 同士を比較します。.
 o nameToString()
:name をタグに持つ Tree を文字列に変換します。.
 o print()
Opts.out に、人間に見やすいように中身を出力するデバッグ用メソッドです。.
 o print(PrintWriter)
 o print(PrintWriter, String)
 o printProp(PrintWriter)
 o property(Symbol)
ノードに付けられたプロパティを検索して返します。.
 o quoteString(String)
This method is called by class Identifier and LiteralToken.
 o resetType()
型情報を持たない Tree を作って返します。.
 o stringToNameTree(String)
 o tag()
抽象構文木の種類を表す tag を取り出します。
 o toString()
Convert tree to String without indentation.
 o type()
このノードの型を返します。.

Constructors

 o Tree
 public Tree(Symbol tag,
             Tree args[])
 o Tree
 public Tree(Symbol tag,
             TreeVec args)
 o Tree
 public Tree(Symbol t)
 o Tree
 public Tree(Symbol t,
             Tree a1)
 o Tree
 public Tree(Symbol t,
             Tree a1,
             Tree a2)
 o Tree
 public Tree(Symbol t,
             Tree a1,
             Tree a2,
             Tree a3)
 o Tree
 public Tree(Symbol t,
             Tree a1,
             Tree a2,
             Tree a3,
             Tree a4)
 o Tree
 public Tree(Symbol t,
             Tree a1,
             Tree a2,
             Tree a3,
             Tree a4,
             Tree a5)
 o Tree
 public Tree(Symbol t,
             Tree a1,
             Tree a2,
             Tree a3,
             Tree a4,
             Tree a5,
             Tree a6)
 o Tree
 public Tree(Symbol t,
             Tree a1,
             Tree a2,
             Tree a3,
             Tree a4,
             Tree a5,
             Tree a6,
             Tree a7)

Methods

 o main
 public static void main(String argv[])
テスト用のメソッドです。

 o tag
 public Symbol tag()
抽象構文木の種類を表す tag を取り出します。

 o args
 public Tree[] args()
抽象構文木の subtree を取り出します。

 o lineNumber
 public int lineNumber()
このノードの行番号情報を返します。. 行番号情報は、このノードを表現していた構文の先頭の行番号です。 構文解析パスではなく マクロ展開パスで生成されるノードには、行番号情報はありません。 行番号情報がない場合は -1 を返します。

 o beginningPoint
 public int beginningPoint()
このノードの開始位置の point を返します。. このメソッドは、まだ実装されていません。

See Also:
EppInputStream
 o endPoint
 public int endPoint()
このノードの終了位置の point を返します。. このメソッドは、まだ実装されていません。

See Also:
EppInputStream
 o type
 public Type type()
このノードの型を返します。. 型が未決定の場合は fatal error になります。

 o property
 public Object property(Symbol key)
ノードに付けられたプロパティを検索して返します。.

See Also:
modifyProperty
 o idName
 public Symbol idName()
このノードが Identifier ならば、その名前を返します。. そうでなければ、 fatal error です。

 o literalToken
 public LiteralToken literalToken()
このノードが LiteralTree ならば、その中身を表す LiteralToken を返します。. そうでなければ、 fatal error です。

 o modifyArgs
 public Tree modifyArgs(Tree args[])
このノードの args のみを変更した Tree を作って返します。. 行番号情報など、 args 以外の全ての情報は新たな Tree にコピーされます。

 o isTyped
 public boolean isTyped()
このメソッドが型情報を持っていれば true 、そうでなければ false を 返します。

 o modifyTypeAndArgs
 public Tree modifyTypeAndArgs(Type type,
                               Tree args[])
このノードの type と args のみを変更した Tree を作って返します。. 行番号情報など、他の全ての情報は新たな Tree にコピーされます。 この Tree がすでに型情報を持っている場合は fatal error になります。

 o resetType
 public Tree resetType()
型情報を持たない Tree を作って返します。. 型情報以外の全ての情報は、もとの Tree から新たな Tree にコピーされます。

 o modifyProperty
 public Tree modifyProperty(Symbol key,
                            Object val)
このノードのプロパティを変更した Tree を作って返します。. 付加情報以外の全ての情報は、 もとの Tree から新たな Tree にコピーされます。

See Also:
property
 o modifyLineNumber
 public Tree modifyLineNumber(int x)
 o modifyBeginningPoint
 public Tree modifyBeginningPoint(int x)
 o modifyEndPoint
 public Tree modifyEndPoint(int x)
 o nameEqual
 public static boolean nameEqual(Tree name1,
                                 Tree name2)
:name をタグに持つ Tree 同士を比較します。.

 o nameToString
 public String nameToString()
:name をタグに持つ Tree を文字列に変換します。. 例えば、 (name (id a) (id b) (id c)) は "a.b.c" になります。

 o print
 public Tree print()
Opts.out に、人間に見やすいように中身を出力するデバッグ用メソッドです。. tree.print() と書けば、 tree が、人間に見やすいようにインデントされて 出力されます。 このメソッドは返値として、自分自身を返します。

epp コマンドの起動時のオプションに応じて、 型情報、行番号情報も同時に出力されます。

これらの情報がついていない場合は、 出力結果をカットアンドペーストして、そのまま BackQuote macro の一部として 使うことができます。

 o print
 public Tree print(PrintWriter out)
 o print
 public void print(PrintWriter out,
                   String indent)
 o printProp
 public void printProp(PrintWriter out)
 o toString
 public String toString()
Convert tree to String without indentation.

Overrides:
toString in class Object
 o quoteString
 public static String quoteString(String in)
This method is called by class Identifier and LiteralToken.
   Examples:
  	"foo" -> "¥"foo¥""
  	"¥n" -> "¥"¥¥n¥""
  	"¥"" => "¥"¥¥¥"¥""

 o stringToNameTree
 public static Tree stringToNameTree(String str)

All Packages  Class Hierarchy  This Package  Previous  Next  Index