ちょっと前に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