不確定特異点

広く深く、ところどころ超深く

cl-lex と CL-Yacc で作る JSON パーサ

Common Lisp の lex/yacc ライブラリを探していたところ、cl-lex と CL-Yacc というそのものズバリのライブラリがありました。

使い方を理解するために JSON パーサを書いてみました。JSON 文字列を読み込んで S 式に変換するだけです。jsown の出力形式に似せてみました。

gist.github.com

define-string-lexer は字句解析器を生成する cl-lex のマクロです。CL-PPCRE の正規表現を使ってトークンを定義できます。

define-parser構文解析器を生成する CL-Yacc のマクロです。start-symbol で出発記号、terminals で終端記号を指定し、その下に非終端記号による生成規則を列挙してます。生成規則にマッチしたら、lambda 式の部分が評価されて、その結果が構文解析結果として返るようになっているようです。

parse-with-lexer に字句解析器と構文解析器を指定してパースする形になります。今回、字句解析器は cl-lex を使って生成しましたが、独自の字句解析器を組み合わせることも可能です。

また、define-string-lexer は文字列に対する字句解析器ですが、これをストリーム用に変換する stream-lexer という関数もありました。ファイルから読み込むときはこれを使った方がよさそうです。

なお、上記のコードは SLIME 上で C-c C-k で REPL に読み込み、REPL 上から直接実行して実験していたため、スクリプト実行対応はしてません。また、テストも十分にされてません。