Revert "Remove info about found string from syntax errors"
This reverts commit 25ab98027d
.
Part of work on #428.
This commit is contained in:
parent
4fe682794d
commit
6b60896216
|
@ -155,8 +155,8 @@ Using the Parser
|
|||
Using the generated parser is simple — just call its `parse` method and pass an
|
||||
input string as a parameter. The method will return a parse result (the exact
|
||||
value depends on the grammar used to generate the parser) or throw an exception
|
||||
if the input is invalid. The exception will contain `location`, `expected` and
|
||||
`message` properties with more details about the error.
|
||||
if the input is invalid. The exception will contain `location`, `expected`,
|
||||
`found`, and `message` properties with more details about the error.
|
||||
|
||||
```javascript
|
||||
parser.parse("abba"); // returns ["a", "b", "b", "a"]
|
||||
|
|
|
@ -768,9 +768,10 @@ function generateJS(ast, options) {
|
|||
' child.prototype = new ctor();',
|
||||
'}',
|
||||
'',
|
||||
'function peg$SyntaxError(message, expected, location) {',
|
||||
'function peg$SyntaxError(message, expected, found, location) {',
|
||||
' this.message = message;',
|
||||
' this.expected = expected;',
|
||||
' this.found = found;',
|
||||
' this.location = location;',
|
||||
' this.name = "SyntaxError";',
|
||||
'',
|
||||
|
@ -965,6 +966,7 @@ function generateJS(ast, options) {
|
|||
' throw peg$buildException(',
|
||||
' null,',
|
||||
' [{ type: "other", description: description }],',
|
||||
' input.substring(peg$savedPos, peg$currPos),',
|
||||
' location',
|
||||
' );',
|
||||
' }',
|
||||
|
@ -972,7 +974,12 @@ function generateJS(ast, options) {
|
|||
' function error(message, location) {',
|
||||
' location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)',
|
||||
'',
|
||||
' throw peg$buildException(message, null, location);',
|
||||
' throw peg$buildException(',
|
||||
' message,',
|
||||
' null,',
|
||||
' input.substring(peg$savedPos, peg$currPos),',
|
||||
' location',
|
||||
' );',
|
||||
' }',
|
||||
'',
|
||||
' function peg$computePosDetails(pos) {',
|
||||
|
@ -1037,7 +1044,7 @@ function generateJS(ast, options) {
|
|||
' peg$maxFailExpected.push(expected);',
|
||||
' }',
|
||||
'',
|
||||
' function peg$buildException(message, expected, location) {',
|
||||
' function peg$buildException(message, expected, found, location) {',
|
||||
' function cleanupExpected(expected) {',
|
||||
' var i, j;',
|
||||
'',
|
||||
|
@ -1067,9 +1074,36 @@ function generateJS(ast, options) {
|
|||
' }',
|
||||
' }',
|
||||
'',
|
||||
' function buildMessage(expected) {',
|
||||
' 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(/[\\u0100-\\u0FFF]/g, function(ch) { return \'\\\\u0\' + hex(ch); })',
|
||||
' .replace(/[\\u1000-\\uFFFF]/g, function(ch) { return \'\\\\u\' + hex(ch); });',
|
||||
' }',
|
||||
'',
|
||||
' var expectedDescs = new Array(expected.length),',
|
||||
' expectedDesc, i;',
|
||||
' expectedDesc, foundDesc, i;',
|
||||
'',
|
||||
' for (i = 0; i < expected.length; i++) {',
|
||||
' expectedDescs[i] = expected[i].description;',
|
||||
|
@ -1081,7 +1115,9 @@ function generateJS(ast, options) {
|
|||
' + expectedDescs[expected.length - 1]',
|
||||
' : expectedDescs[0];',
|
||||
'',
|
||||
' return "Expected " + expectedDesc + ".";',
|
||||
' foundDesc = found ? "\\"" + stringEscape(found) + "\\"" : "end of input";',
|
||||
'',
|
||||
' return "Expected " + expectedDesc + " but " + foundDesc + " found.";',
|
||||
' }',
|
||||
'',
|
||||
' if (expected !== null) {',
|
||||
|
@ -1089,8 +1125,9 @@ function generateJS(ast, options) {
|
|||
' }',
|
||||
'',
|
||||
' return new peg$SyntaxError(',
|
||||
' message !== null ? message : buildMessage(expected),',
|
||||
' message !== null ? message : buildMessage(expected, found),',
|
||||
' expected,',
|
||||
' found,',
|
||||
' location',
|
||||
' );',
|
||||
' }',
|
||||
|
@ -1130,7 +1167,10 @@ function generateJS(ast, options) {
|
|||
' throw peg$buildException(',
|
||||
' null,',
|
||||
' peg$maxFailExpected,',
|
||||
' peg$computeLocation(peg$maxFailPos, peg$maxFailPos)',
|
||||
' peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,',
|
||||
' peg$maxFailPos < input.length',
|
||||
' ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)',
|
||||
' : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)',
|
||||
' );',
|
||||
' }',
|
||||
'}'
|
||||
|
|
|
@ -21,9 +21,10 @@
|
|||
child.prototype = new ctor();
|
||||
}
|
||||
|
||||
function peg$SyntaxError(message, expected, location) {
|
||||
function peg$SyntaxError(message, expected, found, location) {
|
||||
this.message = message;
|
||||
this.expected = expected;
|
||||
this.found = found;
|
||||
this.location = location;
|
||||
this.name = "SyntaxError";
|
||||
|
||||
|
@ -427,6 +428,7 @@
|
|||
throw peg$buildException(
|
||||
null,
|
||||
[{ type: "other", description: description }],
|
||||
input.substring(peg$savedPos, peg$currPos),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
@ -434,7 +436,12 @@
|
|||
function error(message, location) {
|
||||
location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)
|
||||
|
||||
throw peg$buildException(message, null, location);
|
||||
throw peg$buildException(
|
||||
message,
|
||||
null,
|
||||
input.substring(peg$savedPos, peg$currPos),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
function peg$computePosDetails(pos) {
|
||||
|
@ -499,7 +506,7 @@
|
|||
peg$maxFailExpected.push(expected);
|
||||
}
|
||||
|
||||
function peg$buildException(message, expected, location) {
|
||||
function peg$buildException(message, expected, found, location) {
|
||||
function cleanupExpected(expected) {
|
||||
var i, j;
|
||||
|
||||
|
@ -524,9 +531,26 @@
|
|||
}
|
||||
}
|
||||
|
||||
function buildMessage(expected) {
|
||||
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(/[\u0100-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
|
||||
.replace(/[\u1000-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
|
||||
}
|
||||
|
||||
var expectedDescs = new Array(expected.length),
|
||||
expectedDesc, i;
|
||||
expectedDesc, foundDesc, i;
|
||||
|
||||
for (i = 0; i < expected.length; i++) {
|
||||
expectedDescs[i] = expected[i].description;
|
||||
|
@ -538,7 +562,9 @@
|
|||
+ expectedDescs[expected.length - 1]
|
||||
: expectedDescs[0];
|
||||
|
||||
return "Expected " + expectedDesc + ".";
|
||||
foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
|
||||
|
||||
return "Expected " + expectedDesc + " but " + foundDesc + " found.";
|
||||
}
|
||||
|
||||
if (expected !== null) {
|
||||
|
@ -546,8 +572,9 @@
|
|||
}
|
||||
|
||||
return new peg$SyntaxError(
|
||||
message !== null ? message : buildMessage(expected),
|
||||
message !== null ? message : buildMessage(expected, found),
|
||||
expected,
|
||||
found,
|
||||
location
|
||||
);
|
||||
}
|
||||
|
@ -4948,7 +4975,10 @@
|
|||
throw peg$buildException(
|
||||
null,
|
||||
peg$maxFailExpected,
|
||||
peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
|
||||
peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
|
||||
peg$maxFailPos < input.length
|
||||
? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
|
||||
: peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1219,8 +1219,9 @@ describe("generated parser behavior", function() {
|
|||
);
|
||||
|
||||
expect(parser).toFailToParse("a", {
|
||||
message: 'Expected a.',
|
||||
message: 'Expected a but "a" found.',
|
||||
expected: [{ type: "other", description: "a" }],
|
||||
found: "a",
|
||||
location: {
|
||||
start: { offset: 0, line: 1, column: 1 },
|
||||
end: { offset: 1, line: 1, column: 2 }
|
||||
|
@ -1239,8 +1240,9 @@ describe("generated parser behavior", function() {
|
|||
].join("\n"), options);
|
||||
|
||||
expect(parser).toFailToParse("a", {
|
||||
message: 'Expected a.',
|
||||
message: 'Expected a but "a" found.',
|
||||
expected: [{ type: "other", description: "a" }],
|
||||
found: "a",
|
||||
location: {
|
||||
start: { offset: 1, line: 1, column: 2 },
|
||||
end: { offset: 2, line: 1, column: 3 }
|
||||
|
@ -1258,6 +1260,7 @@ describe("generated parser behavior", function() {
|
|||
|
||||
expect(parser).toFailToParse("a", {
|
||||
message: "a",
|
||||
found: "a",
|
||||
expected: null,
|
||||
location: {
|
||||
start: { offset: 0, line: 1, column: 1 },
|
||||
|
@ -1279,6 +1282,7 @@ describe("generated parser behavior", function() {
|
|||
expect(parser).toFailToParse("a", {
|
||||
message: "a",
|
||||
expected: null,
|
||||
found: "a",
|
||||
location: {
|
||||
start: { offset: 1, line: 1, column: 2 },
|
||||
end: { offset: 2, line: 1, column: 3 }
|
||||
|
@ -1395,12 +1399,26 @@ describe("generated parser behavior", function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe("found string reporting", function() {
|
||||
it("reports found string correctly at the end of input", function() {
|
||||
var parser = peg.generate('start = "a"', options);
|
||||
|
||||
expect(parser).toFailToParse("", { found: null });
|
||||
});
|
||||
|
||||
it("reports found string correctly in the middle of input", function() {
|
||||
var parser = peg.generate('start = "a"', options);
|
||||
|
||||
expect(parser).toFailToParse("b", { found: "b" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("message building", function() {
|
||||
it("builds message correctly with no alternative", function() {
|
||||
var parser = peg.generate('start = "a"', options);
|
||||
|
||||
expect(parser).toFailToParse("ab", {
|
||||
message: 'Expected end of input.'
|
||||
message: 'Expected end of input but "b" found.'
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1408,7 +1426,7 @@ describe("generated parser behavior", function() {
|
|||
var parser = peg.generate('start = "a"', options);
|
||||
|
||||
expect(parser).toFailToParse("b", {
|
||||
message: 'Expected "a".'
|
||||
message: 'Expected "a" but "b" found.'
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1416,19 +1434,46 @@ describe("generated parser behavior", function() {
|
|||
var parser = peg.generate('start = "a" / "b" / "c"', options);
|
||||
|
||||
expect(parser).toFailToParse("d", {
|
||||
message: 'Expected "a", "b" or "c".'
|
||||
message: 'Expected "a", "b" or "c" but "d" found.'
|
||||
});
|
||||
});
|
||||
|
||||
it("builds message correctly at the end of input", function() {
|
||||
var parser = peg.generate('start = "a"', options);
|
||||
|
||||
expect(parser).toFailToParse("", {
|
||||
message: 'Expected "a" but end of input found.'
|
||||
});
|
||||
});
|
||||
|
||||
it("builds message correctly in the middle of input", function() {
|
||||
var parser = peg.generate('start = "a"', options);
|
||||
|
||||
expect(parser).toFailToParse("b", {
|
||||
message: 'Expected "a" but "b" found.'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("position reporting", function() {
|
||||
it("reports position correctly with no trailing input", function() {
|
||||
it("reports position correctly at the end of input", function() {
|
||||
var parser = peg.generate('start = "a"', options);
|
||||
|
||||
expect(parser).toFailToParse("", {
|
||||
location: {
|
||||
start: { offset: 0, line: 1, column: 1 },
|
||||
end: { offset: 0, line: 1, column: 1 }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("reports position correctly in the middle of input", function() {
|
||||
var parser = peg.generate('start = "a"', options);
|
||||
|
||||
expect(parser).toFailToParse("b", {
|
||||
location: {
|
||||
start: { offset: 0, line: 1, column: 1 },
|
||||
end: { offset: 0, line: 1, column: 1 }
|
||||
end: { offset: 1, line: 1, column: 2 }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1439,7 +1484,7 @@ describe("generated parser behavior", function() {
|
|||
expect(parser).toFailToParse("aa", {
|
||||
location: {
|
||||
start: { offset: 1, line: 1, column: 2 },
|
||||
end: { offset: 1, line: 1, column: 2 }
|
||||
end: { offset: 2, line: 1, column: 3 }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1455,7 +1500,7 @@ describe("generated parser behavior", function() {
|
|||
expect(parser).toFailToParse("1\n2\n\n3\n\n\n4 5 x", {
|
||||
location: {
|
||||
start: { offset: 13, line: 7, column: 5 },
|
||||
end: { offset: 13, line: 7, column: 5 }
|
||||
end: { offset: 14, line: 7, column: 6 }
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1463,13 +1508,13 @@ describe("generated parser behavior", function() {
|
|||
expect(parser).toFailToParse("1\nx", { // Old Mac
|
||||
location: {
|
||||
start: { offset: 2, line: 2, column: 1 },
|
||||
end: { offset: 2, line: 2, column: 1 }
|
||||
end: { offset: 3, line: 2, column: 2 }
|
||||
}
|
||||
});
|
||||
expect(parser).toFailToParse("1\r\nx", { // Windows
|
||||
location: {
|
||||
start: { offset: 3, line: 2, column: 1 },
|
||||
end: { offset: 3, line: 2, column: 1 }
|
||||
end: { offset: 4, line: 2, column: 2 }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue