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
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
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