2015-06-08 20:21:19 +02:00
|
|
|
"use strict";
|
|
|
|
|
2016-09-08 16:04:36 +02:00
|
|
|
let peg = require("../../../../lib/peg");
|
2016-09-08 13:29:06 +02:00
|
|
|
|
2016-07-29 18:06:16 +02:00
|
|
|
describe("compiler pass |reportInfiniteRepetition|", function() {
|
2016-09-08 16:04:36 +02:00
|
|
|
let pass = peg.compiler.passes.check.reportInfiniteRepetition;
|
2015-04-01 12:16:27 +02:00
|
|
|
|
|
|
|
it("reports infinite loops for zero_or_more", function() {
|
|
|
|
expect(pass).toReportError('start = ("")*', {
|
2016-07-04 07:19:57 +02:00
|
|
|
message: "Possible infinite loop when parsing (repetition used with an expression that may not consume any input).",
|
2015-04-06 10:34:07 +02:00
|
|
|
location: {
|
|
|
|
start: { offset: 8, line: 1, column: 9 },
|
|
|
|
end: { offset: 13, line: 1, column: 14 }
|
|
|
|
}
|
2015-04-01 12:16:27 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it("reports infinite loops for one_or_more", function() {
|
|
|
|
expect(pass).toReportError('start = ("")+', {
|
2016-07-04 07:19:57 +02:00
|
|
|
message: "Possible infinite loop when parsing (repetition used with an expression that may not consume any input).",
|
2015-04-06 10:34:07 +02:00
|
|
|
location: {
|
|
|
|
start: { offset: 8, line: 1, column: 9 },
|
|
|
|
end: { offset: 13, line: 1, column: 14 }
|
|
|
|
}
|
2015-04-01 12:16:27 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2015-09-04 17:35:37 +02:00
|
|
|
it("computes expressions that always consume input on success correctly", function() {
|
2015-08-03 16:56:57 +02:00
|
|
|
expect(pass).toReportError([
|
|
|
|
'start = a*',
|
|
|
|
'a "a" = ""'
|
|
|
|
].join('\n'));
|
|
|
|
expect(pass).not.toReportError([
|
|
|
|
'start = a*',
|
|
|
|
'a "a" = "a"'
|
|
|
|
].join('\n'));
|
|
|
|
|
2015-04-01 12:16:27 +02:00
|
|
|
expect(pass).toReportError('start = ("" / "a" / "b")*');
|
|
|
|
expect(pass).toReportError('start = ("a" / "" / "b")*');
|
|
|
|
expect(pass).toReportError('start = ("a" / "b" / "")*');
|
|
|
|
expect(pass).not.toReportError('start = ("a" / "b" / "c")*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = ("" { })*');
|
|
|
|
expect(pass).not.toReportError('start = ("a" { })*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = ("" "" "")*');
|
|
|
|
expect(pass).not.toReportError('start = ("a" "" "")*');
|
|
|
|
expect(pass).not.toReportError('start = ("" "a" "")*');
|
|
|
|
expect(pass).not.toReportError('start = ("" "" "a")*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = (a:"")*');
|
|
|
|
expect(pass).not.toReportError('start = (a:"a")*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = ($"")*');
|
|
|
|
expect(pass).not.toReportError('start = ($"a")*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = (&"")*');
|
|
|
|
expect(pass).toReportError('start = (&"a")*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = (!"")*');
|
|
|
|
expect(pass).toReportError('start = (!"a")*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = (""?)*');
|
|
|
|
expect(pass).toReportError('start = ("a"?)*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = (""*)*');
|
|
|
|
expect(pass).toReportError('start = ("a"*)*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = (""+)*');
|
|
|
|
expect(pass).not.toReportError('start = ("a"+)*');
|
|
|
|
|
2016-03-11 16:18:29 +01:00
|
|
|
expect(pass).toReportError('start = ("")*');
|
|
|
|
expect(pass).not.toReportError('start = ("a")*');
|
|
|
|
|
2015-04-01 12:16:27 +02:00
|
|
|
expect(pass).toReportError('start = (&{ })*');
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = (!{ })*');
|
|
|
|
|
|
|
|
expect(pass).toReportError([
|
|
|
|
'start = a*',
|
|
|
|
'a = ""'
|
|
|
|
].join('\n'));
|
|
|
|
expect(pass).not.toReportError([
|
|
|
|
'start = a*',
|
|
|
|
'a = "a"'
|
|
|
|
].join('\n'));
|
|
|
|
|
|
|
|
expect(pass).toReportError('start = ""*');
|
|
|
|
expect(pass).not.toReportError('start = "a"*');
|
|
|
|
|
|
|
|
expect(pass).not.toReportError('start = [a-d]*');
|
|
|
|
|
2015-07-17 15:31:46 +02:00
|
|
|
expect(pass).not.toReportError('start = .*');
|
2015-04-01 12:16:27 +02:00
|
|
|
});
|
|
|
|
});
|