FrontPage
2008/06/26からのアクセス回数
ここでは、antlr/ANTLRWorksを使ってみるに続いて、例題を構文木を使った 解析に変更して、ANTLRWorksでのデバッグ方法も合わせて紹介する。
例題を四則演算に戻し、変数を導入したのが以下のE3.gです。
grammar E3;
options{
}
tokens{
}
prog
statement
expression
aop
product
pop
factor
IDENTIFIER : ('a'..'z'|'A'..'Z')+ ; CONSTANT : '0'..'9'+ ; NEWLINE : '\r'? '\n' ; WS : (' '|'\t')+ {skip();} ; }}
optionsに
options{
} }} とし、出力を構文木、ASTLabelTypeを標準のCommonTreeと宣言します。
出力された構文木が言語依存しないようにtokensでオペレータのトークンを宣言します。
tokens{
} }}
ここでは、代入と四則演算を定義しました。
構文木を生成する場合に便利なオペレータ!と^の使い方について説明します。
構文木は、
^(ルート 要素1 要素2 ...) }} のように表現し、ルート要素の子要素として、要素1、要素2が生成されることを表します。
構文木生成オペレータは、構文の要素の後に!または、^を続けて付けて使用します。
statementを例に説明すると
}} は、NEWLINEを構文木に出力せず、expressionを返す形になります。
文法定義 -> 構文木置換定義 }}
}} は、
のように代入トークンの下に識別子とその値(expression)の構文木を生成するように指定します。
progの定義で
}} の部分で確認のために、生成されたツリーを出力しています。
入力として
a=1 a+2*3
}} を入力したときのOutputとASTの画面です。
出力は、1行毎の結果で、
(ASSIGN a 1) (ALU_ADD a (ALU_MUL 2 3)) }} と期待通りの結果となり、ASTも
^(nil ^(ASSIGN a 1) ^(ALU_ADD a ^(ALUMUL 2 3))) }} となっています。
ちなにみ^や!オペレータを使用しない場合には、以下のような定義になります(構文のみ抜粋)。 expression, factorの定義が複雑になっています。
prog
statement
expression
aop
product
pop
factor
}}
構文木解析T1.gは、以下のような定義になります。
tree grammar T1;
options{
}
@header { import java.util.HashMap; }
@members { HashMap memory = new HashMap(); }
prog : statement+ ;
statement
expression returns [int value]
}}
これまでは、grammar宣言を使っていましたが、構文木を扱う文法では、
のようにtree grammar宣言を使用します。
optionsでは、
options{
} }} のように
します。
header宣言では、import文やpackage文等のヘッダ情報を宣言します。
例では、HashMapをインポートしています。
@header { import java.util.HashMap; } }}
members宣言では、構文解析で使用するprivate変数やメソッドを定義します。
例では、HashMap型のmemory変数を宣言しています。
@members { HashMap memory = new HashMap(); } }}
例題の文法は、
注意すべき点は、この処理は最初の文法には依存しない点です
残念ながらANTLRWorksでは構文木を扱う文法は直接デバッグすることはできないので、テスト プログラムを作成します。
TestE.javaは、以下のように作成します。
import org.antlr.runtime.ANTLRInputStream; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.tree.CommonTree; import org.antlr.runtime.tree.CommonTreeNodeStream;
public class TestE {
} }}
ここで、T1をwalkerと宣言していますが、構文木解析プログラムがデザインパターンの ビジターパターンを採用しているからです。
T1.gをデバッグオプション付きでコード生成すると
java org.antlr.Tool -g T1.g }} ANTWorksのリモートデバッグが可能なコードを生成します。
最初にTestEを起動し、以下のような入力データを入れます。
a=1 a+2*3
}}
TestEは、
(ASSIGN a 1) (ALU_ADD a (ALU_MUL 2 3)) }} を出力して停止します。
次にANTLRWorksのDebuggerからDebug Remoteメニューを選択します。
のように入力に構文木が表示され、parse Treeで解析の結果が表示されます。
コンソールには、計算結果が表示されます。
7 }}
最後に停止ボタンを押すとプログラムは終了します。
このようにANTLRWorksを使って簡単に構文木解析のプログラムもデバッグできます。
この記事は、
皆様のご意見、ご希望をお待ちしております。