Add location information to |GrammarError|

This means all errors thrown by |PEG.buildParser| now have associated
location information.
redux
David Majda 9 years ago
parent 89146915ce
commit eaca5f0acf

@ -10,13 +10,13 @@ function reportInfiniteLoops(ast) {
var check = visitor.build({ var check = visitor.build({
zero_or_more: function(node) { zero_or_more: function(node) {
if (asts.matchesEmpty(ast, node.expression)) { if (asts.matchesEmpty(ast, node.expression)) {
throw new GrammarError("Infinite loop detected."); throw new GrammarError("Infinite loop detected.", node.location);
} }
}, },
one_or_more: function(node) { one_or_more: function(node) {
if (asts.matchesEmpty(ast, node.expression)) { if (asts.matchesEmpty(ast, node.expression)) {
throw new GrammarError("Infinite loop detected."); throw new GrammarError("Infinite loop detected.", node.location);
} }
} }
}); });

@ -34,7 +34,8 @@ function reportLeftRecursion(ast) {
rule_ref: function(node, visitedRules) { rule_ref: function(node, visitedRules) {
if (arrays.contains(visitedRules, node.name)) { if (arrays.contains(visitedRules, node.name)) {
throw new GrammarError( throw new GrammarError(
"Left recursion detected for rule \"" + node.name + "\"." "Left recursion detected for rule \"" + node.name + "\".",
node.location
); );
} }

@ -8,7 +8,8 @@ function reportMissingRules(ast) {
rule_ref: function(node) { rule_ref: function(node) {
if (!asts.findRule(ast, node.name)) { if (!asts.findRule(ast, node.name)) {
throw new GrammarError( throw new GrammarError(
"Referenced rule \"" + node.name + "\" does not exist." "Referenced rule \"" + node.name + "\" does not exist.",
node.location
); );
} }
} }

@ -1,9 +1,10 @@
var classes = require("./utils/classes"); var classes = require("./utils/classes");
/* Thrown when the grammar contains an error. */ /* Thrown when the grammar contains an error. */
function GrammarError(message) { function GrammarError(message, location) {
this.name = "GrammarError"; this.name = "GrammarError";
this.message = message; this.message = message;
this.location = location;
} }
classes.subclass(GrammarError, Error); classes.subclass(GrammarError, Error);

@ -3,13 +3,21 @@ describe("compiler pass |reportLeftRecursion|", function() {
it("reports infinite loops for zero_or_more", function() { it("reports infinite loops for zero_or_more", function() {
expect(pass).toReportError('start = ("")*', { expect(pass).toReportError('start = ("")*', {
message: "Infinite loop detected." message: "Infinite loop detected.",
location: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 13, line: 1, column: 14 }
}
}); });
}); });
it("reports infinite loops for one_or_more", function() { it("reports infinite loops for one_or_more", function() {
expect(pass).toReportError('start = ("")+', { expect(pass).toReportError('start = ("")+', {
message: "Infinite loop detected." message: "Infinite loop detected.",
location: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 13, line: 1, column: 14 }
}
}); });
}); });

@ -3,7 +3,11 @@ describe("compiler pass |reportLeftRecursion|", function() {
it("reports direct left recursion", function() { it("reports direct left recursion", function() {
expect(pass).toReportError('start = start', { expect(pass).toReportError('start = start', {
message: 'Left recursion detected for rule \"start\".' message: 'Left recursion detected for rule \"start\".',
location: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 13, line: 1, column: 14 }
}
}); });
}); });
@ -12,7 +16,11 @@ describe("compiler pass |reportLeftRecursion|", function() {
'start = stop', 'start = stop',
'stop = start' 'stop = start'
].join("\n"), { ].join("\n"), {
message: 'Left recursion detected for rule \"start\".' message: 'Left recursion detected for rule \"start\".',
location: {
start: { offset: 21, line: 2, column: 9 },
end: { offset: 26, line: 2, column: 14 }
}
}); });
}); });

@ -3,7 +3,11 @@ describe("compiler pass |reportMissingRules|", function() {
it("reports missing rules", function() { it("reports missing rules", function() {
expect(pass).toReportError('start = missing', { expect(pass).toReportError('start = missing', {
message: 'Referenced rule "missing" does not exist.' message: 'Referenced rule "missing" does not exist.',
location: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 15, line: 1, column: 16 }
}
}); });
}); });
}); });

Loading…
Cancel
Save