kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

Macro PEG with 後方参照で、「変数宣言がない場合エラー」を構文解析時にチェックする

ほぼタイトルの通りです。先日導入した、Macro PEG + 後方参照の拡張を利用することで、変数宣言のテーブルのようなものを構文解析時に作り出すことができるようになったので、それを利用することで、変数宣言をみるたびごとに、table | varibleのようにして、ORで定義した変数名を追加していきます。

gist.github.com

規則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に後方参照を追加すると、扱える文法の範囲がかなり拡大します。