Comparing version 0.0.1 to 0.0.5
{ | ||
"name": "parsimmon", | ||
"version": "0.0.1", | ||
"version": "0.0.5", | ||
"description": "A monadic LL(infinity) parser combinator library", | ||
@@ -13,6 +13,6 @@ "keywords": ["parsing", "parse", "parser combinators"], | ||
"mocha": "*", | ||
"uglify-js": "*" | ||
"uglify-js": "2.x" | ||
}, | ||
"dependencies": { | ||
"pjs": "*" | ||
"pjs": "3.x" | ||
}, | ||
@@ -19,0 +19,0 @@ "scripts": { |
var Parsimmon = {}; | ||
Parsimmon.Parser = P(function(_, _super, Parser) { | ||
"use strict"; | ||
// The Parser object is a wrapper for a parser function. | ||
@@ -11,11 +12,13 @@ // Externally, you use one to parse a string by calling | ||
function parseError(stream, message) { | ||
if (stream) { | ||
stream = "'"+stream+"'"; | ||
function parseError(stream, i, expected) { | ||
if (i === stream.length) { | ||
var message = 'expected ' + expected + ', got the end of the string'; | ||
} | ||
else { | ||
stream = 'EOF'; | ||
var prefix = (i > 0 ? "'..." : "'"); | ||
var suffix = (stream.length - i > 12 ? "...'" : "'"); | ||
var message = 'expected ' + expected + ' at character ' + i + ', got ' | ||
+ prefix + stream.slice(i, i+12) + suffix; | ||
} | ||
throw 'Parse Error: '+message+' at '+stream; | ||
throw 'Parse Error: ' + message + "\n parsing: '" + stream + "'"; | ||
} | ||
@@ -26,5 +29,5 @@ | ||
_.parse = function(stream) { | ||
return this.skip(eof)._(stream, success, parseError); | ||
return this.skip(eof)._(stream, 0, success, parseError); | ||
function success(stream, result) { return result; } | ||
function success(stream, i, result) { return result; } | ||
}; | ||
@@ -36,7 +39,7 @@ | ||
return Parser(function(stream, onSuccess, onFailure) { | ||
return self._(stream, onSuccess, failure); | ||
return Parser(function(stream, i, onSuccess, onFailure) { | ||
return self._(stream, i, onSuccess, failure); | ||
function failure(newStream) { | ||
return alternative._(stream, onSuccess, onFailure); | ||
function failure(stream, newI) { | ||
return alternative._(stream, i, onSuccess, onFailure); | ||
} | ||
@@ -49,8 +52,8 @@ }); | ||
return Parser(function(stream, onSuccess, onFailure) { | ||
return self._(stream, success, onFailure); | ||
return Parser(function(stream, i, onSuccess, onFailure) { | ||
return self._(stream, i, success, onFailure); | ||
function success(newStream, result) { | ||
function success(stream, newI, result) { | ||
var nextParser = (next instanceof Parser ? next : next(result)); | ||
return nextParser._(newStream, onSuccess, onFailure); | ||
return nextParser._(stream, newI, onSuccess, onFailure); | ||
} | ||
@@ -61,12 +64,25 @@ }); | ||
// -*- optimized iterative combinators -*- // | ||
// equivalent to: | ||
// _.many = function() { | ||
// return this.times(0, Infinity); | ||
// }; | ||
// or, more explicitly: | ||
// _.many = function() { | ||
// var self = this; | ||
// return self.then(function(x) { | ||
// return self.many().then(function(xs) { | ||
// return [x].concat(xs); | ||
// }); | ||
// }).or(succeed([])); | ||
// }; | ||
_.many = function() { | ||
var self = this; | ||
return Parser(function(stream, onSuccess, onFailure) { | ||
return Parser(function(stream, i, onSuccess, onFailure) { | ||
var xs = []; | ||
while (self._(stream, success, failure)); | ||
return onSuccess(stream, xs); | ||
while (self._(stream, i, success, failure)); | ||
return onSuccess(stream, i, xs); | ||
function success(newStream, x) { | ||
stream = newStream; | ||
function success(stream, newI, x) { | ||
i = newI; | ||
xs.push(x); | ||
@@ -82,2 +98,22 @@ return true; | ||
// equivalent to: | ||
// _.times = function(min, max) { | ||
// if (arguments.length < 2) max = min; | ||
// var self = this; | ||
// if (min > 0) { | ||
// return self.then(function(x) { | ||
// return self.times(min - 1, max - 1).then(function(xs) { | ||
// return [x].concat(xs); | ||
// }); | ||
// }); | ||
// } | ||
// else if (max > 0) { | ||
// return self.then(function(x) { | ||
// return self.times(0, max - 1).then(function(xs) { | ||
// return [x].concat(xs); | ||
// }); | ||
// }).or(succeed([])); | ||
// } | ||
// else return succeed([]); | ||
// }; | ||
_.times = function(min, max) { | ||
@@ -87,3 +123,3 @@ if (arguments.length < 2) max = min; | ||
return Parser(function(stream, onSuccess, onFailure) { | ||
return Parser(function(stream, i, onSuccess, onFailure) { | ||
var xs = []; | ||
@@ -93,26 +129,26 @@ var result = true; | ||
for (var i = 0; i < min; i += 1) { | ||
result = self._(stream, success, firstFailure); | ||
if (!result) return onFailure(stream, failure); | ||
for (var times = 0; times < min; times += 1) { | ||
result = self._(stream, i, success, firstFailure); | ||
if (!result) return onFailure(stream, i, failure); | ||
} | ||
for (; i < max && result; i += 1) { | ||
result = self._(stream, success, secondFailure); | ||
for (; times < max && result; times += 1) { | ||
result = self._(stream, i, success, secondFailure); | ||
} | ||
return onSuccess(stream, xs); | ||
return onSuccess(stream, i, xs); | ||
function success(newStream, x) { | ||
function success(stream, newI, x) { | ||
xs.push(x); | ||
stream = newStream; | ||
i = newI; | ||
return true; | ||
} | ||
function firstFailure(newStream, msg) { | ||
function firstFailure(stream, newI, msg) { | ||
failure = msg; | ||
stream = newStream; | ||
i = newI; | ||
return false; | ||
} | ||
function secondFailure(newStream, msg) { | ||
function secondFailure(stream, newI, msg) { | ||
return false; | ||
@@ -146,12 +182,12 @@ } | ||
var len = str.length; | ||
var expected = "expected '"+str+"'"; | ||
var expected = "'"+str+"'"; | ||
return Parser(function(stream, onSuccess, onFailure) { | ||
var head = stream.slice(0, len); | ||
return Parser(function(stream, i, onSuccess, onFailure) { | ||
var head = stream.slice(i, i+len); | ||
if (head === str) { | ||
return onSuccess(stream.slice(len), head); | ||
return onSuccess(stream, i+len, head); | ||
} | ||
else { | ||
return onFailure(stream, expected); | ||
return onFailure(stream, i, expected); | ||
} | ||
@@ -164,13 +200,13 @@ }); | ||
var expected = 'expected '+re; | ||
var expected = ''+re; | ||
return Parser(function(stream, onSuccess, onFailure) { | ||
var match = re.exec(stream); | ||
return Parser(function(stream, i, onSuccess, onFailure) { | ||
var match = re.exec(stream.slice(i)); | ||
if (match) { | ||
var result = match[0]; | ||
return onSuccess(stream.slice(result.length), result); | ||
return onSuccess(stream, i+result.length, result); | ||
} | ||
else { | ||
return onFailure(stream, expected); | ||
return onFailure(stream, i, expected); | ||
} | ||
@@ -181,10 +217,10 @@ }); | ||
var succeed = Parsimmon.succeed = function(result) { | ||
return Parser(function(stream, onSuccess) { | ||
return onSuccess(stream, result); | ||
return Parser(function(stream, i, onSuccess) { | ||
return onSuccess(stream, i, result); | ||
}); | ||
}; | ||
var fail = Parsimmon.fail = function(msg) { | ||
return Parser(function(stream, _, onFailure) { | ||
return onFailure(stream, msg); | ||
var fail = Parsimmon.fail = function(expected) { | ||
return Parser(function(stream, i, _, onFailure) { | ||
return onFailure(stream, i, expected); | ||
}); | ||
@@ -200,17 +236,17 @@ }; | ||
var any = Parsimmon.any = Parser(function(stream, onSuccess, onFailure) { | ||
if (!stream) return onFailure(stream, 'expected any character'); | ||
var any = Parsimmon.any = Parser(function(stream, i, onSuccess, onFailure) { | ||
if (i >= stream.length) return onFailure(stream, i, 'any character'); | ||
return onSuccess(stream.slice(1), stream.charAt(0)); | ||
return onSuccess(stream, i+1, stream.charAt(i)); | ||
}); | ||
var all = Parsimmon.all = Parser(function(stream, onSuccess, onFailure) { | ||
return onSuccess('', stream); | ||
var all = Parsimmon.all = Parser(function(stream, i, onSuccess, onFailure) { | ||
return onSuccess(stream, stream.length, stream.slice(i)); | ||
}); | ||
var eof = Parsimmon.eof = Parser(function(stream, onSuccess, onFailure) { | ||
if (stream) return onFailure(stream, 'expected EOF'); | ||
var eof = Parsimmon.eof = Parser(function(stream, i, onSuccess, onFailure) { | ||
if (i < stream.length) return onFailure(stream, i, 'EOF'); | ||
return onSuccess(stream, stream); | ||
return onSuccess(stream, i, ''); | ||
}); | ||
}); |
@@ -6,2 +6,6 @@ var assert = require('assert') | ||
function partialEquals(x) { | ||
return function(y) { return x === y; } | ||
} | ||
suite('parser', function() { | ||
@@ -21,3 +25,4 @@ var string = Parsimmon.string; | ||
assert.equal(parser.parse('x'), 'x'); | ||
assert.throws(function() { parser.parse('y') }) | ||
assert.throws(function() { parser.parse('y') }, | ||
partialEquals("Parse Error: expected 'x' at character 0, got 'y'\n parsing: 'y'")); | ||
}); | ||
@@ -30,3 +35,4 @@ | ||
assert.equal(parser.parse('4'), '4'); | ||
assert.throws(function() { parser.parse('x'); }); | ||
assert.throws(function() { parser.parse('x'); }, | ||
partialEquals("Parse Error: expected /^[0-9]/ at character 0, got 'x'\n parsing: 'x'")); | ||
assert.throws(function() { regex(/./) }, 'must be anchored'); | ||
@@ -39,4 +45,6 @@ }); | ||
assert.equal(parser.parse('xy'), 'y'); | ||
assert.throws(function() { parser.parse('y'); }); | ||
assert.throws(function() { parser.parse('xz'); }); | ||
assert.throws(function() { parser.parse('y'); }, | ||
partialEquals("Parse Error: expected 'x' at character 0, got 'y'\n parsing: 'y'")); | ||
assert.throws(function() { parser.parse('xz'); }, | ||
partialEquals("Parse Error: expected 'y' at character 1, got '...z'\n parsing: 'xz'")); | ||
}); | ||
@@ -206,3 +214,4 @@ | ||
assert.throws(function() { parser.parse('y'); }); | ||
assert.throws(function() { parser.parse('y'); }, | ||
partialEquals("Parse Error: expected 'x' at character 0, got 'y'\n parsing: 'y'")); | ||
assert.equal(parser.parse('x'), 'x'); | ||
@@ -219,3 +228,3 @@ }); | ||
if (operator === allowedOperator) return succeed(operator); | ||
else return fail('expected '+allowedOperator); | ||
else return fail(allowedOperator); | ||
}) | ||
@@ -227,7 +236,9 @@ .skip(string('y')) | ||
assert.equal(parser.parse('x+y'), '+'); | ||
assert.throws(function() { parser.parse('x*y'); }); | ||
assert.throws(function() { parser.parse('x*y'); }, | ||
partialEquals("Parse Error: expected + at character 2, got '...y'\n parsing: 'x*y'")); | ||
allowedOperator = '*'; | ||
assert.equal(parser.parse('x*y'), '*'); | ||
assert.throws(function() { parser.parse('x+y'); }); | ||
assert.throws(function() { parser.parse('x+y'); }, | ||
partialEquals("Parse Error: expected * at character 2, got '...y'\n parsing: 'x+y'")); | ||
}); | ||
@@ -234,0 +245,0 @@ }); |
Sorry, the diff of this file is not supported yet
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 3 instances in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
405
0
136
0
22544