pegjs/spec/compiler/passes/report-left-recursion.spec.js
David Majda 725927e05f Change ordering of "action" code
Places all code that does something with "action" AST nodes under code
handling "choice" nodes.

This ordering is logical because now all the node handling code matches
the sequence in which various node types usually appear when descending
through the AST tree.
2012-06-26 20:28:06 +02:00

93 lines
2.9 KiB
JavaScript

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"));
});
});