From 2d38c5cab3e4b63654b9947422ef67728a011850 Mon Sep 17 00:00:00 2001 From: David Majda Date: Sun, 22 Aug 2010 20:01:16 +0200 Subject: [PATCH] Handle non-unique expected values of match failuers differently Before this commit, uniqueness was checked when addding the failure. Now we make the entiries unique when generating the error report, saving a little time when the parsing is successful. This does not increase the benchmark numbers too much though. Results of benchmark with 100 runs on V8: Before: 37.25 kB/s After: 37.41 kB/s Speedup: 0.241 % Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3 --- src/emitter.js | 39 ++++++++++++++++----------------------- src/parser.js | 38 ++++++++++++++++---------------------- src/utils.js | 4 ---- 3 files changed, 32 insertions(+), 49 deletions(-) diff --git a/src/emitter.js b/src/emitter.js index 4ebd8b2..8cc9e1c 100644 --- a/src/emitter.js +++ b/src/emitter.js @@ -137,21 +137,6 @@ PEG.compiler.emitter = function(ast) { " + '\"';", " }", " ", - /* This needs to be in sync with |contains| in utils.js. */ - " function contains(array, value) {", - " /*", - " * Stupid IE does not have Array.prototype.indexOf, otherwise this", - " * function would be a one-liner.", - " */", - " var length = array.length;", - " for (var i = 0; i < length; i++) {", - " if (array[i] === value) {", - " return true;", - " }", - " }", - " return false;", - " }", - " ", " function matchFailed(failure) {", " if (pos < rightmostMatchFailuresPos) {", " return;", @@ -162,25 +147,33 @@ PEG.compiler.emitter = function(ast) { " rightmostMatchFailuresExpected = [];", " }", " ", - " if (!contains(rightmostMatchFailuresExpected, failure)) {", - " rightmostMatchFailuresExpected.push(failure);", - " }", + " rightmostMatchFailuresExpected.push(failure);", " }", " ", " ${parseFunctionDefinitions}", " ", " function buildErrorMessage() {", " function buildExpected(failuresExpected) {", - " switch (failuresExpected.length) {", + " failuresExpected.sort();", + " ", + " var lastFailure = null;", + " var failuresExpectedUnique = [];", + " for (var i = 0; i < failuresExpected.length; i++) {", + " if (failuresExpected[i] !== lastFailure) {", + " failuresExpectedUnique.push(failuresExpected[i]);", + " lastFailure = failuresExpected[i];", + " }", + " }", + " ", + " switch (failuresExpectedUnique.length) {", " case 0:", " return 'end of input';", " case 1:", - " return failuresExpected[0];", + " return failuresExpectedUnique[0];", " default:", - " failuresExpected.sort();", - " return failuresExpected.slice(0, failuresExpected.length - 1).join(', ')", + " return failuresExpectedUnique.slice(0, failuresExpectedUnique.length - 1).join(', ')", " + ' or '", - " + failuresExpected[failuresExpected.length - 1];", + " + failuresExpectedUnique[failuresExpectedUnique.length - 1];", " }", " }", " ", diff --git a/src/parser.js b/src/parser.js index 7caf27d..94002a1 100644 --- a/src/parser.js +++ b/src/parser.js @@ -32,20 +32,6 @@ PEG.parser = (function(){ + '"'; } - function contains(array, value) { - /* - * Stupid IE does not have Array.prototype.indexOf, otherwise this - * function would be a one-liner. - */ - var length = array.length; - for (var i = 0; i < length; i++) { - if (array[i] === value) { - return true; - } - } - return false; - } - function matchFailed(failure) { if (pos < rightmostMatchFailuresPos) { return; @@ -56,9 +42,7 @@ PEG.parser = (function(){ rightmostMatchFailuresExpected = []; } - if (!contains(rightmostMatchFailuresExpected, failure)) { - rightmostMatchFailuresExpected.push(failure); - } + rightmostMatchFailuresExpected.push(failure); } function parse_grammar() { @@ -3443,16 +3427,26 @@ PEG.parser = (function(){ function buildErrorMessage() { function buildExpected(failuresExpected) { - switch (failuresExpected.length) { + failuresExpected.sort(); + + var lastFailure = null; + var failuresExpectedUnique = []; + for (var i = 0; i < failuresExpected.length; i++) { + if (failuresExpected[i] !== lastFailure) { + failuresExpectedUnique.push(failuresExpected[i]); + lastFailure = failuresExpected[i]; + } + } + + switch (failuresExpectedUnique.length) { case 0: return 'end of input'; case 1: - return failuresExpected[0]; + return failuresExpectedUnique[0]; default: - failuresExpected.sort(); - return failuresExpected.slice(0, failuresExpected.length - 1).join(', ') + return failuresExpectedUnique.slice(0, failuresExpectedUnique.length - 1).join(', ') + ' or ' - + failuresExpected[failuresExpected.length - 1]; + + failuresExpectedUnique[failuresExpectedUnique.length - 1]; } } diff --git a/src/utils.js b/src/utils.js index d6bf8ba..7afdf88 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,7 +1,3 @@ -/* - * The code needs to be in sync with the code template in the compilation - * function for "action" nodes. - */ function contains(array, value) { /* * Stupid IE does not have Array.prototype.indexOf, otherwise this function