Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

parsimmon

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

parsimmon - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

2

package.json
{
"name": "parsimmon",
"version": "0.0.5",
"version": "0.0.6",
"description": "A monadic LL(infinity) parser combinator library",

@@ -5,0 +5,0 @@ "keywords": ["parsing", "parse", "parser combinators"],

@@ -33,2 +33,18 @@ var Parsimmon = {};

function furthestFailure(onFailure, myI, myExpected) {
return function(stream, yourI, yourExpected) {
if (myI > yourI) return onFailure(stream, myI, myExpected);
else return onFailure.apply(this, arguments);
};
}
function furthestFailureSuccess(onSuccess, myFurthestFailureI, myFurthestExpected) {
return function(stream, i, result, yourFurthestFailureI, yourFurthestExpected) {
if (myFurthestFailureI > yourFurthestFailureI) {
return onSuccess(stream, i, result, myFurthestFailureI, myFurthestExpected);
}
else return onSuccess.apply(this, arguments);
};
}
// -*- primitive combinators -*- //

@@ -41,4 +57,6 @@ _.or = function(alternative) {

function failure(stream, newI) {
return alternative._(stream, i, onSuccess, onFailure);
function failure(stream, newI, expected) {
var altSuccess = furthestFailureSuccess(onSuccess, newI, expected);
var altFailure = furthestFailure(onFailure, newI, expected);
return alternative._(stream, i, altSuccess, altFailure);
}

@@ -54,5 +72,7 @@ });

function success(stream, newI, result) {
function success(stream, newI, result, furthestFailureI, furthestExpected) {
var nextParser = (next instanceof Parser ? next : next(result));
return nextParser._(stream, newI, onSuccess, onFailure);
var nextSuccess = furthestFailureSuccess(onSuccess, furthestFailureI, furthestExpected);
var nextFailure = furthestFailure(onFailure, furthestFailureI, furthestExpected);
return nextParser._(stream, newI, nextSuccess, nextFailure);
}

@@ -82,11 +102,18 @@ });

while (self._(stream, i, success, failure));
return onSuccess(stream, i, xs);
var furthestFailureI, furthestExpected;
return onSuccess(stream, i, xs, furthestFailureI, furthestExpected);
function success(stream, newI, x) {
function success(stream, newI, x, successFurthestFailureI, successFurthestExpected) {
i = newI;
xs.push(x);
furthestFailureI = successFurthestFailureI;
furthestExpected = successFurthestExpected;
return true;
}
function failure() {
function failure(stream, newI, expected) {
if (!(furthestFailureI > newI)) {
furthestFailureI = newI;
furthestExpected = expected;
}
return false;

@@ -124,30 +151,30 @@ }

var result = true;
var failure;
var furthestFailureI, furthestExpected;
for (var times = 0; times < min; times += 1) {
result = self._(stream, i, success, firstFailure);
if (!result) return onFailure(stream, i, failure);
result = self._(stream, i, success, failure);
if (!result) return onFailure(stream, furthestFailureI, furthestExpected);
}
for (; times < max && result; times += 1) {
result = self._(stream, i, success, secondFailure);
result = self._(stream, i, success, failure);
}
return onSuccess(stream, i, xs);
return onSuccess(stream, i, xs, furthestFailureI, furthestExpected);
function success(stream, newI, x) {
function success(stream, newI, x, successFurthestFailureI, successFurthestExpected) {
i = newI;
xs.push(x);
i = newI;
furthestFailureI = successFurthestFailureI;
furthestExpected = successFurthestExpected;
return true;
}
function firstFailure(stream, newI, msg) {
failure = msg;
i = newI;
function failure(stream, newI, expected) {
if (!(furthestFailureI > newI)) {
furthestFailureI = newI;
furthestExpected = expected;
}
return false;
}
function secondFailure(stream, newI, msg) {
return false;
}
});

@@ -185,3 +212,3 @@ };

if (head === str) {
return onSuccess(stream, i+len, head);
return onSuccess(stream, i+len, head, -1);
}

@@ -204,3 +231,3 @@ else {

var result = match[0];
return onSuccess(stream, i+result.length, result);
return onSuccess(stream, i+result.length, result, -1);
}

@@ -235,7 +262,7 @@ else {

return onSuccess(stream, i+1, stream.charAt(i));
return onSuccess(stream, i+1, stream.charAt(i), -1);
});
var all = Parsimmon.all = Parser(function(stream, i, onSuccess, onFailure) {
return onSuccess(stream, stream.length, stream.slice(i));
return onSuccess(stream, stream.length, stream.slice(i), -1);
});

