Parse::RecDescentでJSONをパース

JSON::Hatchet の構文解析子 - Tociyuki::DiaryのJSONパーサがすっきりと書けていたのものだから,ちょっとうちもJSONパースしたくなってので書いてみました.といってもLL構文のパーサを1から書くのも芸がない感じだったので.Parse::RecDescentというCPANモジュールを使ってJSONのパーシングをしてみました.

Parse::RecDescentはその名のとおり,汎用の再帰下降型パーサです.LL(1)文法にのっとっていれば,パースが可能です.*1

id:tociyukiさんがの記事にあるBNFを流用させてもらい,JSONのパーサを書くと以下のようになりました.

このように,BNFっぽいものを記述するだけでパースを行うことができてお手軽です.パターンとして正規表現を書くこともできて,スキャナーに相当することもやってくれてます.

構文規則に合わせてパージングにともなう処理を記述できます.各要素の左にあるブレースの中がそれです.処理部分を省略すると,マッチした構文要素がそのまま返ります.ここでは,arrayやobjectのパース時に,これらに相当するPerlのArrayとHashを生成して要素を追加するようにしています.

構文規則とそれにともなう処理をまとめて書けるので,ちょっとした記法(特殊なURLとかおれおれWiki記法みたいまもの)をパースするのに便利そうです.Parse::RecDescent自体,BNFをパースして実行するDSL*2を提供していて,内部でevalとかしまくってるぽいので,このコードを読んでみるのもおもしろそうですねー.

*1:もうすこし拡張された文法もパースできるっぽい?

*2:というか文字列をパースしてるのでDSLではないか