"use strict"; const pegjs = require("pegjs"); const { validateOptions, either, required, isString, isPlainObject, allowExtraProperties } = require("validatem"); const fs = require("fs"); const moduleEval = require("eval"); const vm = require("vm"); const asExpression = require("as-expression"); const textParser = require("../text-parser"); module.exports = function createPegParser({ grammar, grammarFile, options }) { validateOptions(arguments, [ { grammar: [ isString ], grammarFile: [ isString ], options: [ isPlainObject ] }, // FIXME: require-either either( allowExtraProperties({ grammar: [ required ] }), allowExtraProperties({ grammarFile: [ required ] }) ) ]); if (grammarFile != null) { // FIXME: cache grammar = fs.readFileSync(grammarFile, "utf8"); } let parserCode = pegjs.generate(grammar, { ... options, output: "source", format: "commonjs" }); let parser = asExpression(() => { if (grammarFile != null) { return moduleEval(parserCode, grammarFile, {}, true); } else { let exports_ = {}; let sandbox = { exports: exports_, module: { exports: exports_, }, require: function () { throw new Error("You cannot use require() when loading a grammar as a string; use the `grammarFile` option instead"); } }; let script = new vm.Script(parserCode.replace(/^\#\!.*/, '')); script.runInNewContext(sandbox); return sandbox.module.exports; } }); return { supportsStreams: false, parse: function (text) { try { return parser.parse(text); } catch (error) { if (error.name === "SyntaxError") { throw textParser.NoResult.chain(error, "Parsing output failed"); } else { throw error; } } } }; };