|
|
|
@ -44,6 +44,9 @@ PEG.buildParser = function(grammar, startRule) {
|
|
|
|
|
if (ast[startRule] === undefined) {
|
|
|
|
|
throw new PEG.Grammar.GrammarError("Missing \"" + startRule + "\" rule.");
|
|
|
|
|
}
|
|
|
|
|
for (var key in ast) {
|
|
|
|
|
ast[key].checkNoLeftRecursion(ast, []);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PEG.Compiler.compileParser(ast, startRule);
|
|
|
|
|
};
|
|
|
|
@ -140,6 +143,47 @@ PEG.Grammar.Action.prototype.checkReferencedRulesExist = function(grammar) {
|
|
|
|
|
this._expression.checkReferencedRulesExist(grammar);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* ===== Left Recursion Checks ===== */
|
|
|
|
|
|
|
|
|
|
PEG.Grammar.Rule.prototype.checkNoLeftRecursion = function(grammar, appliedRules) {
|
|
|
|
|
this._expression.checkNoLeftRecursion(grammar, appliedRules.concat(this._name));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PEG.Grammar.Literal.prototype.checkNoLeftRecursion = function(grammar, appliedRules) {};
|
|
|
|
|
|
|
|
|
|
PEG.Grammar.Any.prototype.checkNoLeftRecursion = function(grammar, appliedRules) {};
|
|
|
|
|
|
|
|
|
|
PEG.Grammar.Sequence.prototype.checkNoLeftRecursion = function(grammar, appliedRules) {
|
|
|
|
|
if (this._elements.length > 0) {
|
|
|
|
|
this._elements[0].checkNoLeftRecursion(grammar, appliedRules);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PEG.Grammar.Choice.prototype.checkNoLeftRecursion = function(grammar, appliedRules) {
|
|
|
|
|
PEG.ArrayUtils.each(this._alternatives, function(alternative) {
|
|
|
|
|
alternative.checkNoLeftRecursion(grammar, appliedRules);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PEG.Grammar.ZeroOrMore.prototype.checkNoLeftRecursion = function(grammar, appliedRules) {
|
|
|
|
|
this._element.checkNoLeftRecursion(grammar, appliedRules);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PEG.Grammar.NotPredicate.prototype.checkNoLeftRecursion = function(grammar, appliedRules) {
|
|
|
|
|
this._expression.checkNoLeftRecursion(grammar, appliedRules);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PEG.Grammar.RuleRef.prototype.checkNoLeftRecursion = function(grammar, appliedRules) {
|
|
|
|
|
if (appliedRules.indexOf(this._name) !== -1) {
|
|
|
|
|
throw new PEG.Grammar.GrammarError("Left recursion detected for rule \"" + this._name + "\".");
|
|
|
|
|
}
|
|
|
|
|
grammar[this._name].checkNoLeftRecursion(grammar, appliedRules);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PEG.Grammar.Action.prototype.checkNoLeftRecursion = function(grammar, appliedRules) {
|
|
|
|
|
this._expression.checkNoLeftRecursion(grammar, appliedRules);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* ===== PEG.Compiler ===== */
|
|
|
|
|
|
|
|
|
|
PEG.Compiler = {
|
|
|
|
|