Checks refactoring
Changed two things: 1. Checks are run in |PEG.Compiler.compileParser|, not in |PEG.buildParser|. 2. Checks are extracted into separate functions.
This commit is contained in:
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…
Reference in a new issue