Jasmine: Convert |reportLeftRecursion| compiler pass tests
parent
2889ca72fc
commit
1471df9a69
@ -0,0 +1,88 @@
|
|||||||
|
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 choice", function() {
|
||||||
|
expect(pass).toReportLeftRecursionIn('start = start / "a" / "b"');
|
||||||
|
expect(pass).toReportLeftRecursionIn('start = "a" / "b" / 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 left recursion inside an action", function() {
|
||||||
|
expect(pass).toReportLeftRecursionIn('start = start { }');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("reports indirect left recursion", function() {
|
||||||
|
expect(pass).toReportLeftRecursionIn([
|
||||||
|
'start = stop',
|
||||||
|
'stop = start'
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
|
});
|
@ -1,40 +0,0 @@
|
|||||||
(function() {
|
|
||||||
|
|
||||||
module("PEG.compiler.passes.reportLeftRecursion");
|
|
||||||
|
|
||||||
test("reports left recursion", function() {
|
|
||||||
function testGrammar(grammar) {
|
|
||||||
raises(
|
|
||||||
function() {
|
|
||||||
var ast = PEG.parser.parse(grammar);
|
|
||||||
PEG.compiler.passes.reportLeftRecursion(ast);
|
|
||||||
},
|
|
||||||
function(e) {
|
|
||||||
return e instanceof PEG.GrammarError
|
|
||||||
&& e.message === "Left recursion detected for rule \"start\".";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var grammars = [
|
|
||||||
/* Direct */
|
|
||||||
'start = start',
|
|
||||||
'start = start / "a" / "b"',
|
|
||||||
'start = "a" / "b" / start',
|
|
||||||
'start = start "a" "b"',
|
|
||||||
'start = label:start',
|
|
||||||
'start = &start',
|
|
||||||
'start = !start',
|
|
||||||
'start = start?',
|
|
||||||
'start = start*',
|
|
||||||
'start = start+',
|
|
||||||
'start = start { }',
|
|
||||||
|
|
||||||
/* Indirect */
|
|
||||||
'start = stop; stop = start'
|
|
||||||
];
|
|
||||||
|
|
||||||
for (var i = 0; i < grammars.length; i++) { testGrammar(grammars[i]); }
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
Loading…
Reference in New Issue