ifc-expressions
Version:
Parsing and evaluation of IFC expressions
186 lines (185 loc) • 13 kB
JavaScript
"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