UNPKG

@scalenc/nc-format

Version:

Library for handling TRUMPF NC file format.

303 lines 14.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExpressionReader = void 0; const Errors_1 = require("./Errors"); const ParserException_1 = require("./ParserException"); const Expressions = __importStar(require("../models/Expressions")); const Token_1 = require("./Token"); const Constants_1 = require("./Constants"); const UNARY_OPERATORS = { [Constants_1.Constants.BITWISE_NOT_OPERATOR]: Expressions.UnaryOperator.B_NOT, [Constants_1.Constants.LOGICAL_NOT_OPERATOR]: Expressions.UnaryOperator.NOT, [Constants_1.Constants.MINUS_SIGN]: Expressions.UnaryOperator.NEGATE, [Constants_1.Constants.CONCAT_OPERATOR]: Expressions.UnaryOperator.TO_STRING, }; const BINARY_OPERATORS = { [Constants_1.Constants.MULTIPLY_OPERATOR]: Expressions.BinaryOperator.MULTIPLY, [Constants_1.Constants.DIVIDE_OPERATOR]: Expressions.BinaryOperator.DIVIDE, [Constants_1.Constants.ADD_OPERATOR]: Expressions.BinaryOperator.ADD, [Constants_1.Constants.SUBTRACT_OPERATOR]: Expressions.BinaryOperator.SUBTRACT, [Constants_1.Constants.CONCAT_OPERATOR]: Expressions.BinaryOperator.CONCAT, [Constants_1.Constants.EQUAL_OPERATOR]: Expressions.BinaryOperator.EQUAL, [Constants_1.Constants.INEQUAL_OPERATOR]: Expressions.BinaryOperator.INEQUAL, [Constants_1.Constants.LESS_OPERATOR]: Expressions.BinaryOperator.LESS, [Constants_1.Constants.LESS_EQUAL_OPERATOR]: Expressions.BinaryOperator.LESS_EQUAL, [Constants_1.Constants.GREATER_EQUAL_OPERATOR]: Expressions.BinaryOperator.GREATER_EQUAL, [Constants_1.Constants.GREATER_OPERATOR]: Expressions.BinaryOperator.GREATER, [Constants_1.Constants.DIV_OPERATOR]: Expressions.BinaryOperator.DIV_DIVIDE, [Constants_1.Constants.MOD_OPERATOR]: Expressions.BinaryOperator.MODULO, [Constants_1.Constants.B_AND_OPERATOR]: Expressions.BinaryOperator.B_AND, [Constants_1.Constants.B_XOR_OPERATOR]: Expressions.BinaryOperator.B_XOR, [Constants_1.Constants.B_OR_OPERATOR]: Expressions.BinaryOperator.B_OR, [Constants_1.Constants.AND_OPERATOR]: Expressions.BinaryOperator.AND, [Constants_1.Constants.XOR_OPERATOR]: Expressions.BinaryOperator.XOR, [Constants_1.Constants.OR_OPERATOR]: Expressions.BinaryOperator.OR, }; class ExpressionReader { parser; constructor(parser) { this.parser = parser; } readExpression() { let operant = this.readOperant(); let binaryOperator = this.tryReadBinaryOperator(); if (binaryOperator !== undefined) { const stack = []; for (; binaryOperator !== undefined; binaryOperator = this.tryReadBinaryOperator()) { while (stack.length > 0 && this.firstHasLowerOrEqualPriority(binaryOperator, stack[stack.length - 1].operator)) { stack.pop(); } const binaryOperation = new Expressions.BinaryOperation(binaryOperator, undefined, undefined); if (stack.length === 0) { binaryOperation.leftExpression = operant; operant = binaryOperation; } else { binaryOperation.leftExpression = stack[stack.length - 1].rightExpression; stack[stack.length - 1].rightExpression = binaryOperation; } stack.push(binaryOperation); binaryOperation.rightExpression = this.readOperant(); } } return operant; } readOperant() { const unaryOperator = this.tryReadUnaryOperator(); if (unaryOperator !== undefined) { const unaryOperation = new Expressions.UnaryOperation(unaryOperator, this.readOperant()); return this.tryMergeNegativeNumber(unaryOperation); } this.assertNotLineOrFileEnd(); let expression; if (this.isNumberToken(this.parser.token)) { expression = this.readNumber(); } else if (this.isNameToken(this.parser.token)) { expression = this.readVariableOrFunction(); } else if (this.isOpeningBracket(this.parser.token)) { expression = this.readBracket(); } else if (this.isString(this.parser.token)) { expression = this.readString(); } else { throw new ParserException_1.ParserException(this.parser, Errors_1.Errors.EXPECTED_OPERANT); } return expression; } readNumber() { if (!this.parser.token) { throw new ParserException_1.ParserException(this.parser, Errors_1.Errors.INVALID_NUMBER); } const value = Token_1.tryParseNumber(this.parser.token); if (value === undefined) { throw new ParserException_1.ParserException(this.parser, Errors_1.Errors.INVALID_NUMBER); } const isInteger = !this.parser.token.value.includes(Constants_1.Constants.DECIMAL_CHAR); const numberFormat = 'hH'.includes(this.parser.token.value[0]) ? Expressions.NumberFormat.HEXADECIMAL : 'bB'.includes(this.parser.token.value[0]) ? Expressions.NumberFormat.BINARY : Expressions.NumberFormat.DECIMAL; const number = new Expressions.Number(value, isInteger, numberFormat); if (this.parser.tryRead() && this.isNumberExponent(this.parser.token)) { this.parser.tryRead(); // Skip 'EX'. const exponentSign = this.tryReadSignToken(); this.assertNotLineOrFileEnd(); ParserException_1.ParserException.expected(this.isDecimalNumberToken(this.parser.token), this.parser, Errors_1.Errors.EXPECTED_NUMBER); const exponent = exponentSign * +this.parser.token.value; number.value *= Math.pow(10, exponent); number.isInteger = false; } return number; } readVariableOrFunction() { const name = this.parser.token.value; const expression = this.parser.tryRead() && this.isOpeningBracket(this.parser.token) ? this.readFunction(name) : this.readVariable(name); return expression; } readFunction(name) { return new Expressions.Function(name, this.readParameterList()); } readVariable(name) { if (name.length === 1 && this.parser.token && !this.parser.token.whiteSpace && this.isDecimalNumberToken(this.parser.token) && !this.parser.token.value.includes(Constants_1.Constants.DECIMAL_CHAR)) { name += this.parser.token.value; this.parser.tryRead(); } const fieldExpressions = this.parser.token && this.isOpeningFieldBracket(this.parser.token) ? this.readParameterList(true) : undefined; return new Expressions.Variable(name, fieldExpressions); } readParameterList(fieldBrace = false) { this.parser.tryRead(); // Skip '[' or '('. const parameters = []; for (;;) { this.assertNotLineOrFileEnd(); if (fieldBrace ? this.isClosingFieldBracket(this.parser.token) : this.isClosingBracket(this.parser.token)) { this.parser.tryRead(); // Skip ']' or ')'. break; } if (this.isArgumentSeparator(this.parser.token)) { parameters.push(null); } else { parameters.push(this.readExpression()); } if (this.isArgumentSeparator(this.parser.token)) { this.parser.tryRead(); // Skip ','. } } return parameters; } readBracket() { this.parser.tryRead(); // Skip '('. const expression = new Expressions.Bracket(this.readExpression()); this.assertNotLineOrFileEnd(); ParserException_1.ParserException.expected(this.isClosingBracket(this.parser.token), this.parser, Errors_1.Errors.EXPECTED_CLOSING_BRACE); this.parser.tryRead(); // Skip ')'. return expression; } readString() { const expression = new Expressions.String(this.parser.token.value); this.parser.tryRead(); return expression; } tryReadBinaryOperator() { if (!this.isOperatorToken(this.parser.token)) { return undefined; } const binaryOperator = BINARY_OPERATORS[this.parser.token.value.toUpperCase()]; ParserException_1.ParserException.expected(binaryOperator !== undefined, this.parser, Errors_1.Errors.EXPECTED_BINARY_OPERATOR); this.parser.tryRead(); return binaryOperator; } tryReadUnaryOperator() { if (!this.isOperatorToken(this.parser.token)) { return undefined; } if (this.parser.token.value === Constants_1.Constants.PLUS_SIGN) { this.parser.tryRead(); // Just skip operator. return undefined; } const unaryOperator = UNARY_OPERATORS[this.parser.token.value.toUpperCase()]; ParserException_1.ParserException.expected(unaryOperator !== undefined, this.parser, Errors_1.Errors.EXPECTED_OPERANT); this.parser.tryRead(); return unaryOperator; } tryMergeNegativeNumber(unaryOperation) { if (unaryOperation.operator === Expressions.UnaryOperator.NEGATE && unaryOperation.expression instanceof Expressions.Number) { unaryOperation.expression.value = -unaryOperation.expression.value; return unaryOperation.expression; } return unaryOperation; } tryReadSignToken() { if (!this.isSignToken(this.parser.token)) { return +1; } const sign = this.parser.token.value === Constants_1.Constants.MINUS_SIGN ? -1 : +1; this.parser.tryRead(); return sign; } isLineOrFileEnd(token) { return !token || token.type === Token_1.TokenType.NEW_LINE || token.type === Token_1.TokenType.COMMENT; } isSignToken(token) { return token?.type === Token_1.TokenType.OPERATOR && (token.value === Constants_1.Constants.PLUS_SIGN || token.value === Constants_1.Constants.MINUS_SIGN); } isOperatorToken(token) { return token?.type === Token_1.TokenType.OPERATOR && !(token.value.length === 1 && token.value[0] === Constants_1.Constants.ASSIGNMENT_OPERATOR); } isDecimalNumberToken(token) { return this.isNumberToken(token) && Constants_1.Constants.DIGIT_CHARS.test(token.value[0]); } isNumberToken(token) { return token?.type === Token_1.TokenType.NUMBER; } isNumberExponent(token) { return token?.type === Token_1.TokenType.IDENTIFIER && !token.whiteSpace && token.value.toUpperCase() === Constants_1.Constants.NUMBER_EXPONENT; } isNameToken(token) { return token?.type === Token_1.TokenType.IDENTIFIER; } isOpeningBracket(token) { return token?.type === Token_1.TokenType.BRACE && token.value.length === 1 && token.value[0] === Constants_1.Constants.OPENING_BRACE; } isClosingBracket(token) { return token?.type === Token_1.TokenType.BRACE && token.value.length === 1 && token.value[0] === Constants_1.Constants.CLOSING_BRACE; } isOpeningFieldBracket(token) { return token?.type === Token_1.TokenType.FIELD_BRACE && token.value.length === 1 && token.value[0] === Constants_1.Constants.OPENING_FIELD_BRACE; } isClosingFieldBracket(token) { return token?.type === Token_1.TokenType.FIELD_BRACE && token.value.length === 1 && token.value[0] === Constants_1.Constants.CLOSING_FIELD_BRACE; } isArgumentSeparator(token) { return token?.type === Token_1.TokenType.SEPARATOR; } isString(token) { return token?.type === Token_1.TokenType.STRING; } assertNotLineOrFileEnd() { ParserException_1.ParserException.assert(!this.isLineOrFileEnd(this.parser.token), this.parser, Errors_1.Errors.UNEXPECTED_LINE_OR_FILE_END); } firstHasLowerOrEqualPriority(operation1, operation2) { const priority1 = this.getPriority(operation1); const priority2 = this.getPriority(operation2); return priority1 <= priority2; } getPriority(binaryOperator) { switch (binaryOperator) { case Expressions.BinaryOperator.MULTIPLY: case Expressions.BinaryOperator.DIVIDE: case Expressions.BinaryOperator.DIV_DIVIDE: case Expressions.BinaryOperator.MODULO: return 10; case Expressions.BinaryOperator.ADD: case Expressions.BinaryOperator.SUBTRACT: return 9; case Expressions.BinaryOperator.B_AND: return 8; case Expressions.BinaryOperator.B_XOR: return 7; case Expressions.BinaryOperator.B_OR: return 6; case Expressions.BinaryOperator.AND: return 5; case Expressions.BinaryOperator.XOR: return 4; case Expressions.BinaryOperator.OR: return 3; case Expressions.BinaryOperator.CONCAT: return 2; default: return 1; } } } exports.ExpressionReader = ExpressionReader; //# sourceMappingURL=ExpressionReader.js.map