UMD parsers: Allow specifying parser dependencies

Introduce two ways of specifying parser dependencies: the "dependencies"
option of PEG.buildParser and the -d/--dependency CLI option. Specified
dependencies are translated into AMD dependencies and Node.js's
"require" calls when generating an UMD parser.

Part of work on #362.
redux
David Majda 8 years ago
parent fe6ce38d08
commit 810567d865

@ -120,6 +120,9 @@ object to `PEG.buildParser`. The following options are supported:
`false`)
* `allowedStartRules` — rules the parser will be allowed to start parsing from
(default: the first rule in the grammar)
* `dependencies` — parser dependencies, the value is an object which maps
variables used to access the dependencies in the parser to module IDs used
to load them; valid only when `format` is set to `"umd"` (default: `{}`)
* `exportVar` — name of a global variable into which the parser object is
assigned to when no module loader is detected; valid only when `format` is
set to `"umd"` (default: `null`)

@ -28,6 +28,8 @@ function printHelp() {
console.log(" -e, --export-var <variable> name of a global variable into which the");
console.log(" parser object is assigned to when no module");
console.log(" loader is detected (default: \"\")");
console.log(" -d, --dependency <dependency> use specified dependency (can be specified");
console.log(" multiple times)");
console.log(" --cache make generated parser cache results");
console.log(" --allowed-start-rules <rules> comma-separated list of rules the generated");
console.log(" parser will be allowed to start parsing");
@ -111,13 +113,14 @@ function readStream(inputStream, callback) {
/* Main */
var options = {
cache: false,
output: "source",
format: "umd",
exportVar: null,
optimize: "speed",
trace: false,
plugins: []
cache: false,
output: "source",
format: "umd",
exportVar: null,
dependencies: {},
optimize: "speed",
trace: false,
plugins: []
};
while (args.length > 0 && isOption(args[0])) {
@ -131,6 +134,20 @@ while (args.length > 0 && isOption(args[0])) {
options.exportVar = args[0];
break;
case "-d":
case "--dependency":
nextArg();
if (args.length === 0) {
abort("Missing parameter of the -d/--dependency option.");
}
if (args[0].indexOf(":") !== -1) {
var parts = args[0].split(":");
options.dependencies[parts[0]] = parts[1];
} else {
options.dependencies[args[0]] = args[0];
}
break;
case "--cache":
options.cache = true;
break;

@ -51,6 +51,7 @@ var compiler = {
optimize: "speed",
output: "parser",
format: "bare",
dependencies: {},
exportVar: null
});

@ -1,9 +1,10 @@
"use strict";
var arrays = require("../../utils/arrays"),
asts = require("../asts"),
op = require("../opcodes"),
js = require("../js");
var arrays = require("../../utils/arrays"),
objects = require("../../utils/objects"),
asts = require("../asts"),
op = require("../opcodes"),
js = require("../js");
/* Generates parser JavaScript code. */
function generateJS(ast, options) {
@ -1184,14 +1185,27 @@ function generateJS(ast, options) {
},
umd: function() {
var parts = [];
var parts = [],
dependencyIds = objects.values(options.dependencies),
dependencyVars = objects.keys(options.dependencies),
dependencies = '['
+ arrays.map(
dependencyIds,
function(id) { return '"' + js.stringEscape(id) + '"'; }
).join(', ')
+ ']',
requires = arrays.map(
dependencyIds,
function(id) { return 'require("' + js.stringEscape(id) + '")'; }
).join(', '),
params = dependencyVars.join(', ');
parts.push([
'(function(root, factory) {',
' if (typeof define === "function" && define.amd) {',
' define([], factory);',
' define(' + dependencies + ', factory);',
' } else if (typeof module === "object" && module.exports) {',
' module.exports = factory();'
' module.exports = factory(' + requires + ');'
].join('\n'));
if (options.exportVar !== null) {
@ -1203,7 +1217,7 @@ function generateJS(ast, options) {
parts.push([
' }',
'})(this, function() {'
'})(this, function(' + params + ') {'
].join('\n'));
parts.push(indent2(generateIntro()));

@ -200,9 +200,9 @@ describe("PEG.js API", function() {
});
/*
* The |format| and |exportVars| options are not tested becasue there is no
* meaningful way to thest their effects without turning this into an
* integration test.
* The |format|, |exportVars|, and |dependencies| options are not tested
* becasue there is no meaningful way to thest their effects without turning
* this into an integration test.
*/
/* The |plugins| option is tested in plugin API specs. */

Loading…
Cancel
Save