Skip to content

Commit

Permalink
Checks refactoring
Browse files Browse the repository at this point in the history
Changed two things:

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

  2. Checks are extracted into separate functions.
  • Loading branch information
dmajda committed May 8, 2010
1 parent 85930cb commit 6f2a188
Showing 1 changed file with 47 additions and 17 deletions.
64 changes: 47 additions & 17 deletions lib/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ===== */
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit 6f2a188

Please sign in to comment.