blogこの広告は、90日以上更新していないブログに表示しています。使うClojure前記事と似たような話。プログラミングHaskellの第8章で紹介されているパーサコンビネータと同じようなことができるfnparseというライブラリがClojureにも存在する。31章)にもあるが、どれも似たような感じのものだ。いつもと同じようにLeiningenのプロジェクトを作って、下記のように指定する。depsルールfnparseは「ルール」という種類の関数と、それを組み合わせて新たなルールを作る「ルールクリエータ」という種類の関数で構成される。ルールまずはシンプルなルールから。\a]})nilこのsimple-aは文字\aのみにマッチするパーサだ。litというのがルールクリエータで、第一引数にマッチするパーサを戻り値として返す関数だ。帰ってきたパーサをsimple-aにバインドする。次に、ルールsimple-aに状態(state)を与えて、戻り値としてパース結果と残りの列を含む状態を得ている。マッチしない列を与えてやると、nilが返る。(先頭からパースするので、マッチしない。)\aと\bと\cにマッチするパーサをそれぞれ準備し、順々に適用していけば、最後には残り(remainder)列がnilになる。文字列は勝手に文字のシーケンスに変わる。nil}]ルールクリエータはlitだけでなく、マッチの条件を示す述語をとるルールクリエータもある。下記は小文字のみにマッチするルールを作っている。\c)}]これだと、それぞれの呼出で一文字ずつしかマッチしないが、複数の文字を連続でマッチさせる方法もある。concはルールクリエータであり、与えられた引数を前から順にマッチさせ、それぞれの結果を順にシーケンスとして返す。最後まで全部マッチしなければルール全体が失敗し、nilを返す。"abbc"})nilconcのような連接だけでなく、複数のルールから一つを選ぶルールクリエータも存在する。下記のaltは、引数で与えられたルールを順にチェックし、マッチしたものを返す。"cdcdcd"})nil連接(conc)、選択(alt)とくれば次は反復だが、もちろん反復も存在する。反復系のルールクリエータはいくつも存在するので、代表的な一つだけ紹介する。下記のrep*は、指定されたルールを0以上個できるだけ多くマッチさせる(最長一致)。"dcdcd"}]さらにもうひとつ、最もよく使うものとしてcomplexがある。これは基本的にはconcと同じなのだが、それぞれのパース結果を加工することができる。nil}]だいたいこれだけ覚えていれば、文脈自由文法が表現できるはず。set-infoを使うことで、文脈依存文法も扱えるようになるのだが、説明し始めると長くなるので、公式の説明を参照。https://github.com/joshua-choi/fnparse/wiki最後に、特殊ルールとルールクリエータの一覧を。特殊ルールこれはルールクリエータではなく、単なるルールだということに注意。a要素aにマッチする。(aは文字でなくても良い。a)が真になるようなaにマッチする。...選択(まずは先に書いたルールでパースし、バックトラックが起こったら次のルールへ行く。rule最短一致(はじめは0から検査し、バックトラックが起こるたびに1ずつ増やしながら検査する。fail-rulematch-ruleにマッチする。fail-ruleにもマッチしたら失敗。ruleマッチするが、remainderを消費しない。altとfactor系のルールはバックトラックが頻繁に起こるので、なるべく減らしたほうが速いパーサになるはず。*1:ずいぶん前に買ったので、古いのしか持ってない。使うclojure.core.logicでPrologのような論理型プログラミングGTK-Serverを使ってシェルからGUI月別アーカイブはてなブログをはじめよう!t2ruさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。