Created
July 10, 2012 23:43
-
-
Save brehaut/3086985 to your computer and use it in GitHub Desktop.
a minimal parser combinator lib hauled out of a project
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
| // 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