[[FrontPage]]

2008/06/26からのアクセス回数 &counter;

#contents

ここでは、[[antlr/ANTLRWorksを使ってみる]]に続いて、例題を構文木を使った
解析に変更して、ANTLRWorksでのデバッグ方法も合わせて紹介する。

** 構文木生成 [#y3eb38a0]
例題を四則演算に戻し、変数を導入したのが以下のE3.gです。

#pre{{
grammar E3;

options{
	output = AST;
	ASTLabelType = CommonTree;
}

tokens{
	ASSIGN; ALU_ADD; ALU_SUB; ALU_MUL; ALU_DIV;
}

prog
	: (
	  statement
		{ if ($statement.tree != null) System.out.println($statement.tree.toStringTree());}
	  )+

	;
statement
	: expression NEWLINE!
	| IDENTIFIER '=' expression NEWLINE
		-> ^(ASSIGN IDENTIFIER expression)
	| NEWLINE!
	;
expression 
	: product (aop^ product)*
	;
aop
	: '+'
		-> ALU_ADD
	| '-'
		-> ALU_SUB
	;
product 
	: factor (pop^ factor)*
	;
pop
	: '*'
		-> ALU_MUL
	| '/'
		-> ALU_DIV
	;
factor 
	: IDENTIFIER
	| CONSTANT
	| '('! expression ')'!
	;

IDENTIFIER	:   ('a'..'z'|'A'..'Z')+ ;
CONSTANT	:   '0'..'9'+ ;
NEWLINE		:   '\r'? '\n' ;
WS		:   (' '|'\t')+ {skip();} ;
}}

*** optionsの変更 [#u9fdd2d8]
optionsに
#pre{{
options{
	output = AST;
	ASTLabelType = CommonTree;
}
}}
とし、出力を構文木、ASTLabelTypeを標準のCommonTreeと宣言します。

*** tokenの追加 [#a09717d4]
出力された構文木が言語依存しないようにtokensでオペレータのトークンを宣言します。
#pre{{
tokens{
	ASSIGN; ALU_ADD; ALU_SUB; ALU_MUL; ALU_DIV;
}
}}

ここでは、代入と四則演算を定義しました。

*** 構文木生成オペレータ [#ze05aae2]
構文木を生成する場合に便利なオペレータ!と^の使い方について説明します。

構文木は、
#pre{{
^(ルート 要素1 要素2 ...)
}}
のように表現し、ルート要素の子要素として、要素1、要素2が生成されることを表します。

構文木生成オペレータは、構文の要素の後に!または、^を続けて付けて使用します。

- ^は、指定された要素をルートとするツリーを生成します
- !は、指定された要素を構文木に出力しません

statementを例に説明すると

#pre{{
	: expression NEWLINE!
}}
は、NEWLINEを構文木に出力せず、expressionを返す形になります。

#pre{{
文法定義 -> 構文木置換定義
}}
->オペレータで構文木の置換方法を指定します。

#pre{{
	| IDENTIFIER '=' expression NEWLINE
		-> ^(ASSIGN IDENTIFIER expression)
}}
は、
  ^(ASSIGN IDENTIFIER expression)
のように代入トークンの下に識別子とその値(expression)の構文木を生成するように指定します。

progの定義で
#pre{{
		{ if ($statement.tree != null) System.out.println($statement.tree.toStringTree());}
}}
の部分で確認のために、生成されたツリーを出力しています。

*** Debuggerで動作を確認 [#q8333fbb]
入力として
#pre{{
a=1
a+2*3

}}
を入力したときのOutputとASTの画面です。

#ref(E3_AST.jpg);


** コメント [#r3273b40]
この記事は、

#vote(おもしろかった,そうでもない,わかりずらい)

皆様のご意見、ご希望をお待ちしております。

#comment

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
SmartDoc