/// <summary> /// Initializes a new instance of the <see cref="ExpressionParsingServiceBase" /> class with a specified math /// definition /// object. /// </summary> /// <param name="definition">The math definition to use.</param> protected private ExpressionParsingServiceBase(MathDefinition definition) { // Preconditions Requires.NotNull( out workingDefinition, definition, nameof(definition)); // Initialized internal state constantExtractors = new LevelDictionary <Type, IConstantsExtractor>(); constantInterpreters = new LevelDictionary <Type, IConstantInterpreter>(); constantPassThroughExtractors = new LevelDictionary <Type, IConstantPassThroughExtractor>(); stringFormatters = new List <IStringFormatter>(); nonaryFunctions = new Dictionary <string, Type>(); unaryFunctions = new Dictionary <string, Type>(); binaryFunctions = new Dictionary <string, Type>(); ternaryFunctions = new Dictionary <string, Type>(); assembliesToRegister = new List <Assembly> { typeof(ExpressionParsingService).GetTypeInfo() .Assembly }; }
public static Level LevelFromString(string levelString) { Level result = Level.NONE; if (LevelDictionary.ContainsKey(levelString)) { result = LevelDictionary[levelString]; } return(result); }
internal WorkingExpressionSet( string expression, MathDefinition mathDefinition, Dictionary <string, Type> nonaryFunctions, Dictionary <string, Type> unaryFunctions, Dictionary <string, Type> binaryFunctions, Dictionary <string, Type> ternaryFunctions, LevelDictionary <Type, IConstantsExtractor> extractors, LevelDictionary <Type, IConstantInterpreter> interpreters, List <IStringFormatter> stringFormatters, CancellationToken cancellationToken) { ParameterRegistry = new StandardParameterRegistry(stringFormatters); ConstantsTable = new Dictionary <string, ConstantNodeBase>(); ReverseConstantsTable = new Dictionary <string, string>(); SymbolTable = new Dictionary <string, ExpressionSymbol>(); ReverseSymbolTable = new Dictionary <string, string>(); StringFormatters = stringFormatters; CancellationToken = cancellationToken; Expression = expression; Definition = mathDefinition; AllOperatorsInOrder = new[] { mathDefinition.GreaterThanOrEqualSymbol, mathDefinition.LessThanOrEqualSymbol, mathDefinition.GreaterThanSymbol, mathDefinition.LessThanSymbol, mathDefinition.NotEqualsSymbol, mathDefinition.EqualsSymbol, mathDefinition.XorSymbol, mathDefinition.OrSymbol, mathDefinition.AndSymbol, mathDefinition.AddSymbol, mathDefinition.SubtractSymbol, mathDefinition.DivideSymbol, mathDefinition.MultiplySymbol, mathDefinition.PowerSymbol, mathDefinition.LeftShiftSymbol, mathDefinition.RightShiftSymbol, mathDefinition.NotSymbol }; NonaryFunctions = nonaryFunctions; UnaryFunctions = unaryFunctions; BinaryFunctions = binaryFunctions; TernaryFunctions = ternaryFunctions; Extractors = extractors; Interpreters = interpreters; FunctionRegex = new Regex( $@"(?'functionName'.*?){Regex.Escape(mathDefinition.Parentheses.Left)}(?'expression'.*?){Regex.Escape(mathDefinition.Parentheses.Right)}"); }
private LevelDictionary <LateralLevelForce> GenerateAppliedLoading() { var appliedLoading = new LevelDictionary <LateralLevelForce>(); foreach (BuildingLevelLateral2 lateralLevel in _levels) { appliedLoading.Add(lateralLevel.Level, GenerateAppliedLoadingAtLevel(lateralLevel)); } return(appliedLoading); }
public static LevelDictionary <PointDrift> GetDesignBoundaryCornerDrifts(LevelDataDictionary <RigidAnalysis> analyses) { var drifts = new LevelDictionary <PointDrift>(); List <BuildingLevelLateral2> sortedLevels = analyses.Select(l => l.Value.LateralLevel).OrderBy(l => l.Level.Elevation).ToList(); for (var i = 0; i < sortedLevels.Count; i++) { BuildingLevel level = sortedLevels[i].Level; RigidAnalysis analysis = analyses[level]; List <PointDrift> driftsAtLevel = DisplacementsWithUnknownDrifts(level, analysis.Responses.NodalLoadCaseResults.Values.SelectMany(r => r)); var storyHeight = sortedLevels[i].Height; if (i == 0) { // Lowest level; compare to ground driftsAtLevel.ForEach(d => { d.Drift = (Unitless)Result.Abs(d.Displacement / storyHeight); d.CoordinateBelow = d.Coordinate; d.DisplacementBelow = new Length(0, LengthUnit.Inch); }); } else { // Elevated level; compare to level below List <PointDrift> driftsAtLevelBelow = drifts[sortedLevels[i - 1].Level]; driftsAtLevel.ForEach(d => { PointDrift driftBelow = d.GetMatchingDriftAtLevelBelow(driftsAtLevelBelow); d.Drift = (Unitless)Result.Abs((d.Displacement - driftBelow.Displacement) / storyHeight); d.CoordinateBelow = driftBelow.Coordinate; d.DisplacementBelow = driftBelow.Displacement; }); } drifts.Add(level, driftsAtLevel); } return(drifts); }
public void Run() { ValidateLevelHeights(); SetDefaultStoryEccentricities(); _baseShear = DetermineSeismicBaseShear(); _distributionFactors = DetermineDistributionFactors(); _storyForces = DetermineStoryForces(); _storyShears = DetermineStoryShears(); AppliedForces = GenerateAppliedLoading(); }
internal static string?CheckAndAdd( IDictionary <string, ConstantNodeBase> constantsTable, IDictionary <string, string> reverseConstantsTable, LevelDictionary <Type, IConstantInterpreter> interpreters, string originalExpression, string content) { // No content if (string.IsNullOrWhiteSpace(content)) { return(null); } // Constant has already been evaluated, let's skip if (reverseConstantsTable.TryGetValue( content, out var key)) { return(key); } ConstantNodeBase?node = null; // Go through each interpreter foreach (var interpreter in interpreters.KeysByLevel.SelectMany(p => p.Value)) { var(success, result) = interpreters[interpreter].EvaluateIsConstant(content); if (success) { node = result; break; } } // Standard formatters if (node == null) { if (ParsingFormatter.ParseNumeric( content, out object?n)) { node = new NumericNode(n); } else if (ParsingFormatter.ParseByteArray( content, out byte[]? ba))
/// <summary> /// Replaces functions calls with expression placeholders. /// </summary> /// <param name="openParenthesis">The symbol of an open parenthesis.</param> /// <param name="closeParenthesis">The symbol of a closed parenthesis.</param> /// <param name="parameterSeparator">The symbol of a parameter separator.</param> /// <param name="constantsTable">The constants table.</param> /// <param name="reverseConstantsTable">The reverse-lookup constants table.</param> /// <param name="symbolTable">The symbols table.</param> /// <param name="reverseSymbolTable">The reverse-lookup symbols table.</param> /// <param name="interpreters">The constant interpreters.</param> /// <param name="parametersTable">The parameters table.</param> /// <param name="expression">The expression before processing.</param> /// <param name="allSymbols">All symbols.</param> internal static void ReplaceFunctions( string openParenthesis, string closeParenthesis, string parameterSeparator, Dictionary <string, ConstantNodeBase> constantsTable, Dictionary <string, string> reverseConstantsTable, Dictionary <string, ExpressionSymbol> symbolTable, Dictionary <string, string> reverseSymbolTable, LevelDictionary <Type, IConstantInterpreter> interpreters, IParameterRegistry parametersTable, string expression, string[] allSymbols) { // Replace the main expression ReplaceOneFunction( string.Empty, openParenthesis, closeParenthesis, parameterSeparator, constantsTable, reverseConstantsTable, symbolTable, reverseSymbolTable, interpreters, parametersTable, expression, allSymbols); for (var i = 1; i < symbolTable.Count; i++) { // Replace sub-expressions ReplaceOneFunction( $"item{i.ToString(CultureInfo.InvariantCulture).PadLeft(4, '0')}", openParenthesis, closeParenthesis, parameterSeparator, constantsTable, reverseConstantsTable, symbolTable, reverseSymbolTable, interpreters, parametersTable, expression, allSymbols); }
static void ReplaceOneFunction( string key, string outerOpenParenthesisSymbol, string outerCloseParenthesisSymbol, string outerParameterSeparatorSymbol, Dictionary <string, ConstantNodeBase> outerConstantsTableReference, Dictionary <string, string> outerReverseConstantsTableReference, Dictionary <string, ExpressionSymbol> outerSymbolTableReference, Dictionary <string, string> outerReverseSymbolTableReference, LevelDictionary <Type, IConstantInterpreter> interpreters, IParameterRegistry outerParametersTableReference, string outerExpressionSymbol, string[] outerAllSymbolsSymbols) { ExpressionSymbol symbol = outerSymbolTableReference[key]; if (symbol.IsFunctionCall) { return; } var replaced = symbol.Expression; while (replaced != null) { outerSymbolTableReference[key].Expression = replaced; replaced = ReplaceFunctionsLocal( replaced, outerOpenParenthesisSymbol, outerCloseParenthesisSymbol, outerParameterSeparatorSymbol, outerConstantsTableReference, outerReverseConstantsTableReference, outerSymbolTableReference, outerReverseSymbolTableReference, interpreters, outerParametersTableReference, outerExpressionSymbol, outerAllSymbolsSymbols); }
public void Test1() { // ARRANGE LevelDictionary <string, int> dict = new LevelDictionary <string, int> { { "key1", 1, 5 }, { "key2", 7, 4 }, { "key3", 2, 1 }, { "key4", 8, 2 }, { "key5", 5, 7 }, { "key6", 3, 3 }, { "key7", 6, 1 } }; int[] orderForValues = { 2, 6, 8, 3, 7, 1, 5 }; int index = 0; // ACT foreach (var val in dict.EnumerateValuesOnLevelKeys()) { // ASSERT Assert.Equal( orderForValues[index++], val); } }
/// <summary> /// Populates tables according to the currently-processed expression. /// </summary> /// <param name="processedExpression">The expression that is being processed.</param> /// <param name="constantsTable">The constants table.</param> /// <param name="reverseConstantsTable">The reverse-lookup constants table.</param> /// <param name="symbolTable">The symbols table.</param> /// <param name="reverseSymbolTable">The reverse-lookup symbols table.</param> /// <param name="parameterRegistry">The parameters registry.</param> /// <param name="interpreters">The constant interpreters.</param> /// <param name="originalExpression">The expression before processing.</param> /// <param name="openParenthesis">The symbol of an open parenthesis.</param> /// <param name="allSymbols">All symbols on which to split, in order.</param> internal static void PopulateTables( string processedExpression, Dictionary <string, ConstantNodeBase> constantsTable, Dictionary <string, string> reverseConstantsTable, Dictionary <string, ExpressionSymbol> symbolTable, Dictionary <string, string> reverseSymbolTable, IParameterRegistry parameterRegistry, LevelDictionary <Type, IConstantInterpreter> interpreters, string originalExpression, string openParenthesis, string[] allSymbols) { // Split expression by all symbols string[] expressions = processedExpression.Split( allSymbols, StringSplitOptions.RemoveEmptyEntries); foreach (var exp in expressions) { if (constantsTable.ContainsKey(exp)) { // We have a constant continue; } if (reverseConstantsTable.ContainsKey(exp)) { // We have a constant that has bee evaluated before continue; } if (parameterRegistry.Exists(exp)) { // We have a parameter continue; } if (symbolTable.ContainsKey(exp)) { // We have an already-existing symbol continue; } if (reverseSymbolTable.ContainsKey(exp)) { // We have a symbol value that has been evaluated before continue; } if (exp.Contains(openParenthesis)) { // We have a part of a function continue; } // Let's check whether it is a constant if (ConstantsGenerator.CheckAndAdd( constantsTable, reverseConstantsTable, interpreters, originalExpression, exp) != null) { continue; } // It's not a constant, nor something ever encountered before // Therefore it should be a parameter _ = parameterRegistry.AdvertiseParameter(exp); } }
static string?ReplaceFunctionsLocal( string source, string openParenthesisSymbol, string closeParenthesisSymbol, string parameterSeparatorSymbol, Dictionary <string, ConstantNodeBase> constantsTableReference, Dictionary <string, string> reverseConstantsTableReference, Dictionary <string, ExpressionSymbol> symbolTableReference, Dictionary <string, string> reverseSymbolTableReference, LevelDictionary <Type, IConstantInterpreter> interpretersReference, IParameterRegistry parametersTableReference, string expressionSymbol, string[] allSymbolsSymbols) { var op = -1; var opl = openParenthesisSymbol.Length; var cpl = closeParenthesisSymbol.Length; while (true) { op = source.InvariantCultureIndexOf( openParenthesisSymbol, op + opl); if (op == -1) { return(null); } if (op == 0) { continue; } var functionHeaderCheck = source.Substring( 0, op); if (allSymbolsSymbols.Any( ( p, check) => check.InvariantCultureEndsWith(p), functionHeaderCheck)) { continue; } var functionHeader = functionHeaderCheck.Split( allSymbolsSymbols, StringSplitOptions.None).Last(); var oop = source.InvariantCultureIndexOf( openParenthesisSymbol, op + opl); var cp = source.InvariantCultureIndexOf( closeParenthesisSymbol, op + cpl); while (oop < cp && oop != -1 && cp != -1) { oop = source.InvariantCultureIndexOf( openParenthesisSymbol, oop + opl); cp = source.InvariantCultureIndexOf( closeParenthesisSymbol, cp + cpl); } if (cp == -1) { continue; } var arguments = source.Substring( op + opl, cp - op - opl); var originalArguments = arguments; var q = arguments; while (q != null) { arguments = q; q = ReplaceFunctionsLocal( q, openParenthesisSymbol, closeParenthesisSymbol, parameterSeparatorSymbol, constantsTableReference, reverseConstantsTableReference, symbolTableReference, reverseSymbolTableReference, interpretersReference, parametersTableReference, expressionSymbol, allSymbolsSymbols); } var argPlaceholders = new List <string>(); foreach (var s in arguments.Split( new[] { parameterSeparatorSymbol }, StringSplitOptions.RemoveEmptyEntries)) { TablePopulationGenerator.PopulateTables( s, constantsTableReference, reverseConstantsTableReference, symbolTableReference, reverseSymbolTableReference, parametersTableReference, interpretersReference, expressionSymbol, openParenthesisSymbol, allSymbolsSymbols); // We check whether or not this is actually a constant argPlaceholders.Add( ConstantsGenerator.CheckAndAdd( constantsTableReference, reverseConstantsTableReference, interpretersReference, expressionSymbol, s) ?? (!parametersTableReference.Exists(s) ? SymbolExpressionGenerator.GenerateSymbolExpression( symbolTableReference, reverseSymbolTableReference, s, false) : s)); } var functionCallBody = $"{functionHeader}{openParenthesisSymbol}{string.Join(parameterSeparatorSymbol, argPlaceholders)}{closeParenthesisSymbol}"; var functionCallToReplace = $"{functionHeader}{openParenthesisSymbol}{originalArguments}{closeParenthesisSymbol}"; var functionCallItem = SymbolExpressionGenerator.GenerateSymbolExpression( symbolTableReference, reverseSymbolTableReference, functionCallBody, true); return(source.Replace( functionCallToReplace, functionCallItem)); } }
internal KeyLevelEnumerable(LevelDictionary <TKey, TValue> instance) =>
public static Level LevelFromString(string levelString) { return((LevelDictionary.ContainsKey(levelString)) ? LevelDictionary[levelString] : Level.NONE); }