summaryrefslogtreecommitdiffstats
path: root/node_modules/fastparse/lib/Parser.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/fastparse/lib/Parser.js')
-rw-r--r--node_modules/fastparse/lib/Parser.js108
1 files changed, 108 insertions, 0 deletions
diff --git a/node_modules/fastparse/lib/Parser.js b/node_modules/fastparse/lib/Parser.js
new file mode 100644
index 0000000..7f47c58
--- /dev/null
+++ b/node_modules/fastparse/lib/Parser.js
@@ -0,0 +1,108 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+function ignoreFunction() {}
+
+function createReturningFunction(value) {
+ return function() {
+ return value;
+ };
+}
+
+function Parser(states) {
+ this.states = this.compileStates(states);
+}
+
+Parser.prototype.compileStates = function(states) {
+ var result = {};
+ Object.keys(states).forEach(function(name) {
+ result[name] = this.compileState(states[name], states);
+ }, this);
+ return result;
+};
+
+Parser.prototype.compileState = function(state, states) {
+ var regExps = [];
+ function iterator(str, value) {
+ regExps.push({
+ groups: Parser.getGroupCount(str),
+ regExp: str,
+ value: value
+ });
+ }
+ function processState(statePart) {
+ if(Array.isArray(statePart)) {
+ statePart.forEach(processState);
+ } else if(typeof statePart === "object") {
+ Object.keys(statePart).forEach(function(key) {
+ iterator(key, statePart[key]);
+ });
+ } else if(typeof statePart === "string") {
+ processState(states[statePart]);
+ } else {
+ throw new Error("Unexpected 'state' format");
+ }
+ }
+ processState(state);
+ var total = regExps.map(function(r) {
+ return "(" + r.regExp + ")";
+ }).join("|");
+ var actions = [];
+ var pos = 1;
+ regExps.forEach(function(r) {
+ var fn;
+ if(typeof r.value === "function") {
+ fn = r.value;
+ } else if(typeof r.value === "string") {
+ fn = createReturningFunction(r.value);
+ } else {
+ fn = ignoreFunction;
+ }
+ actions.push({
+ name: r.regExp,
+ fn: fn,
+ pos: pos,
+ pos2: pos + r.groups + 1
+ });
+ pos += r.groups + 1;
+ });
+ return {
+ regExp: new RegExp(total, "g"),
+ actions: actions
+ };
+};
+
+Parser.getGroupCount = function(regExpStr) {
+ return new RegExp("(" + regExpStr + ")|^$").exec("").length - 2;
+};
+
+Parser.prototype.parse = function(initialState, string, context) {
+ context = context || {};
+ var currentState = initialState;
+ var currentIndex = 0;
+ for(;;) {
+ var state = this.states[currentState];
+ var regExp = state.regExp;
+ regExp.lastIndex = currentIndex;
+ var match = regExp.exec(string);
+ if(!match) return context;
+ var actions = state.actions;
+ currentIndex = state.regExp.lastIndex;
+ for(var i = 0; i < actions.length; i++) {
+ var action = actions[i];
+ if(match[action.pos]) {
+ var ret = action.fn.apply(context, Array.prototype.slice.call(match, action.pos, action.pos2).concat([state.regExp.lastIndex - match[0].length, match[0].length]));
+ if(ret) {
+ if(!(ret in this.states))
+ throw new Error("State '" + ret + "' doesn't exist");
+ currentState = ret;
+ }
+ break;
+ }
+ }
+ }
+};
+
+module.exports = Parser;