@@ -246,4 +273,4 @@

return onSuccess(stream, i, '');
return onSuccess(stream, i, '', -1);
});
});

@@ -207,7 +207,7 @@ var assert = require('assert')

var parser = any.then(function(ch) {
return fail('character '+ch+' not allowed');
return fail('a character besides ' + ch);
}).or(string('x'));
assert.throws(function() { parser.parse('y'); },
partialEquals("Parse Error: expected 'x' at character 0, got 'y'\n parsing: 'y'"));
partialEquals("Parse Error: expected a character besides y, got the end of the string\n parsing: 'y'"));
assert.equal(parser.parse('x'), 'x');

@@ -247,2 +247,67 @@ });

});
suite('smart error messages', function() {
// this is mainly about .or(), .many(), and .times(), but not about
// their core functionality, so it's in its own test suite
suite('or', function() {
test('prefer longest branch', function() {
var parser = string('abc').then(string('def')).or(string('ab').then(string('cd')));
assert.throws(function() { parser.parse('abc'); },
partialEquals("Parse Error: expected 'def', got the end of the string\n parsing: 'abc'"));
});
test('prefer last of equal length branches', function() {
var parser = string('abc').then(string('def')).or(string('abc').then(string('d')));
assert.throws(function() { parser.parse('abc'); },
partialEquals("Parse Error: expected 'd', got the end of the string\n parsing: 'abc'"));
});
test('prefer longest branch even after a success', function() {
var parser = string('abcdef').then(string('g')).or(string('ab'))
.then(string('cd')).then(string('xyz'));
assert.throws(function() { parser.parse('abcdef'); },
partialEquals("Parse Error: expected 'g', got the end of the string\n parsing: 'abcdef'"));
});
});
suite('many', function() {
test('prefer longest branch even in a .many()', function() {
var atom = regex(/^[^()\s]+/);
var sexpr = string('(').then(function() { return list; }).skip(string(')'));
var list = optWhitespace.then(atom.or(sexpr)).skip(optWhitespace).many();
assert.deepEqual(list.parse('(a b) (c ((() d)))'), [['a', 'b'], ['c', [[[], 'd']]]]);
assert.throws(function() { list.parse('(a b ()) c)'); },
partialEquals("Parse Error: expected EOF at character 10, got '...)'\n parsing: '(a b ()) c)'"));
assert.throws(function() { list.parse('(a (b)) (() c'); },
partialEquals("Parse Error: expected ')', got the end of the string\n parsing: '(a (b)) (() c'"));
});
test('prefer longest branch in .or() nested in .many()', function() {
var parser = string('abc').then(string('def')).or(string('a')).many();
assert.deepEqual(parser.parse('aaabcdefaa'), ['a', 'a', 'def', 'a', 'a']);
assert.throws(function() { parser.parse('aaabcde'); },
partialEquals("Parse Error: expected 'def' at character 5, got '...de'\n parsing: 'aaabcde'"));
});
});
suite('times', function() {
test('prefer longest branch in .times() too', function() {
var parser = string('abc').then(string('def')).or(string('a')).times(3, 6);
assert.throws(function() { parser.parse('aabcde'); },
partialEquals("Parse Error: expected 'def' at character 4, got '...de'\n parsing: 'aabcde'"));
assert.throws(function() { parser.parse('aaaaabcde'); },
partialEquals("Parse Error: expected 'def' at character 7, got '...de'\n parsing: 'aaaaabcde'"));
});
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc