UNPKG

hyperformula-dc

Version:

HyperFormula is a JavaScript engine for efficient processing of spreadsheet-like data and formulas

1,048 lines (827 loc) 41.4 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } require("core-js/modules/es.reflect.construct.js"); require("core-js/modules/es.reflect.get.js"); require("core-js/modules/es.object.get-own-property-descriptor.js"); require("core-js/modules/es.symbol.js"); require("core-js/modules/es.symbol.description.js"); require("core-js/modules/es.object.to-string.js"); require("core-js/modules/es.symbol.iterator.js"); require("core-js/modules/es.array.iterator.js"); require("core-js/modules/es.string.iterator.js"); require("core-js/modules/web.dom-collections.iterator.js"); require("core-js/modules/es.function.name.js"); require("core-js/modules/es.array.from.js"); exports.__esModule = true; exports.FormulaLexer = exports.FormulaParser = void 0; require("core-js/modules/es.array.slice.js"); require("core-js/modules/es.regexp.exec.js"); require("core-js/modules/es.string.split.js"); require("core-js/modules/es.array.concat.js"); require("core-js/modules/es.string.replace.js"); require("core-js/modules/es.number.constructor.js"); require("core-js/modules/es.array.map.js"); require("core-js/modules/es.number.is-integer.js"); require("core-js/modules/es.object.get-prototype-of.js"); var _chevrotain = require("chevrotain"); var _Cell = require("../Cell"); var _errorMessage = require("../error-message"); var _addressRepresentationConverters = require("./addressRepresentationConverters"); var _Ast = require("./Ast"); var _CellAddress = require("./CellAddress"); var _LexerConfig = require("./LexerConfig"); function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } /** * LL(k) formula parser described using Chevrotain DSL * * It is equivalent to the grammar below: * * F -> '=' E <br/> * B -> K < B | K >= B ... | K <br/> * K -> E & K | E <br/> * E -> M + E | M - E | M <br/> * M -> W * M | W / M | W <br/> * W -> C * W | C <br/> * C -> N | R | O | A | P | num <br/> * N -> '(' E ')' <br/> * R -> A:OFFSET(..) | A:A <br/> * O -> OFFSET(..) | OFFSET(..):A | OFFSET(..):OFFSET(..) <br/> * A -> A1 | $A1 | A$1 | $A$1 <br/> * P -> SUM(..) <br/> */ var FormulaParser = /*#__PURE__*/function (_EmbeddedActionsParse) { _inherits(FormulaParser, _EmbeddedActionsParse); var _super = _createSuper(FormulaParser); function FormulaParser(lexerConfig, sheetMapping) { var _this; _classCallCheck(this, FormulaParser); _this = _super.call(this, lexerConfig.allTokens, { outputCst: false, maxLookahead: 7 }); /** * Entry rule */ _this.formula = _this.RULE('formula', function () { _this.CONSUME(_LexerConfig.EqualsOp); return _this.SUBRULE(_this.booleanExpression); }); /** * Rule for boolean expression (e.g. 1 <= A1) */ _this.booleanExpression = _this.RULE('booleanExpression', function () { var lhs = _this.SUBRULE(_this.concatenateExpression); _this.MANY(function () { var op = _this.CONSUME(_LexerConfig.BooleanOp); var rhs = _this.SUBRULE2(_this.concatenateExpression); if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.EqualsOp)) { lhs = (0, _Ast.buildEqualsOpAst)(lhs, rhs, op.leadingWhitespace); } else if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.NotEqualOp)) { lhs = (0, _Ast.buildNotEqualOpAst)(lhs, rhs, op.leadingWhitespace); } else if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.GreaterThanOp)) { lhs = (0, _Ast.buildGreaterThanOpAst)(lhs, rhs, op.leadingWhitespace); } else if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.LessThanOp)) { lhs = (0, _Ast.buildLessThanOpAst)(lhs, rhs, op.leadingWhitespace); } else if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.GreaterThanOrEqualOp)) { lhs = (0, _Ast.buildGreaterThanOrEqualOpAst)(lhs, rhs, op.leadingWhitespace); } else if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.LessThanOrEqualOp)) { lhs = (0, _Ast.buildLessThanOrEqualOpAst)(lhs, rhs, op.leadingWhitespace); } else { _this.ACTION(function () { throw Error('Operator not supported'); }); } }); return lhs; }); _this.booleanExpressionOrEmpty = _this.RULE('booleanExpressionOrEmpty', function () { return _this.OR([{ ALT: function ALT() { return _this.SUBRULE(_this.booleanExpression); } }, { ALT: (0, _chevrotain.EMPTY_ALT)((0, _Ast.buildEmptyArgAst)()) }]); }); /** * Rule for concatenation operator expression (e.g. "=" & A1) */ _this.concatenateExpression = _this.RULE('concatenateExpression', function () { var lhs = _this.SUBRULE(_this.additionExpression); _this.MANY(function () { var op = _this.CONSUME(_LexerConfig.ConcatenateOp); var rhs = _this.SUBRULE2(_this.additionExpression); lhs = (0, _Ast.buildConcatenateOpAst)(lhs, rhs, op.leadingWhitespace); }); return lhs; }); /** * Rule for addition category operators (e.g. 1 + A1, 1 - A1) */ _this.additionExpression = _this.RULE('additionExpression', function () { var lhs = _this.SUBRULE(_this.multiplicationExpression); _this.MANY(function () { var op = _this.CONSUME(_LexerConfig.AdditionOp); var rhs = _this.SUBRULE2(_this.multiplicationExpression); if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.PlusOp)) { lhs = (0, _Ast.buildPlusOpAst)(lhs, rhs, op.leadingWhitespace); } else if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.MinusOp)) { lhs = (0, _Ast.buildMinusOpAst)(lhs, rhs, op.leadingWhitespace); } else { _this.ACTION(function () { throw Error('Operator not supported'); }); } }); return lhs; }); /** * Rule for multiplication category operators (e.g. 1 * A1, 1 / A1) */ _this.multiplicationExpression = _this.RULE('multiplicationExpression', function () { var lhs = _this.SUBRULE(_this.powerExpression); _this.MANY(function () { var op = _this.CONSUME(_LexerConfig.MultiplicationOp); var rhs = _this.SUBRULE2(_this.powerExpression); if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.TimesOp)) { lhs = (0, _Ast.buildTimesOpAst)(lhs, rhs, op.leadingWhitespace); } else if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.DivOp)) { lhs = (0, _Ast.buildDivOpAst)(lhs, rhs, op.leadingWhitespace); } else { _this.ACTION(function () { throw Error('Operator not supported'); }); } }); return lhs; }); /** * Rule for power expression */ _this.powerExpression = _this.RULE('powerExpression', function () { var lhs = _this.SUBRULE(_this.atomicExpression); _this.MANY(function () { var op = _this.CONSUME(_LexerConfig.PowerOp); var rhs = _this.SUBRULE2(_this.atomicExpression); if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.PowerOp)) { lhs = (0, _Ast.buildPowerOpAst)(lhs, rhs, op.leadingWhitespace); } else { _this.ACTION(function () { throw Error('Operator not supported'); }); } }); return lhs; }); /** * Rule for atomic expressions, which is positive atomic expression or negation of it */ _this.atomicExpression = _this.RULE('atomicExpression', function () { return _this.OR([{ ALT: function ALT() { var op = _this.CONSUME(_LexerConfig.AdditionOp); var value = _this.SUBRULE(_this.atomicExpression); if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.PlusOp)) { return (0, _Ast.buildPlusUnaryOpAst)(value, op.leadingWhitespace); } else if ((0, _chevrotain.tokenMatcher)(op, _LexerConfig.MinusOp)) { return (0, _Ast.buildMinusUnaryOpAst)(value, op.leadingWhitespace); } else { _this.customParsingError = (0, _Ast.parsingError)(_Ast.ParsingErrorType.ParserError, 'Mismatched token type'); return _this.customParsingError; } } }, { ALT: function ALT() { return _this.SUBRULE2(_this.rightUnaryOpAtomicExpression); } }]); }); _this.rightUnaryOpAtomicExpression = _this.RULE('rightUnaryOpAtomicExpression', function () { var positiveAtomicExpression = _this.SUBRULE(_this.positiveAtomicExpression); var percentage = _this.OPTION(function () { return _this.CONSUME(_LexerConfig.PercentOp); }); if (percentage) { return (0, _Ast.buildPercentOpAst)(positiveAtomicExpression, percentage.leadingWhitespace); } return positiveAtomicExpression; }); /** * Rule for positive atomic expressions */ _this.positiveAtomicExpression = _this.RULE('positiveAtomicExpression', function () { var _a; return _this.OR((_a = _this.atomicExpCache) !== null && _a !== void 0 ? _a : _this.atomicExpCache = [{ ALT: function ALT() { return _this.SUBRULE(_this.arrayExpression); } }, { ALT: function ALT() { return _this.SUBRULE(_this.cellRangeExpression); } }, { ALT: function ALT() { return _this.SUBRULE(_this.columnRangeExpression); } }, { ALT: function ALT() { return _this.SUBRULE(_this.rowRangeExpression); } }, { ALT: function ALT() { return _this.SUBRULE(_this.offsetExpression); } }, { ALT: function ALT() { return _this.SUBRULE(_this.cellReference); } }, { ALT: function ALT() { return _this.SUBRULE(_this.procedureExpression); } }, { ALT: function ALT() { return _this.SUBRULE(_this.namedExpressionExpression); } }, { ALT: function ALT() { var number = _this.CONSUME(_this.lexerConfig.NumberLiteral); return (0, _Ast.buildNumberAst)(_this.numericStringToNumber(number.image), number.leadingWhitespace); } }, { ALT: function ALT() { var str = _this.CONSUME(_LexerConfig.StringLiteral); return (0, _Ast.buildStringAst)(str); } }, { ALT: function ALT() { var token = _this.CONSUME(_LexerConfig.ErrorLiteral); var errString = token.image.toUpperCase(); var errorType = _this.lexerConfig.errorMapping[errString]; if (errorType) { return (0, _Ast.buildCellErrorAst)(new _Cell.CellError(errorType), token.leadingWhitespace); } else { return _this.parsingError(_Ast.ParsingErrorType.ParserError, 'Unknown error literal'); } } }]); }); /** * Rule for procedure expressions: SUM(1,A1) */ _this.procedureExpression = _this.RULE('procedureExpression', function () { var _a; var procedureNameToken = _this.CONSUME(_LexerConfig.ProcedureName); var procedureName = procedureNameToken.image.toUpperCase().slice(0, -1); var canonicalProcedureName = (_a = _this.lexerConfig.functionMapping[procedureName]) !== null && _a !== void 0 ? _a : procedureName; var args = []; var argument = _this.SUBRULE(_this.booleanExpressionOrEmpty); _this.MANY(function () { var _a; var separator = _this.CONSUME(_this.lexerConfig.ArgSeparator); if (argument.type === _Ast.AstNodeType.EMPTY) { argument.leadingWhitespace = (_a = separator.leadingWhitespace) === null || _a === void 0 ? void 0 : _a.image; } args.push(argument); argument = _this.SUBRULE2(_this.booleanExpressionOrEmpty); }); args.push(argument); if (args.length === 1 && args[0].type === _Ast.AstNodeType.EMPTY) { args.length = 0; } var rParenToken = _this.CONSUME(_LexerConfig.RParen); return (0, _Ast.buildProcedureAst)(canonicalProcedureName, args, procedureNameToken.leadingWhitespace, rParenToken.leadingWhitespace); }); _this.namedExpressionExpression = _this.RULE('namedExpressionExpression', function () { var name = _this.CONSUME(_LexerConfig.NamedExpression); return (0, _Ast.buildNamedExpressionAst)(name.image, name.leadingWhitespace); }); /** * Rule for expressions that start with OFFSET() function * * OFFSET() function can occur as cell reference or part of cell range. * In order to preserve LL(k) properties, expressions that starts with OFFSET() functions needs to have separate rule. * * Proper {@link Ast} node type is built depending on the presence of {@link RangeSeparator} */ _this.offsetExpression = _this.RULE('offsetExpression', function () { var offsetProcedure = _this.SUBRULE(_this.offsetProcedureExpression); var end; _this.OPTION(function () { _this.CONSUME(_LexerConfig.RangeSeparator); if (offsetProcedure.type === _Ast.AstNodeType.CELL_RANGE) { end = _this.parsingError(_Ast.ParsingErrorType.RangeOffsetNotAllowed, 'Range offset not allowed here'); } else { end = _this.SUBRULE(_this.endOfRangeWithOffsetStartExpression, { ARGS: [offsetProcedure] }); } }); if (end !== undefined) { return end; } return offsetProcedure; }); /** * Rule for OFFSET() function expression */ _this.offsetProcedureExpression = _this.RULE('offsetProcedureExpression', function () { var args = []; _this.CONSUME(_this.lexerConfig.OffsetProcedureName); _this.CONSUME(_LexerConfig.LParen); _this.MANY_SEP({ SEP: _this.lexerConfig.ArgSeparator, DEF: function DEF() { args.push(_this.SUBRULE(_this.booleanExpression)); } }); _this.CONSUME(_LexerConfig.RParen); return _this.handleOffsetHeuristic(args); }); /** * Rule for cell ranges (e.g. A1:B$3, A1:OFFSET()) */ _this.cellRangeExpression = _this.RULE('cellRangeExpression', function () { var start = _this.CONSUME(_LexerConfig.CellReference); _this.CONSUME2(_LexerConfig.RangeSeparator); return _this.SUBRULE(_this.endOfRangeExpression, { ARGS: [start] }); }); /** * Rule for column range, e.g. A:B, Sheet1!A:B, Sheet1!A:Sheet1!B */ _this.columnRangeExpression = _this.RULE('columnRangeExpression', function () { var range = _this.CONSUME(_LexerConfig.ColumnRange); var _range$image$split = range.image.split(':'), _range$image$split2 = _slicedToArray(_range$image$split, 2), startImage = _range$image$split2[0], endImage = _range$image$split2[1]; var start = _this.ACTION(function () { return (0, _addressRepresentationConverters.columnAddressFromString)(_this.sheetMapping, startImage, _this.formulaAddress); }); var end = _this.ACTION(function () { return (0, _addressRepresentationConverters.columnAddressFromString)(_this.sheetMapping, endImage, _this.formulaAddress); }); if (start === undefined || end === undefined) { return (0, _Ast.buildCellErrorAst)(new _Cell.CellError(_Cell.ErrorType.REF)); } if (start.exceedsSheetSizeLimits(_this.lexerConfig.maxColumns) || end.exceedsSheetSizeLimits(_this.lexerConfig.maxColumns)) { return (0, _Ast.buildErrorWithRawInputAst)(range.image, new _Cell.CellError(_Cell.ErrorType.NAME), range.leadingWhitespace); } if (start.sheet === undefined && end.sheet !== undefined) { return _this.parsingError(_Ast.ParsingErrorType.ParserError, 'Malformed range expression'); } var sheetReferenceType = _this.rangeSheetReferenceType(start.sheet, end.sheet); if (start.sheet !== undefined && end.sheet === undefined) { end = end.withAbsoluteSheet(start.sheet); } return (0, _Ast.buildColumnRangeAst)(start, end, sheetReferenceType, range.leadingWhitespace); }); /** * Rule for row range, e.g. 1:2, Sheet1!1:2, Sheet1!1:Sheet1!2 */ _this.rowRangeExpression = _this.RULE('rowRangeExpression', function () { var range = _this.CONSUME(_LexerConfig.RowRange); var _range$image$split3 = range.image.split(':'), _range$image$split4 = _slicedToArray(_range$image$split3, 2), startImage = _range$image$split4[0], endImage = _range$image$split4[1]; var start = _this.ACTION(function () { return (0, _addressRepresentationConverters.rowAddressFromString)(_this.sheetMapping, startImage, _this.formulaAddress); }); var end = _this.ACTION(function () { return (0, _addressRepresentationConverters.rowAddressFromString)(_this.sheetMapping, endImage, _this.formulaAddress); }); if (start === undefined || end === undefined) { return (0, _Ast.buildCellErrorAst)(new _Cell.CellError(_Cell.ErrorType.REF)); } if (start.exceedsSheetSizeLimits(_this.lexerConfig.maxRows) || end.exceedsSheetSizeLimits(_this.lexerConfig.maxRows)) { return (0, _Ast.buildErrorWithRawInputAst)(range.image, new _Cell.CellError(_Cell.ErrorType.NAME), range.leadingWhitespace); } if (start.sheet === undefined && end.sheet !== undefined) { return _this.parsingError(_Ast.ParsingErrorType.ParserError, 'Malformed range expression'); } var sheetReferenceType = _this.rangeSheetReferenceType(start.sheet, end.sheet); if (start.sheet !== undefined && end.sheet === undefined) { end = end.withAbsoluteSheet(start.sheet); } return (0, _Ast.buildRowRangeAst)(start, end, sheetReferenceType, range.leadingWhitespace); }); /** * Rule for cell reference expression (e.g. A1, $A1, A$1, $A$1, $Sheet42!A$17) */ _this.cellReference = _this.RULE('cellReference', function () { var cell = _this.CONSUME(_LexerConfig.CellReference); var address = _this.ACTION(function () { return (0, _addressRepresentationConverters.cellAddressFromString)(_this.sheetMapping, cell.image, _this.formulaAddress); }); if (address === undefined) { return (0, _Ast.buildErrorWithRawInputAst)(cell.image, new _Cell.CellError(_Cell.ErrorType.REF), cell.leadingWhitespace); } else if (address.exceedsSheetSizeLimits(_this.lexerConfig.maxColumns, _this.lexerConfig.maxRows)) { return (0, _Ast.buildErrorWithRawInputAst)(cell.image, new _Cell.CellError(_Cell.ErrorType.NAME), cell.leadingWhitespace); } else { return (0, _Ast.buildCellReferenceAst)(address, cell.leadingWhitespace); } }); /** * Rule for end of range expression * * End of range may be a cell reference or OFFSET() function call */ _this.endOfRangeExpression = _this.RULE('endOfRangeExpression', function (start) { return _this.OR([{ ALT: function ALT() { return _this.SUBRULE(_this.endRangeReference, { ARGS: [start] }); } }, { ALT: function ALT() { var _a; var offsetProcedure = _this.SUBRULE(_this.offsetProcedureExpression); var startAddress = _this.ACTION(function () { return (0, _addressRepresentationConverters.cellAddressFromString)(_this.sheetMapping, start.image, _this.formulaAddress); }); if (startAddress === undefined) { return (0, _Ast.buildCellErrorAst)(new _Cell.CellError(_Cell.ErrorType.REF)); } if (offsetProcedure.type === _Ast.AstNodeType.CELL_REFERENCE) { var end = offsetProcedure.reference; var sheetReferenceType = _Ast.RangeSheetReferenceType.RELATIVE; if (startAddress.sheet !== undefined) { sheetReferenceType = _Ast.RangeSheetReferenceType.START_ABSOLUTE; end = end.withAbsoluteSheet(startAddress.sheet); } return (0, _Ast.buildCellRangeAst)(startAddress, end, sheetReferenceType, (_a = start.leadingWhitespace) === null || _a === void 0 ? void 0 : _a.image); } else { return _this.parsingError(_Ast.ParsingErrorType.RangeOffsetNotAllowed, 'Range offset not allowed here'); } } }]); }); /** * Rule for end of range expression * * End of range may be a cell reference or OFFSET() function call */ _this.endOfRangeWithOffsetStartExpression = _this.RULE('endOfRangeWithOffsetStartExpression', function (start) { return _this.OR([{ ALT: function ALT() { return _this.SUBRULE(_this.endRangeWithOffsetStartReference, { ARGS: [start] }); } }, { ALT: function ALT() { var offsetProcedure = _this.SUBRULE(_this.offsetProcedureExpression); if (offsetProcedure.type === _Ast.AstNodeType.CELL_REFERENCE) { var end = offsetProcedure.reference; var sheetReferenceType = _Ast.RangeSheetReferenceType.RELATIVE; if (start.reference.sheet !== undefined) { sheetReferenceType = _Ast.RangeSheetReferenceType.START_ABSOLUTE; end = end.withAbsoluteSheet(start.reference.sheet); } return (0, _Ast.buildCellRangeAst)(start.reference, end, sheetReferenceType, start.leadingWhitespace); } else { return _this.parsingError(_Ast.ParsingErrorType.RangeOffsetNotAllowed, 'Range offset not allowed here'); } } }]); }); /** * Rule for end range reference expression with additional checks considering range start */ _this.endRangeReference = _this.RULE('endRangeReference', function (start) { var _a; var end = _this.CONSUME(_LexerConfig.CellReference); var startAddress = _this.ACTION(function () { return (0, _addressRepresentationConverters.cellAddressFromString)(_this.sheetMapping, start.image, _this.formulaAddress); }); var endAddress = _this.ACTION(function () { return (0, _addressRepresentationConverters.cellAddressFromString)(_this.sheetMapping, end.image, _this.formulaAddress); }); if (startAddress === undefined || endAddress === undefined) { return _this.ACTION(function () { return (0, _Ast.buildErrorWithRawInputAst)("".concat(start.image, ":").concat(end.image), new _Cell.CellError(_Cell.ErrorType.REF), start.leadingWhitespace); }); } else if (startAddress.exceedsSheetSizeLimits(_this.lexerConfig.maxColumns, _this.lexerConfig.maxRows) || endAddress.exceedsSheetSizeLimits(_this.lexerConfig.maxColumns, _this.lexerConfig.maxRows)) { return _this.ACTION(function () { return (0, _Ast.buildErrorWithRawInputAst)("".concat(start.image, ":").concat(end.image), new _Cell.CellError(_Cell.ErrorType.NAME), start.leadingWhitespace); }); } return _this.buildCellRange(startAddress, endAddress, (_a = start.leadingWhitespace) === null || _a === void 0 ? void 0 : _a.image); }); /** * Rule for end range reference expression starting with offset procedure with additional checks considering range start */ _this.endRangeWithOffsetStartReference = _this.RULE('endRangeWithOffsetStartReference', function (start) { var end = _this.CONSUME(_LexerConfig.CellReference); var endAddress = _this.ACTION(function () { return (0, _addressRepresentationConverters.cellAddressFromString)(_this.sheetMapping, end.image, _this.formulaAddress); }); if (endAddress === undefined) { return _this.ACTION(function () { return (0, _Ast.buildCellErrorAst)(new _Cell.CellError(_Cell.ErrorType.REF)); }); } return _this.buildCellRange(start.reference, endAddress, start.leadingWhitespace); }); _this.arrayExpression = _this.RULE('arrayExpression', function () { return _this.OR([{ ALT: function ALT() { var ltoken = _this.CONSUME(_LexerConfig.ArrayLParen); var ret = _this.SUBRULE(_this.insideArrayExpression); var rtoken = _this.CONSUME(_LexerConfig.ArrayRParen); return (0, _Ast.buildArrayAst)(ret.args, ltoken.leadingWhitespace, rtoken.leadingWhitespace); } }, { ALT: function ALT() { return _this.SUBRULE(_this.parenthesisExpression); } }]); }); _this.insideArrayExpression = _this.RULE('insideArrayExpression', function () { var ret = [[]]; ret[ret.length - 1].push(_this.SUBRULE(_this.booleanExpression)); _this.MANY(function () { _this.OR([{ ALT: function ALT() { _this.CONSUME(_this.lexerConfig.ArrayColSeparator); ret[ret.length - 1].push(_this.SUBRULE2(_this.booleanExpression)); } }, { ALT: function ALT() { _this.CONSUME(_this.lexerConfig.ArrayRowSeparator); ret.push([]); ret[ret.length - 1].push(_this.SUBRULE3(_this.booleanExpression)); } }]); }); return (0, _Ast.buildArrayAst)(ret); }); /** * Rule for parenthesis expression */ _this.parenthesisExpression = _this.RULE('parenthesisExpression', function () { var lParenToken = _this.CONSUME(_LexerConfig.LParen); var expression = _this.SUBRULE(_this.booleanExpression); var rParenToken = _this.CONSUME(_LexerConfig.RParen); return (0, _Ast.buildParenthesisAst)(expression, lParenToken.leadingWhitespace, rParenToken.leadingWhitespace); }); _this.numericStringToNumber = function (input) { var normalized = input.replace(_this.lexerConfig.decimalSeparator, '.'); return Number(normalized); }; _this.lexerConfig = lexerConfig; _this.sheetMapping = sheetMapping; _this.formulaAddress = (0, _Cell.simpleCellAddress)(0, 0, 0); _this.performSelfAnalysis(); return _this; } /** * Parses tokenized formula and builds abstract syntax tree * * @param tokens - tokenized formula * @param formulaAddress - address of the cell in which formula is located */ _createClass(FormulaParser, [{ key: "parseFromTokens", value: function parseFromTokens(tokens, formulaAddress) { this.input = tokens; var ast = this.formulaWithContext(formulaAddress); var errors = []; if (this.customParsingError) { errors.push(this.customParsingError); } errors = errors.concat(this.errors.map(function (e) { return { type: _Ast.ParsingErrorType.ParserError, message: e.message }; })); if (errors.length > 0) { ast = (0, _Ast.buildParsingErrorAst)(); } return { ast: ast, errors: errors }; } /** * Entry rule wrapper that sets formula address * * @param address - address of the cell in which formula is located */ }, { key: "formulaWithContext", value: function formulaWithContext(address) { this.formulaAddress = address; return this.formula(); } }, { key: "reset", value: function reset() { _get(_getPrototypeOf(FormulaParser.prototype), "reset", this).call(this); this.customParsingError = undefined; } }, { key: "buildCellRange", value: function buildCellRange(startAddress, endAddress, leadingWhitespace) { if (startAddress.sheet === undefined && endAddress.sheet !== undefined) { return this.parsingError(_Ast.ParsingErrorType.ParserError, 'Malformed range expression'); } var sheetReferenceType = this.rangeSheetReferenceType(startAddress.sheet, endAddress.sheet); if (startAddress.sheet !== undefined && endAddress.sheet === undefined) { endAddress = endAddress.withAbsoluteSheet(startAddress.sheet); } return (0, _Ast.buildCellRangeAst)(startAddress, endAddress, sheetReferenceType, leadingWhitespace); } /** * Returns {@link CellReferenceAst} or {@link CellRangeAst} based on OFFSET function arguments * * @param args - OFFSET function arguments */ }, { key: "handleOffsetHeuristic", value: function handleOffsetHeuristic(args) { var cellArg = args[0]; if (cellArg.type !== _Ast.AstNodeType.CELL_REFERENCE) { return this.parsingError(_Ast.ParsingErrorType.StaticOffsetError, 'First argument to OFFSET is not a reference'); } var rowsArg = args[1]; var rowShift; if (rowsArg.type === _Ast.AstNodeType.NUMBER && Number.isInteger(rowsArg.value)) { rowShift = rowsArg.value; } else if (rowsArg.type === _Ast.AstNodeType.PLUS_UNARY_OP && rowsArg.value.type === _Ast.AstNodeType.NUMBER && Number.isInteger(rowsArg.value.value)) { rowShift = rowsArg.value.value; } else if (rowsArg.type === _Ast.AstNodeType.MINUS_UNARY_OP && rowsArg.value.type === _Ast.AstNodeType.NUMBER && Number.isInteger(rowsArg.value.value)) { rowShift = -rowsArg.value.value; } else { return this.parsingError(_Ast.ParsingErrorType.StaticOffsetError, 'Second argument to OFFSET is not a static number'); } var columnsArg = args[2]; var colShift; if (columnsArg.type === _Ast.AstNodeType.NUMBER && Number.isInteger(columnsArg.value)) { colShift = columnsArg.value; } else if (columnsArg.type === _Ast.AstNodeType.PLUS_UNARY_OP && columnsArg.value.type === _Ast.AstNodeType.NUMBER && Number.isInteger(columnsArg.value.value)) { colShift = columnsArg.value.value; } else if (columnsArg.type === _Ast.AstNodeType.MINUS_UNARY_OP && columnsArg.value.type === _Ast.AstNodeType.NUMBER && Number.isInteger(columnsArg.value.value)) { colShift = -columnsArg.value.value; } else { return this.parsingError(_Ast.ParsingErrorType.StaticOffsetError, 'Third argument to OFFSET is not a static number'); } var heightArg = args[3]; var height; if (heightArg === undefined) { height = 1; } else if (heightArg.type === _Ast.AstNodeType.NUMBER) { height = heightArg.value; if (height < 1) { return this.parsingError(_Ast.ParsingErrorType.StaticOffsetError, 'Fourth argument to OFFSET is too small number'); } else if (!Number.isInteger(height)) { return this.parsingError(_Ast.ParsingErrorType.StaticOffsetError, 'Fourth argument to OFFSET is not integer'); } } else { return this.parsingError(_Ast.ParsingErrorType.StaticOffsetError, 'Fourth argument to OFFSET is not a static number'); } var widthArg = args[4]; var width; if (widthArg === undefined) { width = 1; } else if (widthArg.type === _Ast.AstNodeType.NUMBER) { width = widthArg.value; if (width < 1) { return this.parsingError(_Ast.ParsingErrorType.StaticOffsetError, 'Fifth argument to OFFSET is too small number'); } else if (!Number.isInteger(width)) { return this.parsingError(_Ast.ParsingErrorType.StaticOffsetError, 'Fifth argument to OFFSET is not integer'); } } else { return this.parsingError(_Ast.ParsingErrorType.StaticOffsetError, 'Fifth argument to OFFSET is not a static number'); } var topLeftCorner = new _CellAddress.CellAddress(cellArg.reference.col + colShift, cellArg.reference.row + rowShift, cellArg.reference.type); var absoluteCol = topLeftCorner.col; var absoluteRow = topLeftCorner.row; if (cellArg.reference.type === _CellAddress.CellReferenceType.CELL_REFERENCE_RELATIVE || cellArg.reference.type === _CellAddress.CellReferenceType.CELL_REFERENCE_ABSOLUTE_COL) { absoluteRow = absoluteRow + this.formulaAddress.row; } if (cellArg.reference.type === _CellAddress.CellReferenceType.CELL_REFERENCE_RELATIVE || cellArg.reference.type === _CellAddress.CellReferenceType.CELL_REFERENCE_ABSOLUTE_ROW) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion absoluteCol = absoluteCol + this.formulaAddress.col; } if (absoluteCol < 0 || absoluteRow < 0) { return (0, _Ast.buildCellErrorAst)(new _Cell.CellError(_Cell.ErrorType.REF, _errorMessage.ErrorMessage.OutOfSheet)); } if (width === 1 && height === 1) { return (0, _Ast.buildCellReferenceAst)(topLeftCorner); } else { var bottomRightCorner = new _CellAddress.CellAddress(topLeftCorner.col + width - 1, topLeftCorner.row + height - 1, topLeftCorner.type); return (0, _Ast.buildCellRangeAst)(topLeftCorner, bottomRightCorner, _Ast.RangeSheetReferenceType.RELATIVE); } } }, { key: "parsingError", value: function parsingError(type, message) { this.customParsingError = (0, _Ast.parsingError)(type, message); return (0, _Ast.buildParsingErrorAst)(); } }, { key: "rangeSheetReferenceType", value: function rangeSheetReferenceType(start, end) { if (start === undefined) { return _Ast.RangeSheetReferenceType.RELATIVE; } else if (end === undefined) { return _Ast.RangeSheetReferenceType.START_ABSOLUTE; } else { return _Ast.RangeSheetReferenceType.BOTH_ABSOLUTE; } } }]); return FormulaParser; }(_chevrotain.EmbeddedActionsParser); exports.FormulaParser = FormulaParser; var FormulaLexer = /*#__PURE__*/function () { function FormulaLexer(lexerConfig) { _classCallCheck(this, FormulaLexer); this.lexerConfig = lexerConfig; this.lexer = new _chevrotain.Lexer(lexerConfig.allTokens, { ensureOptimizations: true }); } /** * Returns Lexer tokens from formula string * * @param text - string representation of a formula */ _createClass(FormulaLexer, [{ key: "tokenizeFormula", value: function tokenizeFormula(text) { var lexingResult = this.lexer.tokenize(text); var tokens = lexingResult.tokens; tokens = this.trimTrailingWhitespaces(tokens); tokens = this.skipWhitespacesInsideRanges(tokens); tokens = this.skipWhitespacesBeforeArgSeparators(tokens); lexingResult.tokens = tokens; return lexingResult; } }, { key: "skipWhitespacesInsideRanges", value: function skipWhitespacesInsideRanges(tokens) { return this.filterTokensByNeighbors(tokens, function (previous, current, next) { return ((0, _chevrotain.tokenMatcher)(previous, _LexerConfig.CellReference) || (0, _chevrotain.tokenMatcher)(previous, _LexerConfig.RangeSeparator)) && (0, _chevrotain.tokenMatcher)(current, _LexerConfig.WhiteSpace) && ((0, _chevrotain.tokenMatcher)(next, _LexerConfig.CellReference) || (0, _chevrotain.tokenMatcher)(next, _LexerConfig.RangeSeparator)); }); } }, { key: "skipWhitespacesBeforeArgSeparators", value: function skipWhitespacesBeforeArgSeparators(tokens) { var _this2 = this; return this.filterTokensByNeighbors(tokens, function (previous, current, next) { return !(0, _chevrotain.tokenMatcher)(previous, _this2.lexerConfig.ArgSeparator) && (0, _chevrotain.tokenMatcher)(current, _LexerConfig.WhiteSpace) && (0, _chevrotain.tokenMatcher)(next, _this2.lexerConfig.ArgSeparator); }); } }, { key: "filterTokensByNeighbors", value: function filterTokensByNeighbors(tokens, shouldBeSkipped) { if (tokens.length < 3) { return tokens; } var i = 0; var filteredTokens = [tokens[i++]]; while (i < tokens.length - 1) { if (!shouldBeSkipped(tokens[i - 1], tokens[i], tokens[i + 1])) { filteredTokens.push(tokens[i]); } ++i; } filteredTokens.push(tokens[i]); return filteredTokens; } }, { key: "trimTrailingWhitespaces", value: function trimTrailingWhitespaces(tokens) { if (tokens.length > 0 && (0, _chevrotain.tokenMatcher)(tokens[tokens.length - 1], _LexerConfig.WhiteSpace)) { tokens.pop(); } return tokens; } }]); return FormulaLexer; }(); exports.FormulaLexer = FormulaLexer;