From d3d4ace153320da5ed74c2446d8165b0b9eefede Mon Sep 17 00:00:00 2001 From: David Majda Date: Sun, 6 Jan 2013 10:32:52 +0100 Subject: [PATCH] Move options handling from passes to |PEG.compiler.compile| This eliminates some duplicate code. --- lib/compiler.js | 15 +++-- lib/compiler/passes/generate-javascript.js | 7 --- lib/compiler/passes/remove-proxy-rules.js | 7 +-- .../passes/remove-proxy-rules.spec.js | 58 +++++++++++++++---- 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index 3d107c0..fd9f27a 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -21,17 +21,22 @@ module.exports = { * during the generation and some may protrude to the generated parser and * cause its malfunction. */ - compile: function(ast, options) { - if (options === undefined) { options = {}; } + compile: function(ast) { + var that = this, + options = arguments.length > 1 ? utils.clone(arguments[1]) : {}; - var that = this, - output = options.output !== undefined ? options.output : "parser"; + utils.defaults(options, { + allowedStartRules: [ast.rules[0].name], + cache: false, + optimize: "speed", + output: "parser" + }); utils.each(this.appliedPassNames, function(passName) { that.passes[passName](ast, options); }); - switch (output) { + switch (options.output) { case "parser": return eval(ast.code); case "source": return ast.code; } diff --git a/lib/compiler/passes/generate-javascript.js b/lib/compiler/passes/generate-javascript.js index 1784db2..3083107 100644 --- a/lib/compiler/passes/generate-javascript.js +++ b/lib/compiler/passes/generate-javascript.js @@ -3,13 +3,6 @@ var utils = require("../../utils"), /* Generates parser JavaScript code. */ module.exports = function(ast, options) { - options = utils.clone(options); - utils.defaults(options, { - cache: false, - allowedStartRules: [ast.rules[0].name], - optimize: "speed" - }); - /* These only indent non-empty lines to avoid trailing whitespace. */ function indent2(code) { return code.replace(/^(.+)$/gm, ' $1'); } function indent4(code) { return code.replace(/^(.+)$/gm, ' $1'); } diff --git a/lib/compiler/passes/remove-proxy-rules.js b/lib/compiler/passes/remove-proxy-rules.js index 9b4d629..c269328 100644 --- a/lib/compiler/passes/remove-proxy-rules.js +++ b/lib/compiler/passes/remove-proxy-rules.js @@ -55,15 +55,12 @@ module.exports = function(ast, options) { replace(ast, from, to); } - var indices = [], - allowedStartRules = options.allowedStartRules !== undefined - ? options.allowedStartRules - : [ast.rules[0].name]; + var indices = []; utils.each(ast.rules, function(rule, i) { if (isProxyRule(rule)) { replaceRuleRefs(ast, rule.name, rule.expression.name); - if (!utils.contains(allowedStartRules, rule.name)) { + if (!utils.contains(options.allowedStartRules, rule.name)) { indices.push(i); } } diff --git a/spec/compiler/passes/remove-proxy-rules.spec.js b/spec/compiler/passes/remove-proxy-rules.spec.js index c8433df..319a5e0 100644 --- a/spec/compiler/passes/remove-proxy-rules.spec.js +++ b/spec/compiler/passes/remove-proxy-rules.spec.js @@ -14,11 +14,12 @@ describe("compiler pass |removeProxyRules|", function() { }; } - var proxiedRefDetails = { type: "rule_ref", name: "proxied" }, + var defaultOptions = { allowedStartRules: ["start"] }, + proxiedRefDetails = { type: "rule_ref", name: "proxied" }, simpleDetails = expressionDetails({ expression: proxiedRefDetails }); it("removes proxy rule from a rule", function() { - expect(pass).toChangeAST(proxyGrammar('start = proxy'), { + expect(pass).toChangeAST(proxyGrammar('start = proxy'), defaultOptions, { rules: [ { type: "rule", name: "start", expression: proxiedRefDetails }, { type: "rule", name: "proxied" } @@ -29,6 +30,7 @@ describe("compiler pass |removeProxyRules|", function() { it("removes proxy rule from a named", function() { expect(pass).toChangeAST( proxyGrammar('start "start" = proxy'), + defaultOptions, simpleDetails ); }); @@ -36,55 +38,91 @@ describe("compiler pass |removeProxyRules|", function() { it("removes proxy rule from a choice", function() { expect(pass).toChangeAST( proxyGrammar('start = proxy / "a" / "b"'), + defaultOptions, expressionDetails({ alternatives: [proxiedRefDetails, {}, {}] }) ); expect(pass).toChangeAST( proxyGrammar('start = "a" / "b" / proxy'), + defaultOptions, expressionDetails({ alternatives: [{}, {}, proxiedRefDetails] }) ); }); it("removes proxy rule from an action", function() { - expect(pass).toChangeAST(proxyGrammar('start = proxy { }'), simpleDetails); + expect(pass).toChangeAST( + proxyGrammar('start = proxy { }'), + defaultOptions, + simpleDetails + ); }); it("removes proxy rule from a sequence", function() { expect(pass).toChangeAST( proxyGrammar('start = proxy "a" "b"'), + defaultOptions, expressionDetails({ elements: [proxiedRefDetails, {}, {}] }) ); expect(pass).toChangeAST( proxyGrammar('start = "a" "b" proxy'), + defaultOptions, expressionDetails({ elements: [{}, {}, proxiedRefDetails] }) ); }); it("removes proxy rule from a labeled", function() { - expect(pass).toChangeAST(proxyGrammar('start = label:proxy'), simpleDetails); + expect(pass).toChangeAST( + proxyGrammar('start = label:proxy'), + defaultOptions, + simpleDetails + ); }); it("removes proxy rule from a text", function() { - expect(pass).toChangeAST(proxyGrammar('start = $proxy'), simpleDetails); + expect(pass).toChangeAST( + proxyGrammar('start = $proxy'), + defaultOptions, + simpleDetails + ); }); it("removes proxy rule from a simple and", function() { - expect(pass).toChangeAST(proxyGrammar('start = &proxy'), simpleDetails); + expect(pass).toChangeAST( + proxyGrammar('start = &proxy'), + defaultOptions, + simpleDetails + ); }); it("removes proxy rule from a simple not", function() { - expect(pass).toChangeAST(proxyGrammar('start = &proxy'), simpleDetails); + expect(pass).toChangeAST( + proxyGrammar('start = &proxy'), + defaultOptions, + simpleDetails + ); }); it("removes proxy rule from an optional", function() { - expect(pass).toChangeAST(proxyGrammar('start = proxy?'), simpleDetails); + expect(pass).toChangeAST( + proxyGrammar('start = proxy?'), + defaultOptions, + simpleDetails + ); }); it("removes proxy rule from a zero or more", function() { - expect(pass).toChangeAST(proxyGrammar('start = proxy*'), simpleDetails); + expect(pass).toChangeAST( + proxyGrammar('start = proxy*'), + defaultOptions, + simpleDetails + ); }); it("removes proxy rule from a one or more", function() { - expect(pass).toChangeAST(proxyGrammar('start = proxy+'), simpleDetails); + expect(pass).toChangeAST( + proxyGrammar('start = proxy+'), + defaultOptions, + simpleDetails + ); }); it("doesn't remove a proxy rule listed in |allowedStartRules|", function() {