Created
June 9, 2011 13:29
-
-
Save igstan/1016726 to your computer and use it in GitHub Desktop.
JavaScript Monadic Parser Combinators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var bind = function (prev, bridge) { | |
return function (input) { | |
var result = prev(input); | |
return result.length === 0 ? result : bridge(result[0])(result[1]); | |
}; | |
}; | |
var result = function (a) { | |
return function (input) { | |
return [a, input]; | |
} | |
}; | |
var failure = function () { | |
return function (input) { | |
return []; | |
}; | |
}; | |
var choice = function (p, q) { | |
return function (input) { | |
var r = p(input); | |
return r.length > 0 ? r : q(input); | |
}; | |
}; | |
var item = function () { | |
return function (input) { | |
return input.length ? [input[0], input.slice(1)] : []; | |
}; | |
}; | |
var satisfies = function (predicate) { | |
return bind(item(), function (a) { | |
return predicate(a) ? result(a) : failure(); | |
}); | |
}; | |
var many = function (p) { | |
return choice(manyOne(p), result([])); | |
}; | |
var manyOne = function (p) { | |
return bind(p, function (x) { | |
return bind(many(p), function (xs) { | |
return result([x].concat(xs)); | |
}); | |
}); | |
}; | |
var character = function (a) { | |
return satisfies(function (b) { return a === b; }); | |
}; | |
var string = function (s) { | |
if (s === "") return result(""); | |
return bind( character(s[0]) , function (f) { | |
return bind( string( s.slice(1) ), function (fs) { | |
return result(f + fs); | |
}); | |
}); | |
}; | |
var regex = function (r) { | |
return satisfies(function (a) { | |
return r.test(a); | |
}); | |
}; | |
var lower = regex(/[a-z]/); | |
var upper = regex(/[A-Z]/); | |
var digit = regex(/[0-9]/); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment