describe("compiler pass |reportLeftRecursion|", function() { var pass = PEG.compiler.passes.reportLeftRecursion; beforeEach(function() { this.addMatchers({ toReportLeftRecursionIn: function(grammar) { var ast = PEG.parser.parse(grammar); try { this.actual(ast); this.message = function() { return "Expected the pass to report left recursion for grammar " + jasmine.pp(grammar) + ", " + "but it didn't."; }; return false; } catch (e) { if (this.isNot) { this.message = function() { return "Expected the pass not to report left recursion for grammar " + jasmine.pp(grammar) + ", " + "but it did."; }; } else { this.message = function() { return "Expected the pass to report left recursion for grammar " + jasmine.pp(grammar) + ", " + "but it reported an error with message " + jasmine.pp(e.message) + "."; }; } return e.message === 'Left recursion detected for rule \"start\".'; } } }); }); it("reports left recursion inside a rule", function() { expect(pass).toReportLeftRecursionIn('start = start'); }); it("reports left recursion inside a named", function() { expect(pass).toReportLeftRecursionIn('start "start" = start'); }); it("reports left recursion inside a choice", function() { expect(pass).toReportLeftRecursionIn('start = start / "a" / "b"'); expect(pass).toReportLeftRecursionIn('start = "a" / "b" / start'); }); it("reports left recursion inside an action", function() { expect(pass).toReportLeftRecursionIn('start = start { }'); }); it("reports left recursion inside a sequence", function() { expect(pass).toReportLeftRecursionIn('start = start "a" "b"'); }); it("reports left recursion inside a labeled", function() { expect(pass).toReportLeftRecursionIn('start = label:start'); }); it("reports left recursion inside a simple and", function() { expect(pass).toReportLeftRecursionIn('start = &start'); }); it("reports left recursion inside a simple not", function() { expect(pass).toReportLeftRecursionIn('start = &start'); }); it("reports left recursion inside an optional", function() { expect(pass).toReportLeftRecursionIn('start = start?'); }); it("reports left recursion inside a zero or more", function() { expect(pass).toReportLeftRecursionIn('start = start*'); }); it("reports left recursion inside a one or more", function() { expect(pass).toReportLeftRecursionIn('start = start+'); }); it("reports indirect left recursion", function() { expect(pass).toReportLeftRecursionIn([ 'start = stop', 'stop = start' ].join("\n")); }); });