Checks refactoring

Changed two things:

  1. Checks are run in |PEG.Compiler.compileParser|, not in
     |PEG.buildParser|.

  2. Checks are extracted into separate functions.
redux
David Majda 14 years ago
parent 85930cbcfe
commit 6f2a188efc

@ -23,19 +23,10 @@ function nop() {}
PEG.buildParser = function(grammar, startRule) {
startRule = startRule || "start";
var ast = PEG.grammarParser.parse(grammar);
for (var rule in ast) {
ast[rule].checkReferencedRulesExist(ast);
}
if (ast[startRule] === undefined) {
throw new PEG.Grammar.GrammarError("Missing \"" + startRule + "\" rule.");
}
for (var rule in ast) {
ast[rule].checkNoLeftRecursion(ast, []);
}
return PEG.Compiler.compileParser(ast, startRule);
return PEG.Compiler.compileParser(
PEG.grammarParser.parse(grammar),
startRule
);
};
/* ===== PEG.ArrayUtils ===== */
@ -462,18 +453,57 @@ PEG.Compiler = {
},
/*
* Generates a parser from a specified grammar and start rule.
* Checks made on the grammar AST before compilation. Each check is a function
* that is passed the AST and start rule and does not return anything. If the
* check passes, the function does not do anything special, otherwise it
* throws |PEG.Grammar.GrammarError|. The checks are run in sequence in order
* of their definition.
*/
compileParser: function(grammar, startRule) {
_checks: [
/* Checks that all referenced rules exist. */
function(ast, startRule) {
for (var rule in ast) {
ast[rule].checkReferencedRulesExist(ast);
}
},
/* Checks that the start rule is defined. */
function(ast, startRule) {
if (ast[startRule] === undefined) {
throw new PEG.Grammar.GrammarError(
"Missing \"" + startRule + "\" rule."
);
}
},
/* Checks that no left recursion is present. */
function(ast, startRule) {
for (var rule in ast) {
ast[rule].checkNoLeftRecursion(ast, []);
}
}
],
/*
* Generates a parser from a specified grammar AST and start rule. Throws
* |PEG.Grammar.GrammarError| if the AST contains a semantic error. Note that
* not all errors are detected during the generation and some may protrude to
* the generated parser and cause its malfunction.
*/
compileParser: function(ast, startRule) {
/*
* This ensures that the same grammar and start rule always generate exactly
* the same parser.
*/
this._resetUniqueIdentifierCounters();
for (var i = 0; i < this._checks.length; i++) {
this._checks[i](ast, startRule);
}
var parseFunctionDefinitions = [];
for (var rule in grammar) {
parseFunctionDefinitions.push(grammar[rule].compile());
for (var rule in ast) {
parseFunctionDefinitions.push(ast[rule].compile());
}
var source = this.formatCode(

Loading…
Cancel
Save