Move options handling from passes to |PEG.compiler.compile|

This eliminates some duplicate code.
redux
David Majda 12 years ago
parent 5942988f66
commit d3d4ace153

@ -21,17 +21,22 @@ module.exports = {
* during the generation and some may protrude to the generated parser and * during the generation and some may protrude to the generated parser and
* cause its malfunction. * cause its malfunction.
*/ */
compile: function(ast, options) { compile: function(ast) {
if (options === undefined) { options = {}; } var that = this,
options = arguments.length > 1 ? utils.clone(arguments[1]) : {};
var that = this, utils.defaults(options, {
output = options.output !== undefined ? options.output : "parser"; allowedStartRules: [ast.rules[0].name],
cache: false,
optimize: "speed",
output: "parser"
});
utils.each(this.appliedPassNames, function(passName) { utils.each(this.appliedPassNames, function(passName) {
that.passes[passName](ast, options); that.passes[passName](ast, options);
}); });
switch (output) { switch (options.output) {
case "parser": return eval(ast.code); case "parser": return eval(ast.code);
case "source": return ast.code; case "source": return ast.code;
} }

@ -3,13 +3,6 @@ var utils = require("../../utils"),
/* Generates parser JavaScript code. */ /* Generates parser JavaScript code. */
module.exports = function(ast, options) { 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. */ /* These only indent non-empty lines to avoid trailing whitespace. */
function indent2(code) { return code.replace(/^(.+)$/gm, ' $1'); } function indent2(code) { return code.replace(/^(.+)$/gm, ' $1'); }
function indent4(code) { return code.replace(/^(.+)$/gm, ' $1'); } function indent4(code) { return code.replace(/^(.+)$/gm, ' $1'); }

@ -55,15 +55,12 @@ module.exports = function(ast, options) {
replace(ast, from, to); replace(ast, from, to);
} }
var indices = [], var indices = [];
allowedStartRules = options.allowedStartRules !== undefined
? options.allowedStartRules
: [ast.rules[0].name];
utils.each(ast.rules, function(rule, i) { utils.each(ast.rules, function(rule, i) {
if (isProxyRule(rule)) { if (isProxyRule(rule)) {
replaceRuleRefs(ast, rule.name, rule.expression.name); replaceRuleRefs(ast, rule.name, rule.expression.name);
if (!utils.contains(allowedStartRules, rule.name)) { if (!utils.contains(options.allowedStartRules, rule.name)) {
indices.push(i); indices.push(i);
} }
} }

@ -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 }); simpleDetails = expressionDetails({ expression: proxiedRefDetails });
it("removes proxy rule from a rule", function() { it("removes proxy rule from a rule", function() {
expect(pass).toChangeAST(proxyGrammar('start = proxy'), { expect(pass).toChangeAST(proxyGrammar('start = proxy'), defaultOptions, {
rules: [ rules: [
{ type: "rule", name: "start", expression: proxiedRefDetails }, { type: "rule", name: "start", expression: proxiedRefDetails },
{ type: "rule", name: "proxied" } { type: "rule", name: "proxied" }
@ -29,6 +30,7 @@ describe("compiler pass |removeProxyRules|", function() {
it("removes proxy rule from a named", function() { it("removes proxy rule from a named", function() {
expect(pass).toChangeAST( expect(pass).toChangeAST(
proxyGrammar('start "start" = proxy'), proxyGrammar('start "start" = proxy'),
defaultOptions,
simpleDetails simpleDetails
); );
}); });
@ -36,55 +38,91 @@ describe("compiler pass |removeProxyRules|", function() {
it("removes proxy rule from a choice", function() { it("removes proxy rule from a choice", function() {
expect(pass).toChangeAST( expect(pass).toChangeAST(
proxyGrammar('start = proxy / "a" / "b"'), proxyGrammar('start = proxy / "a" / "b"'),
defaultOptions,
expressionDetails({ alternatives: [proxiedRefDetails, {}, {}] }) expressionDetails({ alternatives: [proxiedRefDetails, {}, {}] })
); );
expect(pass).toChangeAST( expect(pass).toChangeAST(
proxyGrammar('start = "a" / "b" / proxy'), proxyGrammar('start = "a" / "b" / proxy'),
defaultOptions,
expressionDetails({ alternatives: [{}, {}, proxiedRefDetails] }) expressionDetails({ alternatives: [{}, {}, proxiedRefDetails] })
); );
}); });
it("removes proxy rule from an action", function() { 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() { it("removes proxy rule from a sequence", function() {
expect(pass).toChangeAST( expect(pass).toChangeAST(
proxyGrammar('start = proxy "a" "b"'), proxyGrammar('start = proxy "a" "b"'),
defaultOptions,
expressionDetails({ elements: [proxiedRefDetails, {}, {}] }) expressionDetails({ elements: [proxiedRefDetails, {}, {}] })
); );
expect(pass).toChangeAST( expect(pass).toChangeAST(
proxyGrammar('start = "a" "b" proxy'), proxyGrammar('start = "a" "b" proxy'),
defaultOptions,
expressionDetails({ elements: [{}, {}, proxiedRefDetails] }) expressionDetails({ elements: [{}, {}, proxiedRefDetails] })
); );
}); });
it("removes proxy rule from a labeled", function() { 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() { 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() { 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() { 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() { 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() { 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() { 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() { it("doesn't remove a proxy rule listed in |allowedStartRules|", function() {

Loading…
Cancel
Save