Add location information to |GrammarError|
This means all errors thrown by |PEG.buildParser| now have associated location information.
This commit is contained in:
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…
Reference in a new issue