You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
1.7 KiB
JavaScript
74 lines
1.7 KiB
JavaScript
"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;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|