| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | 
							- /*
 
- 	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;
 
 
  |