diff --git a/gulpfile.js b/gulpfile.js index d0d42e9..496fe67 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -66,7 +66,7 @@ task( "benchmark", cb => { // Generate the grammar parser. task( "build:parser", cb => { - node( "bin/peg src/grammar.pegjs -o lib/parser/grammar.js -c src/pegjs.config.js", cb ); + node( "bin/peg src/parser.pegjs -o lib/parser.js -c src/pegjs.config.js", cb ); } ); diff --git a/lib/parser/ast.js b/lib/ast/Grammar.js similarity index 90% rename from lib/parser/ast.js rename to lib/ast/Grammar.js index 917a511..9000030 100644 --- a/lib/parser/ast.js +++ b/lib/ast/Grammar.js @@ -1,20 +1,9 @@ "use strict"; -const visitor = require( "../compiler/visitor" ); +const Node = require( "./Node" ); +const visitor = require( "./visitor" ); const util = require( "../util" ); -class Node { - - constructor( type, location ) { - - this.type = type; - this.location = location; - - } - -} -exports.Node = Node; - class Grammar extends Node { // Creates a new AST @@ -57,7 +46,8 @@ class Grammar extends Node { } } -exports.Grammar = Grammar; + +module.exports = Grammar; /* ***************************** @private ***************************** */ diff --git a/lib/ast/Node.js b/lib/ast/Node.js new file mode 100644 index 0000000..3087813 --- /dev/null +++ b/lib/ast/Node.js @@ -0,0 +1,14 @@ +"use strict"; + +class Node { + + constructor( type, location ) { + + this.type = type; + this.location = location; + + } + +} + +module.exports = Node; diff --git a/lib/ast/index.js b/lib/ast/index.js new file mode 100644 index 0000000..4ac1ebb --- /dev/null +++ b/lib/ast/index.js @@ -0,0 +1,5 @@ +"use strict"; + +exports.visitor = require( "./visitor" ); +exports.Node = require( "./Node" ); +exports.Grammar = require( "./Grammar" ); diff --git a/lib/compiler/visitor.js b/lib/ast/visitor.js similarity index 83% rename from lib/compiler/visitor.js rename to lib/ast/visitor.js index 18e8718..198b5e1 100644 --- a/lib/compiler/visitor.js +++ b/lib/ast/visitor.js @@ -10,32 +10,34 @@ class ASTVisitor { visit( node ) { // istanbul ignore next - if ( ! node ) throw new Error( "Visitor function called with no or `null` node" ); + if ( ! node ) throw new Error( "Visitor function called with no arguments or a `falsy` node" ); - const func = this[ node.type ]; + const fn = this[ node.type ]; // istanbul ignore next - if ( ! func ) throw new Error( "Visitor function for node type '" + node.type + " not defined" ); + if ( ! fn ) throw new Error( `Visitor function for node type "${ node.type }" not defined` ); - const args = __slice.call( arguments, 0 ); - - return func.apply( this, args ); + return fn.apply( this, arguments ); } +} + +module.exports = { + + ASTVisitor, + // Simple AST node visitor builder for PEG.js - static build( functions ) { + build( functions ) { let visitor = new ASTVisitor(); util.extend( visitor, functions ); visitor = util.enforceFastProperties( visitor ); return visitor.visit.bind( visitor ); - } + }, -} -ASTVisitor.ASTVisitor = ASTVisitor; -module.exports = ASTVisitor; +}; // Helper's to create visitor's for use with the ASTVisitor class const on = ASTVisitor.for = { @@ -99,17 +101,19 @@ const DEFAULT_FUNCTIONS = { grammar( node ) { - const extraArgs = __slice.call( arguments, 1 ); + const args = [ void 0 ].concat( __slice.call( arguments, 1 ) ); if ( node.initializer ) { - this.visit.apply( this, [ node.initializer ].concat( extraArgs ) ); + args[ 0 ] = node.initializer; + this.visit.apply( this, args ); } node.rules.forEach( rule => { - this.visit.apply( this, [ rule ].concat( extraArgs ) ); + args[ 0 ] = rule; + this.visit.apply( this, args ); } ); diff --git a/lib/compiler/index.js b/lib/compiler/index.js index fe5f913..c0515dc 100644 --- a/lib/compiler/index.js +++ b/lib/compiler/index.js @@ -10,7 +10,6 @@ const reportInfiniteRecursion = require( "./passes/report-infinite-recursion" ); const reportInfiniteRepetition = require( "./passes/report-infinite-repetition" ); const reportUndefinedRules = require( "./passes/report-undefined-rules" ); const inferenceMatchResult = require( "./passes/inference-match-result" ); -const visitor = require( "./visitor" ); const util = require( "../util" ); function processOptions( options, defaults ) { @@ -25,9 +24,6 @@ function processOptions( options, defaults ) { } const compiler = { - // AST node visitor builder. Useful mainly for plugins which manipulate the - // AST. - visitor: visitor, // Compiler passes. // @@ -96,6 +92,7 @@ const compiler = { } } + }; module.exports = compiler; diff --git a/lib/compiler/passes/calc-report-failures.js b/lib/compiler/passes/calc-report-failures.js index 1bc2ce1..70d3676 100644 --- a/lib/compiler/passes/calc-report-failures.js +++ b/lib/compiler/passes/calc-report-failures.js @@ -1,6 +1,6 @@ "use strict"; -const visitor = require( "../visitor" ); +const visitor = require( "../../ast" ).visitor; // Determines if rule always used in disabled report failure context, // that means, that any failures, reported within it, are never will be diff --git a/lib/compiler/passes/generate-bytecode.js b/lib/compiler/passes/generate-bytecode.js index f0bee29..2e679fe 100644 --- a/lib/compiler/passes/generate-bytecode.js +++ b/lib/compiler/passes/generate-bytecode.js @@ -1,7 +1,7 @@ "use strict"; const op = require( "../opcodes" ); -const visitor = require( "../visitor" ); +const visitor = require( "../../ast" ).visitor; const util = require( "../../util" ); // Generates bytecode. diff --git a/lib/compiler/passes/inference-match-result.js b/lib/compiler/passes/inference-match-result.js index d834951..8aed1d4 100644 --- a/lib/compiler/passes/inference-match-result.js +++ b/lib/compiler/passes/inference-match-result.js @@ -1,6 +1,6 @@ "use strict"; -const visitor = require( "../visitor" ); +const visitor = require( "../../ast" ).visitor; const GrammarError = require( "../../grammar-error" ); // Inference match result of the rule. Can be: diff --git a/lib/compiler/passes/remove-proxy-rules.js b/lib/compiler/passes/remove-proxy-rules.js index a452e0e..db32cc5 100644 --- a/lib/compiler/passes/remove-proxy-rules.js +++ b/lib/compiler/passes/remove-proxy-rules.js @@ -1,6 +1,6 @@ "use strict"; -const visitor = require( "../visitor" ); +const visitor = require( "../../ast" ).visitor; // Removes proxy rules -- that is, rules that only delegate to other rule. function removeProxyRules( ast, options ) { diff --git a/lib/compiler/passes/report-duplicate-labels.js b/lib/compiler/passes/report-duplicate-labels.js index 35746e3..28564fc 100644 --- a/lib/compiler/passes/report-duplicate-labels.js +++ b/lib/compiler/passes/report-duplicate-labels.js @@ -1,7 +1,7 @@ "use strict"; const GrammarError = require( "../../grammar-error" ); -const visitor = require( "../visitor" ); +const visitor = require( "../../ast" ).visitor; const util = require( "../../util" ); const __hasOwnProperty = Object.prototype.hasOwnProperty; diff --git a/lib/compiler/passes/report-duplicate-rules.js b/lib/compiler/passes/report-duplicate-rules.js index b1fb3d0..287554b 100644 --- a/lib/compiler/passes/report-duplicate-rules.js +++ b/lib/compiler/passes/report-duplicate-rules.js @@ -1,7 +1,7 @@ "use strict"; const GrammarError = require( "../../grammar-error" ); -const visitor = require( "../visitor" ); +const visitor = require( "../../ast" ).visitor; const __hasOwnProperty = Object.prototype.hasOwnProperty; // Checks that each rule is defined only once. diff --git a/lib/compiler/passes/report-infinite-recursion.js b/lib/compiler/passes/report-infinite-recursion.js index 9118878..def253f 100644 --- a/lib/compiler/passes/report-infinite-recursion.js +++ b/lib/compiler/passes/report-infinite-recursion.js @@ -1,7 +1,7 @@ "use strict"; const GrammarError = require( "../../grammar-error" ); -const visitor = require( "../visitor" ); +const visitor = require( "../../ast" ).visitor; // Reports left recursion in the grammar, which prevents infinite recursion in // the generated parser. diff --git a/lib/compiler/passes/report-infinite-repetition.js b/lib/compiler/passes/report-infinite-repetition.js index f7e7b95..72d9dc9 100644 --- a/lib/compiler/passes/report-infinite-repetition.js +++ b/lib/compiler/passes/report-infinite-repetition.js @@ -1,7 +1,7 @@ "use strict"; const GrammarError = require( "../../grammar-error" ); -const visitor = require( "../visitor" ); +const visitor = require( "../../ast" ).visitor; // Reports expressions that don't consume any input inside |*| or |+| in the // grammar, which prevents infinite loops in the generated parser. diff --git a/lib/compiler/passes/report-undefined-rules.js b/lib/compiler/passes/report-undefined-rules.js index 4e5796e..ea8ef24 100644 --- a/lib/compiler/passes/report-undefined-rules.js +++ b/lib/compiler/passes/report-undefined-rules.js @@ -1,7 +1,7 @@ "use strict"; const GrammarError = require( "../../grammar-error" ); -const visitor = require( "../visitor" ); +const visitor = require( "../../ast" ).visitor; // Checks that all referenced rules exist. function reportUndefinedRules( ast, options ) { diff --git a/lib/parser/grammar.js b/lib/parser.js similarity index 99% rename from lib/parser/grammar.js rename to lib/parser.js index b2f2060..33a62d1 100644 --- a/lib/parser/grammar.js +++ b/lib/parser.js @@ -5,7 +5,7 @@ "use strict"; var ast = require("./ast"); -var util = require("../util"); +var util = require("./util"); function peg$subclass(child, parent) { function C() { this.constructor = child; } diff --git a/lib/parser/index.js b/lib/parser/index.js deleted file mode 100644 index a79660f..0000000 --- a/lib/parser/index.js +++ /dev/null @@ -1,9 +0,0 @@ -"use strict"; - -const ast = require( "./ast" ); -const parser = require( "./grammar" ); - -parser.Grammar = ast.Grammar; -parser.Node = ast.Node; - -module.exports = parser; diff --git a/lib/peg.js b/lib/peg.js index 7304ef1..432f9a0 100644 --- a/lib/peg.js +++ b/lib/peg.js @@ -1,6 +1,7 @@ "use strict"; const GrammarError = require( "./grammar-error" ); +const ast = require( "./ast" ); const compiler = require( "./compiler" ); const parser = require( "./parser" ); const util = require( "./util" ); @@ -10,6 +11,7 @@ const peg = { VERSION: "0.11.0-dev", GrammarError: GrammarError, + ast: ast, parser: parser, compiler: compiler, util: util, diff --git a/lib/typings/api.d.ts b/lib/typings/api.d.ts index 25b4ba4..32ea1ed 100644 --- a/lib/typings/api.d.ts +++ b/lib/typings/api.d.ts @@ -5,7 +5,7 @@ export as namespace peg; declare namespace peg { - type AST = parser.Grammar; + type Grammar = ast.Grammar; type GeneratedParser = gp.API; type SyntaxError = gp.SyntaxErrorConstructor; type SourceLocation = gp.SourceLocation; @@ -28,13 +28,10 @@ declare namespace peg { } - /** - * A generated PEG.js parser to parse PEG.js grammar source's. - */ - namespace parser { + namespace ast { /** - * PEG.js node constructor, used internally by the PEG.js to create nodes. + * PEG.js node constructor, used internally by the PEG.js parser to create nodes. */ class Node { @@ -54,20 +51,20 @@ declare namespace peg { private readonly _alwaysConsumesOnSuccess: any; type: "grammar"; - comments?: CommentMao; - initializer?: ast.Initializer; - rules: ast.Rule[]; + comments?: Comment; + initializer?: Initializer; + rules: Rule[]; constructor( - initializer: void | ast.Initializer, - rules: ast.Rule[], - comments: void | CommentMao, + initializer: void | Initializer, + rules: Rule[], + comments: void | Comment, location: SourceLocation, ); - findRule( name: string ): ast.Rule | void; + findRule( name: string ): Rule | void; indexOfRule( name: string ): number; - alwaysConsumesOnSuccess( node: ast.Node ): boolean; + alwaysConsumesOnSuccess( node: Object ): boolean; // Added by Bytecode generator @@ -82,7 +79,7 @@ declare namespace peg { } - interface CommentMao { + interface Comment { [ offset: number ]: { @@ -94,189 +91,234 @@ declare namespace peg { } + interface INode extends peg.ast.Node { } + /** - * Interface's that describe the abstact sytax tree used by PEG.js + * This type represent's all PEG.js AST node's. */ - namespace ast { + type Object + = Grammar + | Initializer + | Rule + | Named + | Expression; - interface INode extends parser.Node { } + interface Initializer extends INode { - /** - * Unlike `parser.Node` this interface represent's all PEG.js node's. - */ - type Node - = parser.Grammar - | Initializer - | Rule - | Named - | Expression; + type: "initializer"; + code: string; - interface Initializer extends INode { + } - type: "initializer"; - code: string; + interface Rule extends INode { - } + // Default properties - interface Rule extends INode { + type: "rule", + name: string; + expression: Named | Expression; - // Default properties + // Added by calc-report-failures pass - type: "rule", - name: string; - expression: Named | Expression; + reportFailures?: boolean; - // Added by calc-report-failures pass + // Added by inference-match-result pass - reportFailures?: boolean; + match?: number; - // Added by inference-match-result pass + // Added by generate-bytecode pass - match?: number; + bytecode?: number[]; - // Added by generate-bytecode pass + } - bytecode?: number[]; + interface Named extends INode { - } + type: "named"; + name: string; + expression: Expression; - interface Named extends INode { + } - type: "named"; - name: string; - expression: Expression; + type Expression + = ChoiceExpression + | ActionExpression + | SequenceExpression + | LabeledExpression + | PrefixedExpression + | SuffixedExpression + | PrimaryExpression; - } + interface ChoiceExpression extends INode { - type Expression - = ChoiceExpression - | ActionExpression + type: "choice"; + alternatives: ( + ActionExpression | SequenceExpression | LabeledExpression | PrefixedExpression | SuffixedExpression - | PrimaryExpression; + | PrimaryExpression + )[]; - interface ChoiceExpression extends INode { + } - type: "choice"; - alternatives: ( - ActionExpression - | SequenceExpression - | LabeledExpression - | PrefixedExpression - | SuffixedExpression - | PrimaryExpression - )[]; + interface ActionExpression extends INode { - } + type: "action"; + expression: ( + SequenceExpression + | LabeledExpression + | PrefixedExpression + | SuffixedExpression + | PrimaryExpression + ); + code: string; - interface ActionExpression extends INode { + } - type: "action"; - expression: ( - SequenceExpression - | LabeledExpression - | PrefixedExpression - | SuffixedExpression - | PrimaryExpression - ); - code: string; + interface SequenceExpression extends INode { - } + type: "sequence", + elements: ( + LabeledExpression + | PrefixedExpression + | SuffixedExpression + | PrimaryExpression + )[]; - interface SequenceExpression extends INode { + } - type: "sequence", - elements: ( - LabeledExpression - | PrefixedExpression - | SuffixedExpression - | PrimaryExpression - )[]; + interface LabeledExpression extends INode { - } + type: "labeled"; + label: string; + expression: ( + PrefixedExpression + | SuffixedExpression + | PrimaryExpression + ); - interface LabeledExpression extends INode { + } - type: "labeled"; - label: string; - expression: ( - PrefixedExpression - | SuffixedExpression - | PrimaryExpression - ); + interface PrefixedExpression extends INode { - } + type: "text" | "simple_and" | "simple_not"; + expression: SuffixedExpression | PrimaryExpression; + + } - interface PrefixedExpression extends INode { + interface SuffixedExpression extends INode { - type: "text" | "simple_and" | "simple_not"; - expression: SuffixedExpression | PrimaryExpression; + type: "optional" | "zero_or_more" | "one_or_more"; + expression: PrimaryExpression; - } + } - interface SuffixedExpression extends INode { + type PrimaryExpression + = LiteralMatcher + | CharacterClassMatcher + | AnyMatcher + | RuleReferenceExpression + | SemanticPredicateExpression + | GroupExpression; - type: "optional" | "zero_or_more" | "one_or_more"; - expression: PrimaryExpression; + interface LiteralMatcher extends INode { - } + type: "literal"; + value: string; + ignoreCase: boolean; - type PrimaryExpression - = LiteralMatcher - | CharacterClassMatcher - | AnyMatcher - | RuleReferenceExpression - | SemanticPredicateExpression - | GroupExpression; + } - interface LiteralMatcher extends INode { + interface CharacterClassMatcher extends INode { - type: "literal"; - value: string; - ignoreCase: boolean; + type: "class"; + parts: ( string[] | string )[]; + inverted: boolean; + ignoreCase: boolean; - } + } - interface CharacterClassMatcher extends INode { + interface AnyMatcher extends INode { - type: "class"; - parts: ( string[] | string )[]; - inverted: boolean; - ignoreCase: boolean; + type: "any"; - } + } - interface AnyMatcher extends INode { + interface RuleReferenceExpression extends INode { - type: "any"; + type: "rule_ref"; + name: string; - } + } + + interface SemanticPredicateExpression extends INode { + + type: "semantic_and" | "semantic_not"; + code: string; + + } - interface RuleReferenceExpression extends INode { + interface GroupExpression extends INode { - type: "rule_ref"; - name: string; + type: "group"; + expression: LabeledExpression | SequenceExpression; + + } + + namespace visitor { + + interface IVisitorMap { + + [ key: string ]: any; + grammar?( node: Grammar, ...args ): R; + initializer?( node: Initializer, ...args ): R; + rule?( node: Rule, ...args ): R; + named?( node: Named, ...args ): R; + choice?( node: ChoiceExpression, ...args ): R; + action?( node: ActionExpression, ...args ): R; + sequence?( node: SequenceExpression, ...args ): R; + labeled?( node: LabeledExpression, ...args ): R; + text?( node: PrefixedExpression, ...args ): R; + simple_and?( node: PrefixedExpression, ...args ): R; + simple_not?( node: PrefixedExpression, ...args ): R; + optional?( node: SuffixedExpression, ...args ): R; + zero_or_more?( node: SuffixedExpression, ...args ): R; + one_or_more?( node: SuffixedExpression, ...args ): R; + literal?( node: LiteralMatcher, ...args ): R; + class?( node: CharacterClassMatcher, ...args ): R; + any?( node: AnyMatcher, ...args ): R; + rule_ref?( node: RuleReferenceExpression, ...args ): R; + semantic_and?( node: SemanticPredicateExpression, ...args ): R; + semantic_not?( node: SemanticPredicateExpression, ...args ): R; + group?( node: GroupExpression, ...args ): R; } - interface SemanticPredicateExpression extends INode { + class ASTVisitor implements IVisitorMap { - type: "semantic_and" | "semantic_not"; - code: string; + visit( node: Object, ...args ): R; } - interface GroupExpression extends INode { + interface IVisitor { - type: "group"; - expression: LabeledExpression | SequenceExpression; + ( node: Object, ...args ): R; } + function build( functions: IVisitorMap ): IVisitor; + } + } + + /** + * A generated PEG.js parser to parse PEG.js grammar source's. + */ + namespace parser { + const SyntaxError: SyntaxError; function parse( input: string, options?: gp.IOptions ): Grammar; @@ -330,48 +372,6 @@ declare namespace peg { } - interface IVisitor { - - ( node: parser.ast.Node, ...args ): R; - - } - - interface IVisitorMap { - - [ key: string ]: any; - grammar?( node: Grammar, ...args ): R; - initializer?( node: parser.ast.Initializer, ...args ): R; - rule?( node: parser.ast.Rule, ...args ): R; - named?( node: parser.ast.Named, ...args ): R; - choice?( node: parser.ast.ChoiceExpression, ...args ): R; - action?( node: parser.ast.ActionExpression, ...args ): R; - sequence?( node: parser.ast.SequenceExpression, ...args ): R; - labeled?( node: parser.ast.LabeledExpression, ...args ): R; - text?( node: parser.ast.PrefixedExpression, ...args ): R; - simple_and?( node: parser.ast.PrefixedExpression, ...args ): R; - simple_not?( node: parser.ast.PrefixedExpression, ...args ): R; - optional?( node: parser.ast.SuffixedExpression, ...args ): R; - zero_or_more?( node: parser.ast.SuffixedExpression, ...args ): R; - one_or_more?( node: parser.ast.SuffixedExpression, ...args ): R; - literal?( node: parser.ast.LiteralMatcher, ...args ): R; - class?( node: parser.ast.CharacterClassMatcher, ...args ): R; - any?( node: parser.ast.AnyMatcher, ...args ): R; - rule_ref?( node: parser.ast.RuleReferenceExpression, ...args ): R; - semantic_and?( node: parser.ast.SemanticPredicateExpression, ...args ): R; - semantic_not?( node: parser.ast.SemanticPredicateExpression, ...args ): R; - group?( node: parser.ast.GroupExpression, ...args ): R; - - } - - class visitor implements IVisitorMap { - - visit: IVisitor; - - static build( functions: IVisitorMap ): IVisitor; - static ASTVisitor: visitor; - - } - namespace passes { namespace check { diff --git a/lib/typings/modules.d.ts b/lib/typings/modules.d.ts index d46c558..ff66bfc 100644 --- a/lib/typings/modules.d.ts +++ b/lib/typings/modules.d.ts @@ -18,22 +18,40 @@ declare module "pegjs/lib/parser" { } -declare module "pegjs/lib/parser/ast" { +declare module "pegjs/lib/peg" { - export const Node: peg.parser.Node; - export const Grammar: peg.parser.Grammar; + export default peg; } -declare module "pegjs/lib/parser/index" { +declare module "pegjs/lib/ast" { - export default peg.parser; + export const Node: peg.ast.Node; + export const Grammar: peg.ast.Grammar; + export const visitor: { + + ASTVisitor: peg.ast.visitor.ASTVisitor; + build( functions: peg.ast.visitor.IVisitorMap ): peg.ast.visitor.IVisitor; + + }; } -declare module "pegjs/lib/peg" { +declare module "pegjs/lib/ast/Grammar" { - export default peg; + export default peg.ast.Grammar; + +} + +declare module "pegjs/lib/ast/Node" { + + export default peg.ast.Node; + +} + +declare module "pegjs/lib/ast/visitor" { + + export default peg.ast.visitor; } @@ -68,12 +86,6 @@ declare module "pegjs/lib/compiler/opcodes" { } -declare module "pegjs/lib/compiler/visitor" { - - export default peg.compiler.visitor; - -} - declare module "pegjs/lib/compiler/passes/calc-report-failures" { export default peg.compiler.passes.generate.calcReportFailures; diff --git a/src/grammar.pegjs b/src/parser.pegjs similarity index 100% rename from src/grammar.pegjs rename to src/parser.pegjs diff --git a/src/pegjs.config.js b/src/pegjs.config.js index d0d1620..2f14601 100644 --- a/src/pegjs.config.js +++ b/src/pegjs.config.js @@ -7,7 +7,7 @@ module.exports = { dependencies: { ast: "./ast", - util: "../util" + util: "./util" }, diff --git a/test/spec/api/plugin-api.spec.js b/test/spec/api/plugin-api.spec.js index 84b819d..fb64885 100644 --- a/test/spec/api/plugin-api.spec.js +++ b/test/spec/api/plugin-api.spec.js @@ -103,11 +103,11 @@ describe( "plugin API", function () { config.parser = peg.generate( ` { - const pp = require( process.cwd() + "/lib/peg" ).parser; + const ast = require( process.cwd() + "/lib/ast" ); } start = .* { - return new pp.Grammar( void 0, [{ + return new ast.Grammar( void 0, [{ type: "rule", name: "start", expression: { diff --git a/test/spec/unit/parser.spec.js b/test/spec/unit/parser.spec.js index 52820dd..a87e319 100644 --- a/test/spec/unit/parser.spec.js +++ b/test/spec/unit/parser.spec.js @@ -3,6 +3,7 @@ const chai = require( "chai" ); const parser = require( "pegjs-dev" ).parser; const util = require( "pegjs-dev" ).util; +const visitor = require( "pegjs-dev" ).ast.visitor; const expect = chai.expect; @@ -167,16 +168,6 @@ describe( "PEG.js grammar parser", function () { let strip; - function buildVisitor( functions ) { - - return function ( node ) { - - return functions[ node.type ].apply( null, arguments ); - - }; - - } - function stripLeaf( node ) { delete node.location; @@ -203,7 +194,7 @@ describe( "PEG.js grammar parser", function () { } - strip = buildVisitor( { + strip = visitor.build( { grammar( node ) { delete node.location;