diff --git a/README.md b/README.md index 0eac3097..32d25ca7 100644 --- a/README.md +++ b/README.md @@ -112,8 +112,8 @@ You can tweak the generated parser with several options: parser object is assigned to when no module loader is detected - `--extra-options ` — additional options (in JSON format, as an object) to pass to `peg.generate` -- `--extra-options-file ` — file with additional options (in JSON - format, as an object) to pass to `peg.generate` +- `-c`, `--extra-options-file ` — file with additional options (in JSON + or commonjs module format, as an object) to pass to `peg.generate` - `--format ` — format of the generated parser: `amd`, `es`, `commonjs`, `globals`, `umd` (default: `commonjs`) - `-o`, `--output ` - file to send output to. Defaults to input file @@ -128,6 +128,28 @@ You can tweak the generated parser with several options: - `-v`, `--version` - output the version number - `-h`, `--help` - display help for command +If you specify options using `-c ` or `--extra-options-file `, you +will need to ensure you are using the correct types. In particular, you may +specify "plugin" as a string, or "plugins" as an array of objects that have a +`use` method. Always use the long (two-dash) form of the option. Options +that contain dashes should be specified in camel case. You may also specify an +"input" field instead of using the command line. + +For example: + +```js +// config.js or config.cjs +module.exports = { + allowedStartRules = ["foo", "bar"], + format: "umd", + exportVar: "foo", + input: "fooGrammar.peggy", + plugins: [require("./plugin.js")], + testFile: "myTestInput.foo", + trace: true +}; +``` + ### JavaScript API In Node.js, require the Peggy parser generator module: diff --git a/bin/peggy.js b/bin/peggy.js index 09e410f3..a734aa1a 100755 --- a/bin/peggy.js +++ b/bin/peggy.js @@ -2237,6 +2237,8 @@ function incrementNodeInspectorPort(args) { const MODULE_FORMATS = ["amd", "commonjs", "es", "globals", "umd"]; const MODULE_FORMATS_WITH_DEPS = ["amd", "commonjs", "es", "umd"]; +const DEFAULT_FORMAT = "COMMON_JS"; +let verbose = false; // Helpers @@ -2245,6 +2247,22 @@ function abort(message) { process.exit(1); } +function abortError(msg, error) { + console.error(msg); + if (typeof error.format === "function") { + abort(error.format([{ + source: testGrammarSource, + text: testText, + }])); + } else { + if (verbose) { + abort(error); + } else { + abort(`Error: ${error.message}`); + } + } +} + function addExtraOptions(options, json) { let extraOptions; @@ -2253,7 +2271,7 @@ function addExtraOptions(options, json) { } catch (e) { if (!(e instanceof SyntaxError)) { throw e; } - abort("Error parsing JSON: " + e.message); + abortError("Error parsing JSON:", e); } if ((extraOptions === null) || (typeof extraOptions !== "object") @@ -2263,12 +2281,20 @@ function addExtraOptions(options, json) { return Object.assign({}, options, extraOptions); } +// Files + +function readStream(inputStream, callback) { + let input = ""; + inputStream.on("data", data => { input += data; }); + inputStream.on("end", () => { callback(input); }); +} + function readFile(name) { let f = null; try { f = fs__default['default'].readFileSync(name, "utf8"); } catch (e) { - abort(`Can't read from file "${name}".`); + abortError(`Can't read from file "${name}".`, e); } return f; } @@ -2276,7 +2302,7 @@ function readFile(name) { // Command line processing const program = new commander.exports.Command(); -const options = program +let options = program .version(peg__default['default'].VERSION, "-v, --version") .arguments("[input_file]") .addOption( @@ -2306,9 +2332,15 @@ const options = program (val, prev) => addExtraOptions(prev, val) ) .option( - "--extra-options-file ", - "file with additional options (in JSON format as an object) to pass to peg.generate", - (val, prev) => addExtraOptions(prev, readFile(val)) + "-c, --extra-options-file ", + "file with additional options (in JSON or commonjs module format as an object) to pass to peg.generate", + (val, prev) => { + if (/\.c?js$/.test(val)) { + return Object.assign({}, prev, require(path__default['default'].resolve(val))); + } else { + return addExtraOptions(prev, readFile(val)); + } + } ) .addOption( new commander.exports.Option( @@ -2316,7 +2348,7 @@ const options = program "format of the generated parser" ) .choices(MODULE_FORMATS) - .default("commonjs") + .default(DEFAULT_FORMAT, '"commonjs"') ) .option("-o, --output ", "output file") .option( @@ -2342,7 +2374,6 @@ const options = program .addOption( new commander.exports.Option("-O, --optimize