Skip to content

Instantly share code, notes, and snippets.

@igstan
Created June 9, 2011 13:29
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save igstan/1016726 to your computer and use it in GitHub Desktop.
Save igstan/1016726 to your computer and use it in GitHub Desktop.
JavaScript Monadic Parser Combinators
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