You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pegjs/spec/unit/compiler/passes/report-infinite-recursion.s...

116 lines
4.0 KiB
JavaScript

/* global peg */
"use strict";
describe("compiler pass |reportInfiniteRecursion|", function() {
var pass = peg.compiler.passes.check.reportInfiniteRecursion;
it("reports direct left recursion", function() {
expect(pass).toReportError('start = start', {
message: 'Possible infinite loop when parsing (left recursion: start -> start).',
location: {
start: { offset: 8, line: 1, column: 9 },
end: { offset: 13, line: 1, column: 14 }
}
});
});
it("reports indirect left recursion", function() {
expect(pass).toReportError([
'start = stop',
'stop = start'
].join("\n"), {
message: 'Possible infinite loop when parsing (left recursion: start -> stop -> start).',
location: {
start: { offset: 21, line: 2, column: 9 },
end: { offset: 26, line: 2, column: 14 }
}
});
});
describe("in sequences", function() {
it("reports left recursion if all preceding elements match empty string", function() {
expect(pass).toReportError('start = "" "" "" start');
});
it("doesn't report left recursion if some preceding element doesn't match empty string", function() {
expect(pass).not.toReportError('start = "a" "" "" start');
expect(pass).not.toReportError('start = "" "a" "" start');
expect(pass).not.toReportError('start = "" "" "a" start');
});
/* Regression test for #359. */
it("reports left recursion when rule reference is wrapped in an expression", function() {
expect(pass).toReportError('start = "" start?');
});
it("computes expressions that always consume input on success correctly", function() {
expect(pass).toReportError([
'start = a start',
'a "a" = ""'
].join('\n'));
expect(pass).not.toReportError([
'start = a start',
'a "a" = "a"'
].join('\n'));
expect(pass).toReportError('start = ("" / "a" / "b") start');
expect(pass).toReportError('start = ("a" / "" / "b") start');
expect(pass).toReportError('start = ("a" / "b" / "") start');
expect(pass).not.toReportError('start = ("a" / "b" / "c") start');
expect(pass).toReportError('start = ("" { }) start');
expect(pass).not.toReportError('start = ("a" { }) start');
expect(pass).toReportError('start = ("" "" "") start');
expect(pass).not.toReportError('start = ("a" "" "") start');
expect(pass).not.toReportError('start = ("" "a" "") start');
expect(pass).not.toReportError('start = ("" "" "a") start');
expect(pass).toReportError('start = a:"" start');
expect(pass).not.toReportError('start = a:"a" start');
expect(pass).toReportError('start = $"" start');
expect(pass).not.toReportError('start = $"a" start');
expect(pass).toReportError('start = &"" start');
expect(pass).toReportError('start = &"a" start');
expect(pass).toReportError('start = !"" start');
expect(pass).toReportError('start = !"a" start');
expect(pass).toReportError('start = ""? start');
expect(pass).toReportError('start = "a"? start');
expect(pass).toReportError('start = ""* start');
expect(pass).toReportError('start = "a"* start');
expect(pass).toReportError('start = ""+ start');
expect(pass).not.toReportError('start = "a"+ start');
expect(pass).toReportError('start = ("") start');
expect(pass).not.toReportError('start = ("a") start');
expect(pass).toReportError('start = &{ } start');
expect(pass).toReportError('start = !{ } start');
expect(pass).toReportError([
'start = a start',
'a = ""'
].join('\n'));
expect(pass).not.toReportError([
'start = a start',
'a = "a"'
].join('\n'));
expect(pass).toReportError('start = "" start');
expect(pass).not.toReportError('start = "a" start');
expect(pass).not.toReportError('start = [a-d] start');
expect(pass).not.toReportError('start = . start');
});
});
});