UNPKG

ifc-expressions

Version:

Parsing and evaluation of IFC expressions

186 lines (185 loc) 13 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.IfcExpression = exports.IfcExpressionParseResult = exports.Types = exports.TypeDisjunction = exports.TupleType = exports.SimpleType = exports.ArrayType = exports.ExprFacade = exports.ExprToTextInputLinker = exports.isExprEvalSuccess = exports.isExprEvalError = exports.isNullish = exports.isPresent = exports.IfcExpressionVisitor = exports.IfcExpressionErrorListener = exports.IfcExpressionEvaluationException = exports.ExprKind = exports.ExprCompiler = exports.NamedObjectAccessor = exports.IfcTypeObjectAccessor = exports.IfcRootObjectAccessor = exports.IfcPropertyAccessor = exports.IfcPropertySetAccessor = exports.IfcTimeStampValue = exports.IfcDurationValue = exports.IfcTimeValue = exports.IfcDateTimeValue = exports.IfcDateValue = exports.ReferenceValue = exports.NumericValue = exports.LogicalValue = exports.BooleanValue = exports.StringValue = exports.IfcElementAccessor = void 0; const antlr4_1 = require("antlr4"); const ExprCompiler_js_1 = require("./compiler/ExprCompiler.js"); Object.defineProperty(exports, "ExprCompiler", { enumerable: true, get: function () { return ExprCompiler_js_1.ExprCompiler; } }); const IfcExpressionErrorListener_js_1 = require("./IfcExpressionErrorListener.js"); Object.defineProperty(exports, "IfcExpressionErrorListener", { enumerable: true, get: function () { return IfcExpressionErrorListener_js_1.IfcExpressionErrorListener; } }); const IfcExpressionValidationListener_js_1 = require("./compiler/IfcExpressionValidationListener.js"); const IfcExpressionUtils_js_1 = require("./util/IfcExpressionUtils.js"); Object.defineProperty(exports, "isNullish", { enumerable: true, get: function () { return IfcExpressionUtils_js_1.isNullish; } }); Object.defineProperty(exports, "isPresent", { enumerable: true, get: function () { return IfcExpressionUtils_js_1.isPresent; } }); const IfcElementAccessor_js_1 = require("./context/IfcElementAccessor.js"); Object.defineProperty(exports, "IfcElementAccessor", { enumerable: true, get: function () { return IfcElementAccessor_js_1.IfcElementAccessor; } }); const StringValue_js_1 = require("./value/StringValue.js"); Object.defineProperty(exports, "StringValue", { enumerable: true, get: function () { return StringValue_js_1.StringValue; } }); const NumericValue_js_1 = require("./value/NumericValue.js"); Object.defineProperty(exports, "NumericValue", { enumerable: true, get: function () { return NumericValue_js_1.NumericValue; } }); const BooleanValue_js_1 = require("./value/BooleanValue.js"); Object.defineProperty(exports, "BooleanValue", { enumerable: true, get: function () { return BooleanValue_js_1.BooleanValue; } }); const LogicalValue_js_1 = require("./value/LogicalValue.js"); Object.defineProperty(exports, "LogicalValue", { enumerable: true, get: function () { return LogicalValue_js_1.LogicalValue; } }); const ReferenceValue_js_1 = require("./value/ReferenceValue.js"); Object.defineProperty(exports, "ReferenceValue", { enumerable: true, get: function () { return ReferenceValue_js_1.ReferenceValue; } }); const IfcPropertySetAccessor_js_1 = require("./context/IfcPropertySetAccessor.js"); Object.defineProperty(exports, "IfcPropertySetAccessor", { enumerable: true, get: function () { return IfcPropertySetAccessor_js_1.IfcPropertySetAccessor; } }); const IfcPropertyAccessor_js_1 = require("./context/IfcPropertyAccessor.js"); Object.defineProperty(exports, "IfcPropertyAccessor", { enumerable: true, get: function () { return IfcPropertyAccessor_js_1.IfcPropertyAccessor; } }); const IfcRootObjectAccessor_js_1 = require("./context/IfcRootObjectAccessor.js"); Object.defineProperty(exports, "IfcRootObjectAccessor", { enumerable: true, get: function () { return IfcRootObjectAccessor_js_1.IfcRootObjectAccessor; } }); const IfcTypeObjectAccessor_js_1 = require("./context/IfcTypeObjectAccessor.js"); Object.defineProperty(exports, "IfcTypeObjectAccessor", { enumerable: true, get: function () { return IfcTypeObjectAccessor_js_1.IfcTypeObjectAccessor; } }); const NamedObjectAccessor_js_1 = require("./context/NamedObjectAccessor.js"); Object.defineProperty(exports, "NamedObjectAccessor", { enumerable: true, get: function () { return NamedObjectAccessor_js_1.NamedObjectAccessor; } }); const IfcExpressionParser_js_1 = __importDefault(require("./gen/parser/IfcExpressionParser.js")); const IfcExpressionVisitor_js_1 = __importDefault(require("./gen/parser/IfcExpressionVisitor.js")); exports.IfcExpressionVisitor = IfcExpressionVisitor_js_1.default; const IfcExpressionLexer_js_1 = __importDefault(require("./gen/parser/IfcExpressionLexer.js")); const IfcExpressionEvaluationException_js_1 = require("./expression/IfcExpressionEvaluationException.js"); Object.defineProperty(exports, "IfcExpressionEvaluationException", { enumerable: true, get: function () { return IfcExpressionEvaluationException_js_1.IfcExpressionEvaluationException; } }); const ExprEvalResult_js_1 = require("./expression/ExprEvalResult.js"); Object.defineProperty(exports, "isExprEvalError", { enumerable: true, get: function () { return ExprEvalResult_js_1.isExprEvalError; } }); Object.defineProperty(exports, "isExprEvalSuccess", { enumerable: true, get: function () { return ExprEvalResult_js_1.isExprEvalSuccess; } }); const ExprKind_js_1 = require("./expression/ExprKind.js"); Object.defineProperty(exports, "ExprKind", { enumerable: true, get: function () { return ExprKind_js_1.ExprKind; } }); const ValidationException_js_1 = require("./error/ValidationException.js"); const ExceptionToExprEvalErrorMapper_js_1 = require("./error/ExceptionToExprEvalErrorMapper.js"); const NopContext_js_1 = require("./context/NopContext.js"); const ExprToTextInputLinker_js_1 = require("./compiler/ExprToTextInputLinker.js"); Object.defineProperty(exports, "ExprToTextInputLinker", { enumerable: true, get: function () { return ExprToTextInputLinker_js_1.ExprToTextInputLinker; } }); const ExprFacade_js_1 = require("./expression/ExprFacade.js"); Object.defineProperty(exports, "ExprFacade", { enumerable: true, get: function () { return ExprFacade_js_1.ExprFacade; } }); const IfcDurationValue_js_1 = require("./value/IfcDurationValue.js"); Object.defineProperty(exports, "IfcDurationValue", { enumerable: true, get: function () { return IfcDurationValue_js_1.IfcDurationValue; } }); const IfcDateValue_js_1 = require("./value/IfcDateValue.js"); Object.defineProperty(exports, "IfcDateValue", { enumerable: true, get: function () { return IfcDateValue_js_1.IfcDateValue; } }); const IfcDateTimeValue_js_1 = require("./value/IfcDateTimeValue.js"); Object.defineProperty(exports, "IfcDateTimeValue", { enumerable: true, get: function () { return IfcDateTimeValue_js_1.IfcDateTimeValue; } }); const IfcTimeValue_js_1 = require("./value/IfcTimeValue.js"); Object.defineProperty(exports, "IfcTimeValue", { enumerable: true, get: function () { return IfcTimeValue_js_1.IfcTimeValue; } }); const IfcTimeStampValue_js_1 = require("./value/IfcTimeStampValue.js"); Object.defineProperty(exports, "IfcTimeStampValue", { enumerable: true, get: function () { return IfcTimeStampValue_js_1.IfcTimeStampValue; } }); const ArrayType_js_1 = require("./type/ArrayType.js"); Object.defineProperty(exports, "ArrayType", { enumerable: true, get: function () { return ArrayType_js_1.ArrayType; } }); const SimpleType_js_1 = require("./type/SimpleType.js"); Object.defineProperty(exports, "SimpleType", { enumerable: true, get: function () { return SimpleType_js_1.SimpleType; } }); const TupleType_js_1 = require("./type/TupleType.js"); Object.defineProperty(exports, "TupleType", { enumerable: true, get: function () { return TupleType_js_1.TupleType; } }); const TypeDisjunction_js_1 = require("./type/TypeDisjunction.js"); Object.defineProperty(exports, "TypeDisjunction", { enumerable: true, get: function () { return TypeDisjunction_js_1.TypeDisjunction; } }); const Types_js_1 = require("./type/Types.js"); Object.defineProperty(exports, "Types", { enumerable: true, get: function () { return Types_js_1.Types; } }); class IfcExpressionParseResult { constructor(input, typeManager, exprContext) { this._typeManager = typeManager; this._parseTree = exprContext; this._input = input; } get typeManager() { return this._typeManager; } get parseTree() { return this._parseTree; } get input() { return this._input; } } exports.IfcExpressionParseResult = IfcExpressionParseResult; class IfcExpression { /** * Parses the input and returns a parse result, which contains the parse tree, the type information per parse tree node, and the input. * @param input * @param errorListener * @return the parse result, which can subequently be compiled into an Expr using compile(). */ static parse(input, errorListener) { const chars = new antlr4_1.CharStream(input); // replace this with a FileStream as required const lexer = new IfcExpressionLexer_js_1.default(chars); const tokens = new antlr4_1.CommonTokenStream(lexer); const parser = new IfcExpressionParser_js_1.default(tokens); lexer.removeErrorListeners(); parser.removeErrorListeners(); const myErrorListener = new IfcExpressionErrorListener_js_1.IfcExpressionErrorListener(); if ((0, IfcExpressionUtils_js_1.isPresent)(errorListener)) { lexer.addErrorListener(errorListener); parser.addErrorListener(errorListener); } lexer.addErrorListener(myErrorListener); parser.addErrorListener(myErrorListener); let expr; expr = parser.expr(); const validationListener = new IfcExpressionValidationListener_js_1.IfcExpressionValidationListener(); if (!myErrorListener.isErrorOccurred()) { const walker = new antlr4_1.ParseTreeWalker(); try { walker.walk(validationListener, expr); } catch (e) { if (e instanceof ValidationException_js_1.ValidationException) { if (errorListener instanceof IfcExpressionErrorListener_js_1.IfcExpressionErrorListener) { errorListener.validationException(e); } myErrorListener.validationException(e); } } } return new IfcExpressionParseResult(input, validationListener.getTypeManager(), expr); } /** * Compiles the specified parseResult into an Expr. * @param parseResult * @return the Expression (Expr), which can be evaluated to obtain its result. */ static compile(parseResult) { const compiler = new ExprCompiler_js_1.ExprCompiler(parseResult.typeManager); const expr = compiler.visit(parseResult.parseTree); ExprToTextInputLinker_js_1.ExprToTextInputLinker.linkTextToExpressions(parseResult.input, expr, compiler.getExprManager()); return new ExprFacade_js_1.ExprFacade(expr); } /** * Evaluates the specified input expression and returns the evaluation result. The parse * and compile steps are done internally. * * @param expression: the input expression * @param context: the context required for accessing the IFC model * @return the result (or an error object). */ static evaluate(expression, context = new NopContext_js_1.NopContext()) { const errorListener = new IfcExpressionErrorListener_js_1.IfcExpressionErrorListener(); const parseResult = IfcExpression.parse(expression, errorListener); if (errorListener.isErrorOccurred()) { return (0, ExceptionToExprEvalErrorMapper_js_1.mapException)(errorListener.getException()); } const compiledExpression = this.compile(parseResult); return compiledExpression.evaluate(context); } static formatError(input, error) { const lines = ["** Error **"]; if (!(0, IfcExpressionUtils_js_1.isNullish)(error["textSpan"])) { const span = error["textSpan"]; const underlined = span.underline(input, "^"); const startString = "Input: "; const indented = this.indent(underlined, startString.length); const replaced = startString + indented.substr(startString.length); replaced.split("\n").forEach((line) => lines.push(line)); } lines.push("Problem: " + error.message); return lines.join("\n"); } static indent(s, by) { return s .split("\n") .map((line) => " ".repeat(by) + line) .join("\n"); } static evaluateExpression(expr, context = new NopContext_js_1.NopContext()) { return expr.evaluate(context); } } exports.IfcExpression = IfcExpression; //# sourceMappingURL=IfcExpression.js.map