|
|
|
@ -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(
|
|
|
|
|