Error handling: Build error message out of |SyntaxError|'s constructor

It will be possible to create errors with user-supplied messages soon.
The |SyntaxError| class needs to be ready for that.

Implements part of #198.
redux
David Majda 11 years ago
parent 3fe6aba7e2
commit dd74ea4144

@ -685,63 +685,8 @@ module.exports = function(ast, options) {
' child.prototype = new ctor();',
' }',
'',
' function SyntaxError(expected, found, offset, line, column) {',
' function buildMessage(expected, found) {',
' function stringEscape(s) {',
' function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }',
'',
/*
* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
* literal except for the closing quote character, backslash, carriage
* return, line separator, paragraph separator, and line feed. Any character
* may appear in the form of an escape sequence.
*
* For portability, we also escape all control and non-ASCII characters.
* Note that "\0" and "\v" escape sequences are not used because JSHint does
* not like the first and IE the second.
*/
' return s',
' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash
' .replace(/"/g, \'\\\\"\')', // closing double quote
' .replace(/\\x08/g, \'\\\\b\')', // backspace
' .replace(/\\t/g, \'\\\\t\')', // horizontal tab
' .replace(/\\n/g, \'\\\\n\')', // line feed
' .replace(/\\f/g, \'\\\\f\')', // form feed
' .replace(/\\r/g, \'\\\\r\')', // carriage return
' .replace(/[\\x00-\\x07\\x0B\\x0E\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })',
' .replace(/[\\x10-\\x1F\\x80-\\xFF]/g, function(ch) { return \'\\\\x\' + hex(ch); })',
' .replace(/[\\u0180-\\u0FFF]/g, function(ch) { return \'\\\\u0\' + hex(ch); })',
' .replace(/[\\u1080-\\uFFFF]/g, function(ch) { return \'\\\\u\' + hex(ch); });',
' }',
'',
' var expectedDescs, expectedDesc, foundDesc, i;',
'',
' switch (expected.length) {',
' case 0:',
' expectedDesc = "end of input";',
' break;',
'',
' case 1:',
' expectedDesc = expected[0].description;',
' break;',
'',
' default:',
' expectedDescs = new Array(expected.length);',
'',
' for (i = 0; i < expected.length; i++) {',
' expectedDescs[i] = expected[i].description;',
' }',
'',
' expectedDesc = expectedDescs.slice(0, -1).join(", ")',
' + " or "',
' + expectedDescs[expected.length - 1];',
' }',
'',
' foundDesc = found ? "\\"" + stringEscape(found) + "\\"" : "end of input";',
'',
' return "Expected " + expectedDesc + " but " + foundDesc + " found.";',
' }',
'',
' function SyntaxError(message, expected, found, offset, line, column) {',
' this.message = message;',
' this.expected = expected;',
' this.found = found;',
' this.offset = offset;',
@ -749,7 +694,6 @@ module.exports = function(ast, options) {
' this.column = column;',
'',
' this.name = "SyntaxError";',
' this.message = buildMessage(expected, found);',
' }',
'',
' peg$subclass(SyntaxError, Error);',
@ -932,6 +876,62 @@ module.exports = function(ast, options) {
' }',
' }',
'',
' function buildMessage(expected, found) {',
' function stringEscape(s) {',
' function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }',
'',
/*
* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
* literal except for the closing quote character, backslash, carriage
* return, line separator, paragraph separator, and line feed. Any character
* may appear in the form of an escape sequence.
*
* For portability, we also escape all control and non-ASCII characters.
* Note that "\0" and "\v" escape sequences are not used because JSHint does
* not like the first and IE the second.
*/
' return s',
' .replace(/\\\\/g, \'\\\\\\\\\')', // backslash
' .replace(/"/g, \'\\\\"\')', // closing double quote
' .replace(/\\x08/g, \'\\\\b\')', // backspace
' .replace(/\\t/g, \'\\\\t\')', // horizontal tab
' .replace(/\\n/g, \'\\\\n\')', // line feed
' .replace(/\\f/g, \'\\\\f\')', // form feed
' .replace(/\\r/g, \'\\\\r\')', // carriage return
' .replace(/[\\x00-\\x07\\x0B\\x0E\\x0F]/g, function(ch) { return \'\\\\x0\' + hex(ch); })',
' .replace(/[\\x10-\\x1F\\x80-\\xFF]/g, function(ch) { return \'\\\\x\' + hex(ch); })',
' .replace(/[\\u0180-\\u0FFF]/g, function(ch) { return \'\\\\u0\' + hex(ch); })',
' .replace(/[\\u1080-\\uFFFF]/g, function(ch) { return \'\\\\u\' + hex(ch); });',
' }',
'',
' var expectedDescs, expectedDesc, foundDesc, i;',
'',
' switch (expected.length) {',
' case 0:',
' expectedDesc = "end of input";',
' break;',
'',
' case 1:',
' expectedDesc = expected[0].description;',
' break;',
'',
' default:',
' expectedDescs = new Array(expected.length);',
'',
' for (i = 0; i < expected.length; i++) {',
' expectedDescs[i] = expected[i].description;',
' }',
'',
' expectedDesc = expectedDescs.slice(0, -1).join(", ")',
' + " or "',
' + expectedDescs[expected.length - 1];',
' }',
'',
' foundDesc = found ? "\\"" + stringEscape(found) + "\\"" : "end of input";',
'',
' return "Expected " + expectedDesc + " but " + foundDesc + " found.";',
' }',
'',
' var pos = Math.max(peg$currPos, peg$maxFailPos),',
' posDetails = peg$computePosDetails(pos),',
' found = pos < input.length ? input.charAt(pos) : null;',
@ -939,6 +939,7 @@ module.exports = function(ast, options) {
' cleanupExpected(peg$maxFailExpected);',
'',
' return new SyntaxError(',
' buildMessage(peg$maxFailExpected, found),',
' peg$maxFailExpected,',
' found,',
' pos,',

@ -11,53 +11,8 @@ module.exports = (function() {
child.prototype = new ctor();
}
function SyntaxError(expected, found, offset, line, column) {
function buildMessage(expected, found) {
function stringEscape(s) {
function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
return s
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\x08/g, '\\b')
.replace(/\t/g, '\\t')
.replace(/\n/g, '\\n')
.replace(/\f/g, '\\f')
.replace(/\r/g, '\\r')
.replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
.replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
.replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
.replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
}
var expectedDescs, expectedDesc, foundDesc, i;
switch (expected.length) {
case 0:
expectedDesc = "end of input";
break;
case 1:
expectedDesc = expected[0].description;
break;
default:
expectedDescs = new Array(expected.length);
for (i = 0; i < expected.length; i++) {
expectedDescs[i] = expected[i].description;
}
expectedDesc = expectedDescs.slice(0, -1).join(", ")
+ " or "
+ expectedDescs[expected.length - 1];
}
foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
return "Expected " + expectedDesc + " but " + foundDesc + " found.";
}
function SyntaxError(message, expected, found, offset, line, column) {
this.message = message;
this.expected = expected;
this.found = found;
this.offset = offset;
@ -65,7 +20,6 @@ module.exports = (function() {
this.column = column;
this.name = "SyntaxError";
this.message = buildMessage(expected, found);
}
peg$subclass(SyntaxError, Error);
@ -492,6 +446,52 @@ module.exports = (function() {
}
}
function buildMessage(expected, found) {
function stringEscape(s) {
function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
return s
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\x08/g, '\\b')
.replace(/\t/g, '\\t')
.replace(/\n/g, '\\n')
.replace(/\f/g, '\\f')
.replace(/\r/g, '\\r')
.replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
.replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
.replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
.replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
}
var expectedDescs, expectedDesc, foundDesc, i;
switch (expected.length) {
case 0:
expectedDesc = "end of input";
break;
case 1:
expectedDesc = expected[0].description;
break;
default:
expectedDescs = new Array(expected.length);
for (i = 0; i < expected.length; i++) {
expectedDescs[i] = expected[i].description;
}
expectedDesc = expectedDescs.slice(0, -1).join(", ")
+ " or "
+ expectedDescs[expected.length - 1];
}
foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
return "Expected " + expectedDesc + " but " + foundDesc + " found.";
}
var pos = Math.max(peg$currPos, peg$maxFailPos),
posDetails = peg$computePosDetails(pos),
found = pos < input.length ? input.charAt(pos) : null;
@ -499,6 +499,7 @@ module.exports = (function() {
cleanupExpected(peg$maxFailExpected);
return new SyntaxError(
buildMessage(peg$maxFailExpected, found),
peg$maxFailExpected,
found,
pos,

Loading…
Cancel
Save