ちょっと前にjavascriptで構文解析とかがはやった気がするので、javascriptのリハビリがてらかいてみた。
ググってみると
あたりがあるのだが、まぁ勉強ということで。javascriptらしく書いてみようかと。
ということで、モナドがどーたらとか難しい話はまぁおいておいて、簡単に値がとりだせますよ、という見栄え重視で作ってみた。基本的な機能しかない。けど拡張するのは簡単。せめて相互再帰くらいは実装したほうがよかったかな。まぁ、こんなの真剣に使う人もいないと思うので、要望があればってことで。ちなみに依存するライブラリはありません。
ダウンロード:Inforno.Parsec
たとえばこんな感じにCSVのパーサが定義できる。withを使ってDSLっぽくしてみた。
javascript code
var CSVParser = Inforno.Parsec.Parsers.define(function(){with(this){this.chars = chrLike(function(c){ return c != '' && c!=',' && c!='\n' && c!='"';});this.quote = chr('"')this.quoteInQuote = str('""') .ret(function(){return '"';});this.charInQuote = chrLike(function(c){ return c!='"';});this.quotedField = quote .and (rep((quoteInQuote) .or (charInQuote))) .and (quote).ret(function(q1, cs, q2){return cs.join("");});this.field = rep1(chars) .ret(Return.str)this.record = sep( (field) .or (quotedField), chr(","), true) .ret(function(fields) {return {fields: fields};})this.csv = sep(record, chr("\n"), true) .and(eof) .ret(function(records) {return {records : records};})}});var testCsv = ['"aaa","b','bb","ccc",zzz,"y""Y""y",xxx'].join("\n");var parser = new CSVParser(testCsv);var parseResult = parser.csv.parse()if(parseResult.success()) {var records = parseResult.result[0].records;for(var i=0,l=records.length;i<l;i++){alert("row("+i+") "+records[i].fields);}}
実はパーサコンビネータって簡単にかけるんだけど、世間的にちゃんと認識されているのかなあ。思うに、パーサコンビネータといえばHaskell界隈であり 、関数型界隈であり(もちろんちゃんとJAVAとかの実装もあるんだけど)、モナドでありそういうところって専門用語が多いから「ふつうの」プログラマからは簡単に見えてないような気がするなあ。
No comments yet
trackback uriLeave a Comment