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.
116 lines
4.0 KiB
JavaScript
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');
|
|
});
|
|
});
|
|
});
|