@ -7,24 +7,18 @@
/* no var */ PEG = { } ;
/ *
* Generates a parser from a specified grammar and start rule and returns it .
* Generates a parser from a specified grammar and returns it .
*
* The grammar must be a string in the format described by the metagramar in the
* metagrammar . pegjs file . The start rule may be unspecified , in which case
* "start" is used .
* metagrammar . pegjs file .
*
* Throws | PEG . grammarParser . SyntaxError | if the grammar contains a syntax error
* or | PEG . GrammarError | if it 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 .
* /
PEG . buildParser = function ( grammar , startRule ) {
startRule = startRule || "start" ;
return PEG . Compiler . compileParser (
PEG . grammarParser . parse ( grammar ) ,
startRule
) ;
PEG . buildParser = function ( grammar ) {
return PEG . Compiler . compileParser ( PEG . grammarParser . parse ( grammar ) ) ;
} ;
/* ===== PEG.GrammarError ===== */
@ -262,14 +256,14 @@ PEG.Compiler = {
/ *
* 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 . GrammarError | . The checks are run in sequence in order of their
* that is passed the AST and does not return anything . If the check passes ,
* the function does not do anything special , otherwise it throws
* | PEG . GrammarError | . The checks are run in sequence in order of their
* definition .
* /
_checks : [
/* Checks that all referenced rules exist. */
function ( ast , startRule ) {
function ( ast ) {
function nop ( ) { }
function checkExpression ( node ) { check ( node . expression ) ; }
@ -313,17 +307,8 @@ PEG.Compiler = {
}
} ,
/* Checks that the start rule is defined. */
function ( ast , startRule ) {
if ( typeof ( ast . rules [ startRule ] ) === "undefined" ) {
throw new PEG . GrammarError (
"Missing \"" + startRule + "\" rule."
) ;
}
} ,
/* Checks that no left recursion is present. */
function ( ast , startRule ) {
function ( ast ) {
function nop ( ) { }
function checkExpression ( node , appliedRules ) {
@ -385,15 +370,15 @@ PEG.Compiler = {
/ *
* Optimalization passes made on the grammar AST before compilation . Each pass
* is a function that is passed the AST and start rule and returns a new AST
* and start rule . The AST can be modified in - place by the pass . The passes
* are run in sequence in order of their definition .
* is a function that is passed the AST and returns a new AST . The AST can be
* modified in - place by the pass . The passes are run in sequence in order of
* their definition .
* /
_passes : [
/ *
* Removes proxy rules -- that is , rules that only delegate to other rule .
* /
function ( ast , startRule ) {
function ( ast ) {
function isProxyRule ( node ) {
return node . type === "rule" && node . expression . type === "rule_ref" ;
}
@ -449,14 +434,14 @@ PEG.Compiler = {
for ( var rule in ast . rules ) {
if ( isProxyRule ( ast . rules [ rule ] ) ) {
replaceRuleRefs ( ast , ast . rules [ rule ] . name , ast . rules [ rule ] . expression . name ) ;
if ( rule === startRule) {
startRule = ast . rules [ rule ] . expression . name ;
if ( rule === ast. startRule) {
ast. startRule = ast . rules [ rule ] . expression . name ;
}
delete ast . rules [ rule ] ;
}
}
return [ ast , startRule ] ;
return ast ;
}
] ,
@ -871,20 +856,18 @@ PEG.Compiler = {
} ,
/ *
* Generates a parser from a specified grammar AST and start rule . Throws
* | PEG . 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 .
* Generates a parser from a specified grammar AST . Throws | PEG . 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 ) {
compileParser : function ( ast ) {
for ( var i = 0 ; i < this . _checks . length ; i ++ ) {
this . _checks [ i ] ( ast , startRule );
this . _checks [ i ] ( ast );
}
for ( var i = 0 ; i < this . _passes . length ; i ++ ) {
var newAstNadStartRule = this . _passes [ i ] ( ast , startRule ) ;
ast = newAstNadStartRule [ 0 ] ;
startRule = newAstNadStartRule [ 1 ] ;
ast = this . _passes [ i ] ( ast ) ;
}
var initializerCode = ast . initializer !== null
@ -1078,7 +1061,7 @@ PEG.Compiler = {
{
initializerCode : initializerCode ,
parseFunctionDefinitions : parseFunctionDefinitions . join ( "\n\n" ) ,
startRule : startRule
startRule : ast. startRule
}
) ;