From 8759d4899e3853689a783258ed6c93ffa1436170 Mon Sep 17 00:00:00 2001 From: David Majda Date: Sun, 27 Jan 2013 20:12:44 +0100 Subject: [PATCH] Fix deduplication in |peg$cleanupExpected| The deduplication skipped over an expected string right after the one that was removed because the index variable was incorrectly incremented in that case. Based on a patch by @fresheneesz: https://github.com/dmajda/pegjs/pull/146 --- lib/compiler/passes/generate-javascript.js | 6 ++++-- lib/parser.js | 6 ++++-- spec/generated-parser.spec.js | 9 ++++++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/compiler/passes/generate-javascript.js b/lib/compiler/passes/generate-javascript.js index 7d48bda..88bd0ed 100644 --- a/lib/compiler/passes/generate-javascript.js +++ b/lib/compiler/passes/generate-javascript.js @@ -880,13 +880,15 @@ module.exports = function(ast, options) { ' }', '', ' function peg$cleanupExpected(expected) {', - ' var i;', + ' var i = 0;', '', ' expected.sort();', '', - ' for (i = 1; i < expected.length; i++) {', + ' while (i < expected.length) {', ' if (expected[i - 1] === expected[i]) {', ' expected.splice(i, 1);', + ' } else {', + ' i++;', ' }', ' }', ' }', diff --git a/lib/parser.js b/lib/parser.js index 5e98ee7..c43b6f5 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -450,13 +450,15 @@ module.exports = (function() { } function peg$cleanupExpected(expected) { - var i; + var i = 0; expected.sort(); - for (i = 1; i < expected.length; i++) { + while (i < expected.length) { if (expected[i - 1] === expected[i]) { expected.splice(i, 1); + } else { + i++; } } } diff --git a/spec/generated-parser.spec.js b/spec/generated-parser.spec.js index 3a45c75..56548a0 100644 --- a/spec/generated-parser.spec.js +++ b/spec/generated-parser.spec.js @@ -833,7 +833,14 @@ describe("generated parser", function() { }); it("removes duplicates from expected strings", function() { - var parser = PEG.buildParser('start = "a" / "a"', options); + /* + * There was a bug in the code that manifested only with three + * duplicates. This is why the following test uses three choices + * instead of seemingly sufficient two. + * + * See https://github.com/dmajda/pegjs/pull/146. + */ + var parser = PEG.buildParser('start = "a" / "a" / "a"', options); expect(parser).toFailToParse("b", { expected: ['"a"'] }); });