XMLパーサっぽいの
30分プログラム、その226。XMLパーサっぽい何か。
OCamlDuceなどの
Javascript-Parsecとprototype.jsを使っている。
使い方
var parser = new DuceParser('<foo>[ <bar>[] <baz>"xyzzy" ]'); var result = parser.xml.parse(); if(result.success()){ console.log(result.result); # => ["<foo><bar></bar><baz>xyzzy</baz></foo>"] }else{ console.log('fail'); }
ソースコード
// include var DuceParser = Inforno.Parsec.Parsers.define(function(){ with(this){ this.alpha = chrLike(function(c){ return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')}); this.dash = chr('-'); // lexer this.space = chrLike(function(c){ return ' \t\n\r'.toArray().include(c); }).retval(''); this.spaces = many(this.space).retval(''); this.ident = alpha.$(many(alpha.l(dash))).ret(function(a,b){ return a+b.join(''); }).$(spaces).ret(function(a,_){ return a;});; // string this.sChar = chrLike(function(c){ return c != '"';}) .l (str('\\"').retval('"')); this.string = between(chr('"'), many(sChar), chr('"')).ret(function(c){ return c.join('');}).$(spaces); // sequence(e.g. [<foo>[] <bar>[] <baz>[]]) this.seq = between(chr('[').$(spaces).retval(''), sepBy(p('xml'),spaces,true).ret(function(cs){ if(cs){ return cs.join(''); } }), spaces.$(chr(']'))).ret(function(cs){ return cs; }).$(spaces); // tag this.tag = between(chr('<'), p('ident'), chr('>')); var t = new Template('<#{tag}>#{child}</#{tag}>'); this.xml = tag.$(string.l(seq)).ret(function(tag,child){ return t.evaluate({ tag:tag, child:child}); }); }});