From 8acea015251917a46eec84185225929bfc888ca8 Mon Sep 17 00:00:00 2001 From: David Majda Date: Sat, 1 Oct 2011 18:46:57 +0200 Subject: [PATCH] Fix reported error position when part of the input is not consumed Closes GH-48. --- src/emitter.js | 2 +- test/compiler-test.js | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/emitter.js b/src/emitter.js index 5b4eaea..1861576 100644 --- a/src/emitter.js +++ b/src/emitter.js @@ -376,7 +376,7 @@ PEG.compiler.emitter = function(ast) { ' var column = 1;', ' var seenCR = false;', ' ', - ' for (var i = 0; i < rightmostFailuresPos; i++) {', + ' for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {', ' var ch = input.charAt(i);', ' if (ch === "\\n") {', ' if (!seenCR) { line++; }', diff --git a/test/compiler-test.js b/test/compiler-test.js index 80693a3..2e18428 100644 --- a/test/compiler-test.js +++ b/test/compiler-test.js @@ -444,23 +444,30 @@ test("error messages", function() { }); test("error positions", function() { - var parser = PEG.buildParser([ + var simpleParser = PEG.buildParser('start = "a"'); + + /* Regular match failure */ + doesNotParseWithPos(simpleParser, "b", 1, 1); + + /* Trailing input */ + doesNotParseWithPos(simpleParser, "ab", 1, 2); + + var digitsParser = PEG.buildParser([ 'start = line (("\\r" / "\\n" / "\\u2028" / "\\u2029")+ line)*', 'line = digits (" "+ digits)*', 'digits = digits:[0-9]+ { return digits.join(""); }' ].join("\n")); - doesNotParseWithPos(parser, "a", 1, 1); - doesNotParseWithPos(parser, "1\n2\n\n3\n\n\n4 5 x", 7, 5); + doesNotParseWithPos(digitsParser, "1\n2\n\n3\n\n\n4 5 x", 7, 5); /* Non-Unix newlines */ - doesNotParseWithPos(parser, "1\rx", 2, 1); // Old Mac - doesNotParseWithPos(parser, "1\r\nx", 2, 1); // Windows - doesNotParseWithPos(parser, "1\n\rx", 3, 1); // mismatched + doesNotParseWithPos(digitsParser, "1\rx", 2, 1); // Old Mac + doesNotParseWithPos(digitsParser, "1\r\nx", 2, 1); // Windows + doesNotParseWithPos(digitsParser, "1\n\rx", 3, 1); // mismatched /* Strange newlines */ - doesNotParseWithPos(parser, "1\u2028x", 2, 1); // line separator - doesNotParseWithPos(parser, "1\u2029x", 2, 1); // paragraph separator + doesNotParseWithPos(digitsParser, "1\u2028x", 2, 1); // line separator + doesNotParseWithPos(digitsParser, "1\u2029x", 2, 1); // paragraph separator }); test("start rule", function() {