Vladislav Folts 11 лет назад
Родитель
Сommit
69c11157b7
1 измененных файлов с 52 добавлено и 43 удалено
  1. 52 43
      src/parser.js

+ 52 - 43
src/parser.js

@@ -1,45 +1,52 @@
+"use strict";
+
 var assert = require("assert.js").ok;
 var Errors = require("errors.js");
 var Lexer = require("lexer.js");
 
+function implicitParser(p){
+	return typeof p === "string" ? Lexer.literal(p) : p;
+}
+
+function argumentsToParsers(args){
+	var parsers = Array.prototype.slice.call(args);
+	for(var i = 0; i < parsers.length; ++i)
+		parsers[i] = implicitParser(parsers[i]);
+	return parsers;
+}
+
 exports.and = function(/*...*/){
-	var args = arguments;
-	assert(args.length >= 2);
+	assert(arguments.length >= 2);
+	var parsers = argumentsToParsers(arguments);
 
 	return function(stream, context){
-		for(var i = 0; i < args.length; ++i){
-			if (i != 0)
+		for(var i = 0; i < parsers.length; ++i){
+			if (i)
 				Lexer.skipSpaces(stream, context);
 			
-			var p = args[i];
-			if (typeof p == "string")
-				p = Lexer.literal(p);
-			
+			var p = parsers[i];
 			if (!p(stream, context))
 				return false;
 		}
-	 	return true;
-	}
-}
+		return true;
+	};
+};
 
 exports.or = function(/*...*/){
-	var args = arguments;
-	assert(args.length >= 2);
+	assert(arguments.length >= 2);
+	var parsers = argumentsToParsers(arguments);
 
 	return function(stream, context){
-		for(var i = 0; i < args.length; ++i){
-			var p = args[i];
-			if (typeof p == "string")
-				p = Lexer.literal(p);
-			
+		for(var i = 0; i < parsers.length; ++i){
+			var p = parsers[i];
 			var savePos = stream.pos();
 			if (p(stream, context))
 				return true;
 			stream.setPos(savePos);
 		}
 		return false;
-	}
-}
+	};
+};
 
 exports.repeat = function(p){
 	return function(stream, context){
@@ -50,50 +57,52 @@ exports.repeat = function(p){
 			}
 			stream.setPos(savePos);
 			return true;
-		}
-}
+		};
+};
 
-exports.optional = function(p){
+exports.optional = function(parser){
 	assert(arguments.length == 1);
-	if (typeof(p) === "string")
-		p = Lexer.literal(p);
+	var p = implicitParser(parser);
+
 	return function(stream, context){
 		var savePos = stream.pos();
 		if ( !p(stream, context))
 			stream.setPos(savePos);
 		return true;
-		}
-}
+		};
+};
 
-exports.required = function(parser, error){
-	if (typeof(parser) === "string")
-		parser = Lexer.literal(parser);
+exports.required = function(parserOrString, error){
+	var parser = implicitParser(parserOrString);
+	
 	return function(stream, context){
 		if (!parser(stream, context))
-			throw new Errors.Error(error);
+			throw new Errors.Error(error 
+					? error 
+					: ("'" + parserOrString + "' expected"));
 		return true;
-	}
-}
+	};
+};
 
-exports.context = function(parser, contextFactory){
-	return function(stream, context){
-		var context = new contextFactory(context);
+exports.context = function(parser, ContextFactory){
+	return function(stream, child){
+		var context = new ContextFactory(child);
 		if (!parser(stream, context))
 			return false;
 		if (context.endParse)
 			return context.endParse() !== false;
 		return true;
-	}
-}
+	};
+};
 
 exports.emit = function(parser, action){
 	assert(action);
-	if (typeof(parser) === "string")
-		parser = Lexer.literal(parser);
+	var p = implicitParser(parser);
+
 	return function(stream, context){
-		if (!parser(stream, context))
+		if (!p(stream, context))
 			return false;
 		action(context);
 		return true;
-	}
-}
+	};
+};