ほぼタイトルの通りです。先日導入した、Macro PEG + 後方参照の拡張を利用することで、変数宣言のテーブルのようなものを構文解析時に作り出すことができるようになったので、それを利用することで、変数宣言をみるたびごとに、table | varible
のようにして、ORで定義した変数名を追加していきます。
規則Statements
の定義がポイントです。
def Statements(table: P[Any]): P[Any] = VAL ~ Identifier.evalCC{i => EQ ~ Expression(table) ~ SEMI_COLON ~ refer(Statements(table | i)).? } / Expression(table) ~ SEMI_COLON ~ refer(Statements(table)).?
val s = 1;
のような変数宣言を見つけたら、s
をリテラルとしてテーブルに追加して続きを読むという作業を行っています。そして、式の中で、table
にある変数が出現した場合のみ、識別子として許可するということを、and-predicateを用いて行います:
def Primary(table: P[Any]): P[Any] = table.and ~ Identifier | IntegerLiteral | (OPEN ~ refer(Expression(table)) ~ CLOSE)
ここではあえてしていませんが、変数のundefといった文があった場合も、not-predicateを用いて同様に記述することができます。
Macro PEGに後方参照を追加すると、扱える文法の範囲がかなり拡大します。