Skip to content

Instantly share code, notes, and snippets.

@brehaut
Created July 10, 2012 23:43
Show Gist options
  • Select an option

  • Save brehaut/3086985 to your computer and use it in GitHub Desktop.

Select an option

Save brehaut/3086985 to your computer and use it in GitHub Desktop.
a minimal parser combinator lib hauled out of a project
// parser
var _parser_global_state = null;
function ParseFailed () {};
function run_parser(p, input_list) {
input_list = input_list.slice()
try {
var old_parser_input = _parser_global_state;
_parser_global_state = {
input: input_list,
index: 0
};
var ret = p();
return {
success: true,
result: ret,
remainder: _parser_global_state.input.slice(_parser_global_state.index)
}
}
catch (e) {
if (e instanceof ParseFailed) return {
success: false,
result: [],
remainder: input_list,
};
throw e;
}
finally {
_parser_global_state = old_parser_input;
}
}
// the primative parsers
function fail_p() {
throw new ParseFailed();
}
function peek_token_p(n) {
n = n || 1;
return _parser_global_state.input.slice(_parser_global_state.index, _parser_global_state.index + n);
}
function get_token_p(n) {
n = n || 1;
var index = _parser_global_state.index;
_parser_global_state.index += n;
return _parser_global_state.input.slice(index, index + n);
}
function end_of_input_p() {
if (_parser_global_state.index < _parser_global_state.input.length) fail_p();
}
function opt_p(p) {
return function () {
var index = _parser_global_state.index;
try {
return p();
}
catch (e) {
if (e instanceof ParseFailed) {
_parser_global_state.index = index;
return;
};
}
}
}
function try_p() {
var fns = Array.prototype.slice.apply(arguments),
j = fns.length;
return function () {
var index = _parser_global_state.index;
for (var i = 0; i < j; i++) {
_parser_global_state.index = index;
try {
return fns[i]();
}
catch (e) {
if (e instanceof ParseFailed) continue;
throw e;
}
}
fail_p();
}
}
function seq_p() {
var fns = Array.prototype.slice.apply(arguments),
j = fns.length;
return function () {
var l = [];
for (var i = 0; i < j; i++) {
var ret = fns[i]();
if (ret) l.push(ret);
}
return l;
}
}
// log_p always succeeds, and it logs a message too
function log_p(message) {
return function () {
console.log("Parser >", message);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment