[compiler]Writing Compilers and Interpreters: その13
手強かった11章が終了。
12章 Interpreting Pascal Programsへ
定数宣言のパースができるようになった。こういう定数の宣言をパースしてクロスリファレンスをかえると、
CONST epsilon = 10; limit = -epsilon; BEGIN END.
こんな感じで、integerということとその値が表示されるところまで来た。
***Definition.PROGRAM dummy_program_name *** Identifier Line numbers ---------- ----------- epsilon 002 003 Defined as: 1 scope nesting level: 1 Type form = 0, type id = integer Value = 10 limit 003 Defined as: 1 scope nesting level: 1 Type form = 0, type id = integer Value = -10
少しずつ前へ。
chap9は型システム。想像していたより難しい。一歩ずつ行かないと。
PROGRAM Test; CONST epsilon = 1.0e-6; TYPE rec = RECORD a : real; x, y : integer; END;
こういうコードに対して、シンボルテーブルをスタックにする。
Level 0がInteger等の組込型が定義されているglobal scope。Level 1がプログラムで使用する変数が定義されている Program Scope。
Lebal 2 がレコード型の変数が定義されているScope。レコード型が出てくる度にスコープを新しく作り、フィールドに他と同じ名前の変数を使えるようにする。
chap8が終了。
for文などが動くようになった。面白くなってきた。
CASE文の処理で caseのラベルをキーにして処理を辞書に入れておくと、caseラベルが増えても一定のコストでジャンプできるハック。その辞書をメモ化するまでがセット。面白いが、いまいち速度的な意味があるのかよくわからない。
手書きパーサー作成中。
BEGIN BEGIN {Temperature conversions.} five := 3; END; END.
これのパース結果をxmlで出力できるようになった。こんな単純なのだと良いけど、これから複雑になってきたときにxmlで良いのかは良く分からない。
<COMPOUND line="1"> <COMPOUND line="2"> <ASSIGN line="3"> <VARIABLE id="five" level="0" > <INTEGER_CONSTANT value="3" > </ASSIGN> </COMPOUND> </COMPOUND>
あとは少しずつパスカルのソースを複雑にしていく。
手書きパーサーを作成中。
このPascalコードをパースして、
BEGIN BEGIN {Temperature conversions.} five := 3; END; END.
fiveを代入先の識別子として認識するところまで来ました。
====== CROSS-REFERENCE TABLE ====== Identifier Line numbers ---------- ----------- five 003 0 instructions generated
もうちょっと大きいPascalコードをパースさせると無限ループする。
デバッグする前に、パースした結果の構文ツリーがちゃんとできているか確認したい。
ちょっとしたことでもブログに書いていかないと、仕事が忙しくなるとモチベーションが消えそう。