diff --git a/lib/compiler/passes/generate-js.js b/lib/compiler/passes/generate-js.js index 301dc0f..3f9b5e3 100644 --- a/lib/compiler/passes/generate-js.js +++ b/lib/compiler/passes/generate-js.js @@ -781,6 +781,106 @@ function generateJS(ast, options) { '}', '', 'peg$subclass(peg$SyntaxError, Error);', + '', + 'peg$SyntaxError.buildMessage = function(expected, found) {', + ' var DESCRIBE_EXPECTATION_FNS = {', + ' literal: function(expectation) {', + ' return "\\\"" + literalEscape(expectation.text) + "\\\"";', + ' },', + '', + ' class: function(expectation) {', + ' var escapedParts = "",', + ' i;', + '', + ' for (i = 0; i < expectation.parts.length; i++) {', + ' escapedParts += expectation.parts[i] instanceof Array', + ' ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1])', + ' : classEscape(expectation.parts[i]);', + ' }', + '', + ' return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";', + ' },', + '', + ' any: function(expectation) {', + ' return "any character";', + ' },', + '', + ' end: function(expectation) {', + ' return "end of input";', + ' },', + '', + ' other: function(expectation) {', + ' return expectation.description;', + ' }', + ' };', + '', + ' function hex(ch) {', + ' return ch.charCodeAt(0).toString(16).toUpperCase();', + ' }', + '', + ' function literalEscape(s) {', + ' return s', + ' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash + ' .replace(/"/g, \'\\\\"\')', // closing double quote + ' .replace(/\\0/g, \'\\\\0\')', // null + ' .replace(/\\t/g, \'\\\\t\')', // horizontal tab + ' .replace(/\\n/g, \'\\\\n\')', // line feed + ' .replace(/\\r/g, \'\\\\r\')', // carriage return + ' .replace(/[\\x00-\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })', + ' .replace(/[\\x10-\\x1F\\x7F-\\x9F]/g, function(ch) { return \'\\\\x\' + hex(ch); });', + ' }', + '', + ' function classEscape(s) {', + ' return s', + ' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash + ' .replace(/\\]/g, \'\\\\]\')', // closing bracket + ' .replace(/\\^/g, \'\\\\^\')', // caret + ' .replace(/-/g, \'\\\\-\')', // dash + ' .replace(/\\0/g, \'\\\\0\')', // null + ' .replace(/\\t/g, \'\\\\t\')', // horizontal tab + ' .replace(/\\n/g, \'\\\\n\')', // line feed + ' .replace(/\\r/g, \'\\\\r\')', // carriage return + ' .replace(/[\\x00-\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })', + ' .replace(/[\\x10-\\x1F\\x7F-\\x9F]/g, function(ch) { return \'\\\\x\' + hex(ch); });', + ' }', + '', + ' function describeExpectation(expectation) {', + ' return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);', + ' }', + '', + ' function describeExpected(expected) {', + ' var descriptions = new Array(expected.length),', + ' i, j;', + '', + ' for (i = 0; i < expected.length; i++) {', + ' descriptions[i] = describeExpectation(expected[i]);', + ' }', + '', + ' descriptions.sort();', + '', + ' if (descriptions.length > 0) {', + ' for (i = 1, j = 1; i < descriptions.length; i++) {', + ' if (descriptions[i - 1] !== descriptions[i]) {', + ' descriptions[j] = descriptions[i];', + ' j++;', + ' }', + ' }', + ' descriptions.length = j;', + ' }', + '', + ' return descriptions.length > 1', + ' ? descriptions.slice(0, -1).join(", ")', + ' + " or "', + ' + descriptions[descriptions.length - 1]', + ' : descriptions[0];', + ' }', + '', + ' function describeFound(found) {', + ' return found ? "\\"" + literalEscape(found) + "\\"" : "end of input";', + ' }', + '', + ' return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";', + '};', '' ].join('\n')); @@ -1045,108 +1145,8 @@ function generateJS(ast, options) { ' }', '', ' function peg$buildException(message, expected, found, location) {', - ' function buildMessage(expected, found) {', - ' var DESCRIBE_EXPECTATION_FNS = {', - ' literal: function(expectation) {', - ' return "\\\"" + literalEscape(expectation.text) + "\\\"";', - ' },', - '', - ' class: function(expectation) {', - ' var escapedParts = "",', - ' i;', - '', - ' for (i = 0; i < expectation.parts.length; i++) {', - ' escapedParts += expectation.parts[i] instanceof Array', - ' ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1])', - ' : classEscape(expectation.parts[i]);', - ' }', - '', - ' return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";', - ' },', - '', - ' any: function(expectation) {', - ' return "any character";', - ' },', - '', - ' end: function(expectation) {', - ' return "end of input";', - ' },', - '', - ' other: function(expectation) {', - ' return expectation.description;', - ' }', - ' };', - '', - ' function hex(ch) {', - ' return ch.charCodeAt(0).toString(16).toUpperCase();', - ' }', - '', - ' function literalEscape(s) {', - ' return s', - ' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash - ' .replace(/"/g, \'\\\\"\')', // closing double quote - ' .replace(/\\0/g, \'\\\\0\')', // null - ' .replace(/\\t/g, \'\\\\t\')', // horizontal tab - ' .replace(/\\n/g, \'\\\\n\')', // line feed - ' .replace(/\\r/g, \'\\\\r\')', // carriage return - ' .replace(/[\\x00-\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })', - ' .replace(/[\\x10-\\x1F\\x7F-\\x9F]/g, function(ch) { return \'\\\\x\' + hex(ch); });', - ' }', - '', - ' function classEscape(s) {', - ' return s', - ' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash - ' .replace(/\\]/g, \'\\\\]\')', // closing bracket - ' .replace(/\\^/g, \'\\\\^\')', // caret - ' .replace(/-/g, \'\\\\-\')', // dash - ' .replace(/\\0/g, \'\\\\0\')', // null - ' .replace(/\\t/g, \'\\\\t\')', // horizontal tab - ' .replace(/\\n/g, \'\\\\n\')', // line feed - ' .replace(/\\r/g, \'\\\\r\')', // carriage return - ' .replace(/[\\x00-\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })', - ' .replace(/[\\x10-\\x1F\\x7F-\\x9F]/g, function(ch) { return \'\\\\x\' + hex(ch); });', - ' }', - '', - ' function describeExpectation(expectation) {', - ' return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);', - ' }', - '', - ' function describeExpected(expected) {', - ' var descriptions = new Array(expected.length),', - ' i, j;', - '', - ' for (i = 0; i < expected.length; i++) {', - ' descriptions[i] = describeExpectation(expected[i]);', - ' }', - '', - ' descriptions.sort();', - '', - ' if (descriptions.length > 0) {', - ' for (i = 1, j = 1; i < descriptions.length; i++) {', - ' if (descriptions[i - 1] !== descriptions[i]) {', - ' descriptions[j] = descriptions[i];', - ' j++;', - ' }', - ' }', - ' descriptions.length = j;', - ' }', - '', - ' return descriptions.length > 1', - ' ? descriptions.slice(0, -1).join(", ")', - ' + " or "', - ' + descriptions[descriptions.length - 1]', - ' : descriptions[0];', - ' }', - '', - ' function describeFound(found) {', - ' return found ? "\\"" + literalEscape(found) + "\\"" : "end of input";', - ' }', - '', - ' return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";', - ' }', - '', ' return new peg$SyntaxError(', - ' message !== null ? message : buildMessage(expected, found),', + ' message !== null ? message : peg$SyntaxError.buildMessage(expected, found),', ' expected,', ' found,', ' location',