Report left recursion and infinite loops only as "possible"
A semantic predicate can prevent the parser to actually enter infinite recursion or loop. This is undetectable at compile-time.
This commit is contained in:
parent
ebf5d969b2
commit
491106c347
|
@ -12,13 +12,13 @@ function reportInfiniteLoops(ast) {
|
||||||
var check = visitor.build({
|
var check = visitor.build({
|
||||||
zero_or_more: function(node) {
|
zero_or_more: function(node) {
|
||||||
if (!asts.alwaysConsumesOnSuccess(ast, node.expression)) {
|
if (!asts.alwaysConsumesOnSuccess(ast, node.expression)) {
|
||||||
throw new GrammarError("Infinite loop detected.", node.location);
|
throw new GrammarError("Possible infinite loop detected.", node.location);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
one_or_more: function(node) {
|
one_or_more: function(node) {
|
||||||
if (!asts.alwaysConsumesOnSuccess(ast, node.expression)) {
|
if (!asts.alwaysConsumesOnSuccess(ast, node.expression)) {
|
||||||
throw new GrammarError("Infinite loop detected.", node.location);
|
throw new GrammarError("Possible infinite loop detected.", node.location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,7 +38,7 @@ function reportLeftRecursion(ast) {
|
||||||
rule_ref: function(node) {
|
rule_ref: function(node) {
|
||||||
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 + "\".",
|
"Possible left recursion detected for rule \"" + node.name + "\".",
|
||||||
node.location
|
node.location
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ describe("compiler pass |reportInfiniteLoops|", 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: "Possible infinite loop detected.",
|
||||||
location: {
|
location: {
|
||||||
start: { offset: 8, line: 1, column: 9 },
|
start: { offset: 8, line: 1, column: 9 },
|
||||||
end: { offset: 13, line: 1, column: 14 }
|
end: { offset: 13, line: 1, column: 14 }
|
||||||
|
@ -18,7 +18,7 @@ describe("compiler pass |reportInfiniteLoops|", function() {
|
||||||
|
|
||||||
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: "Possible infinite loop detected.",
|
||||||
location: {
|
location: {
|
||||||
start: { offset: 8, line: 1, column: 9 },
|
start: { offset: 8, line: 1, column: 9 },
|
||||||
end: { offset: 13, line: 1, column: 14 }
|
end: { offset: 13, line: 1, column: 14 }
|
||||||
|
|
|
@ -8,7 +8,7 @@ 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: 'Possible left recursion detected for rule \"start\".',
|
||||||
location: {
|
location: {
|
||||||
start: { offset: 8, line: 1, column: 9 },
|
start: { offset: 8, line: 1, column: 9 },
|
||||||
end: { offset: 13, line: 1, column: 14 }
|
end: { offset: 13, line: 1, column: 14 }
|
||||||
|
@ -21,7 +21,7 @@ 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: 'Possible left recursion detected for rule \"start\".',
|
||||||
location: {
|
location: {
|
||||||
start: { offset: 21, line: 2, column: 9 },
|
start: { offset: 21, line: 2, column: 9 },
|
||||||
end: { offset: 26, line: 2, column: 14 }
|
end: { offset: 26, line: 2, column: 14 }
|
||||||
|
|
Loading…
Reference in a new issue