|
|
|
@ -344,38 +344,19 @@ PEG.compiler.emitter = function(ast) {
|
|
|
|
|
' #block definition',
|
|
|
|
|
' ',
|
|
|
|
|
' #end',
|
|
|
|
|
' function buildErrorMessage() {',
|
|
|
|
|
' function buildExpected(failuresExpected) {',
|
|
|
|
|
' 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 failuresExpectedUnique[0];',
|
|
|
|
|
' default:',
|
|
|
|
|
' return failuresExpectedUnique.slice(0, failuresExpectedUnique.length - 1).join(", ")',
|
|
|
|
|
' + " or "',
|
|
|
|
|
' + failuresExpectedUnique[failuresExpectedUnique.length - 1];',
|
|
|
|
|
' ',
|
|
|
|
|
' function cleanupExpected(expected) {',
|
|
|
|
|
' expected.sort();',
|
|
|
|
|
' ',
|
|
|
|
|
' var lastExpected = null;',
|
|
|
|
|
' var cleanExpected = [];',
|
|
|
|
|
' for (var i = 0; i < expected.length; i++) {',
|
|
|
|
|
' if (expected[i] !== lastExpected) {',
|
|
|
|
|
' cleanExpected.push(expected[i]);',
|
|
|
|
|
' lastExpected = expected[i];',
|
|
|
|
|
' }',
|
|
|
|
|
' }',
|
|
|
|
|
' ',
|
|
|
|
|
' var expected = buildExpected(rightmostFailuresExpected);',
|
|
|
|
|
' var actualPos = Math.max(pos, rightmostFailuresPos);',
|
|
|
|
|
' var actual = actualPos < input.length',
|
|
|
|
|
' ? quote(input.charAt(actualPos))',
|
|
|
|
|
' : "end of input";',
|
|
|
|
|
' ',
|
|
|
|
|
' return "Expected " + expected + " but " + actual + " found.";',
|
|
|
|
|
' return cleanExpected;',
|
|
|
|
|
' }',
|
|
|
|
|
' ',
|
|
|
|
|
' function computeErrorPosition() {',
|
|
|
|
@ -440,10 +421,14 @@ PEG.compiler.emitter = function(ast) {
|
|
|
|
|
' * handle these states.',
|
|
|
|
|
' */',
|
|
|
|
|
' if (result === null || pos !== input.length) {',
|
|
|
|
|
' var offset = Math.max(pos, rightmostFailuresPos);',
|
|
|
|
|
' var found = offset < input.length ? input.charAt(offset) : null;',
|
|
|
|
|
' var errorPosition = computeErrorPosition();',
|
|
|
|
|
' ',
|
|
|
|
|
' throw new this.SyntaxError(',
|
|
|
|
|
' buildErrorMessage(),',
|
|
|
|
|
' Math.max(pos, rightmostFailuresPos),',
|
|
|
|
|
' cleanupExpected(rightmostFailuresExpected),',
|
|
|
|
|
' found,',
|
|
|
|
|
' offset,',
|
|
|
|
|
' errorPosition.line,',
|
|
|
|
|
' errorPosition.column',
|
|
|
|
|
' );',
|
|
|
|
@ -458,9 +443,30 @@ PEG.compiler.emitter = function(ast) {
|
|
|
|
|
' ',
|
|
|
|
|
' /* Thrown when a parser encounters a syntax error. */',
|
|
|
|
|
' ',
|
|
|
|
|
' result.SyntaxError = function(message, offset, line, column) {',
|
|
|
|
|
' result.SyntaxError = function(expected, found, offset, line, column) {',
|
|
|
|
|
' function buildMessage(expected, found) {',
|
|
|
|
|
' var expectedHumanized, foundHumanized;',
|
|
|
|
|
' ',
|
|
|
|
|
' switch (expected.length) {',
|
|
|
|
|
' case 0:',
|
|
|
|
|
' expectedHumanized = "end of input";',
|
|
|
|
|
' break;',
|
|
|
|
|
' case 1:',
|
|
|
|
|
' expectedHumanized = expected[0];',
|
|
|
|
|
' break;',
|
|
|
|
|
' default:',
|
|
|
|
|
' expectedHumanized = expected.slice(0, expected.length - 1).join(", ")',
|
|
|
|
|
' + " or "',
|
|
|
|
|
' + expected[expected.length - 1];',
|
|
|
|
|
' }',
|
|
|
|
|
' ',
|
|
|
|
|
' foundHumanized = found ? quote(found) : "end of input";',
|
|
|
|
|
' ',
|
|
|
|
|
' return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";',
|
|
|
|
|
' }',
|
|
|
|
|
' ',
|
|
|
|
|
' this.name = "SyntaxError";',
|
|
|
|
|
' this.message = message;',
|
|
|
|
|
' this.message = buildMessage(expected, found);',
|
|
|
|
|
' this.offset = offset;',
|
|
|
|
|
' this.line = line;',
|
|
|
|
|
' this.column = column;',
|
|
|
|
|