UNPKG

syntax-cli-prog

Version:

Syntactic analysis toolkit, language agnostic parsers generator.

233 lines (182 loc) 5.41 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _vm = require('vm'); var _vm2 = _interopRequireDefault(_vm); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var SANDBOX = Object.assign(global, { /** * Matched text of the tokenizer. */ yytext: '', /** * Length of the matched text. */ yyleng: 0, /** * Extra global object lex rules, and other handlers * may use to track any needed state across the handlers. */ yy: {}, /** * Stores different parse callbacks. */ yyparse: { onParseBegin: function onParseBegin() {}, onParseEnd: function onParseEnd() {} }, /** * Creates location object. */ yyloc: function yyloc(start, end) { // Epsilon doesn't produce location. if (!start || !end) { return start || end; } return { startOffset: start.startOffset, endOffset: end.endOffset, startLine: start.startLine, endLine: end.endLine, startColumn: start.startColumn, endColumn: end.endColumn }; }, /** * Result value of production handlers, used as $$. */ __: null, /** * Result node location object. */ __loc: null, /** * To require modules. */ require: require }); /** * Execution context. */ /** * The MIT License (MIT) * Copyright (c) 2015-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com> */ var context = new _vm2.default.createContext(SANDBOX); /** * Evaluation unit for different handlers (of lex rules, productions, etc), * which shares the same global space via sandbox. */ var CodeUnit = { /** * Sets value to bindings. */ setBindings: function setBindings(bindings) { Object.assign(SANDBOX, bindings); }, /** * Evaluates the code. If `shouldRewrite` is `true` (default), * rewrites $1, $2, $$, etc. to _1, _2, __, etc. */ eval: function _eval(code) { var shouldRewrite = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; if (shouldRewrite) { code = this._rewriteParamsInCode(code); } return _vm2.default.runInContext(code, context); }, /** * Creates parameters string for a semantic action. * * Consists of: positioned arguments, named arguments, * and location data. * * Example of using the arguments in a handler: * * $1, $2, $expr, $term, @1, @2 * * Created parameters: _1, _2, _expr, _term, _1loc, _2loc */ createProductionParamsArray: function createProductionParamsArray(_ref) { var production = _ref.production, captureLocations = _ref.captureLocations; if (production.isEpsilon()) { return []; } var symbols = production.getRHS().map(function (symbol) { return symbol.getSymbol(); }); // $1, $2, ... var semanticValues = []; // @1, @2, ... var locations = captureLocations ? [] : null; for (var i = 0; i < symbols.length; i++) { var semanticValue = '_' + (i + 1); semanticValues.push(semanticValue); if (captureLocations) { locations.push(semanticValue + 'loc'); } } var params = captureLocations ? semanticValues.concat(locations) : semanticValues; return params; }, /** * See `createProductionParamsArray`. */ createProductionParams: function createProductionParams(_ref2) { var production = _ref2.production, captureLocations = _ref2.captureLocations; return this.createProductionParamsArray({ production: production, captureLocations: captureLocations }).join(', '); }, /** * Creates default location prologue to semantic action. Begin is * taken from first symbol on RHS, the end -- from the last one. * * @$.startOffset = @1.startOffset * @$.endOffset = @1.endOffset * ... */ createLocationPrologue: function createLocationPrologue(production) { if (production.isEpsilon()) { return '__loc = null;'; } var start = 1; var end = production.getRHS().length; return '__loc = yyloc(_' + start + 'loc, _' + end + 'loc);'; }, /** * Creates a handler for a production. Attaches default * location prologue (user code can override it). */ createProductionHandler: function createProductionHandler(_ref3) { var production = _ref3.production, captureLocations = _ref3.captureLocations; var params = this.createProductionParams({ production: production, captureLocations: captureLocations }); var locationPrologue = captureLocations ? this.createLocationPrologue(production) : ''; var action = production.getRawSemanticAction(); return this.createHandler(params, locationPrologue + action); }, /** * Rewrites $1, @1, $name to _1, _1loc, _name */ _rewriteParamsInCode: function _rewriteParamsInCode(code) { return code.replace(/\$(\d+)/g, '_$1').replace(/@(\d+)/g, '_$1loc').replace(/\$\$/g, '__').replace(/@\$/g, '__loc'); }, /** * Creates a handler function with code, and parameters. */ createHandler: function createHandler(parameters, code) { return this.eval('(function(' + parameters + ') { ' + code + ' })'); }, /** * Returns evaluation sandbox. */ getSandbox: function getSandbox() { return SANDBOX; } }; exports.default = CodeUnit;