private IMathNode isSpeicalFormattedNumber(string expression) { expression = expression.Trim(); var nbc = new NumericBaseConverter(); // Probably formatted via 0x hex? Check for hex input if (expression[0] == '0' && (expression[1] == 'x' || expression[1] == 'X')) { try { string number = expression.Substring(2); var val = (decimal)Int64.Parse(number, System.Globalization.NumberStyles.HexNumber); var inner = new NumericMathNode(new UnitDouble(val, UnitTypes.Hexadecimal, NumericBaseUnits.Hexadecimal, nbc)) { UnitType = UnitTypes.Hexadecimal }; return(new UnitUniLeafMathNode(inner, UnitTypes.Hexadecimal, nbc, NumericBaseUnits.Hexadecimal)); } catch { } } if (expression[0] == '0' && (expression[1] == 'b' || expression[1] == 'B')) { try { string number = expression.Substring(2); var val = (decimal)Convert.ToInt64(number, 2); var inner = new NumericMathNode(new UnitDouble(val, UnitTypes.Binary, NumericBaseUnits.Binary, nbc)) { UnitType = UnitTypes.Binary }; return(new UnitUniLeafMathNode(inner, UnitTypes.Binary, nbc, NumericBaseUnits.Binary)); } catch { } } if (expression[0] == '0') { try { var val = (decimal)Convert.ToInt64(expression, 8); var inner = new NumericMathNode(new UnitDouble(val, UnitTypes.Octal, NumericBaseUnits.Octal, nbc)) { UnitType = UnitTypes.Octal }; return(new UnitUniLeafMathNode(inner, UnitTypes.Octal, nbc, NumericBaseUnits.Octal)); } catch { } } return(null); }
private IMathNode parse(string expression) { if (String.IsNullOrEmpty(expression)) { return(null); } expression = expression.Trim(); expression = expression.TrimOuterParens(); short lowestop = -1; int oppos = -1; int parens = 0; int oplength = 0; string symbol = String.Empty; // Check for misplaced operators ( + - / * ^ ) if (this.invalidPreceedingOperators.Keys.Contains(expression[0].ToString()) || this.invalidPreceedingOperators.Keys.Contains(expression.Last().ToString())) { throw new InvalidOperatorException(expression[0], expression); } int startPos = 0; if (expression[0] == '-' || expression[0] == '~') { startPos++; } int lastNonWhiteSpace = -1; // get first smallest operator and parse left and right for (int pos = expression.Length - 1; pos >= startPos; pos--) { short opval; char tmp = expression[pos]; if (expression[pos] == ')') { lastNonWhiteSpace = pos; parens++; } else if (expression[pos] == '(') { lastNonWhiteSpace = pos; parens--; } if (parens < 0) { throw new InvalidMathExpressionException(expression); } var searchop = expression[pos].ToString(); if (searchop == "<" || searchop == ">") { searchop = expression[pos - 1].ToString() + expression[pos].ToString(); pos--; } if (!this.operators.ContainsKey(searchop)) { if (!Char.IsWhiteSpace(expression[pos])) { lastNonWhiteSpace = pos; } continue; } if (this.invalidPreceedingOperators.ContainsKey(searchop) && this.operators.ContainsKey(expression[pos - 1].ToString())) { throw new InvalidOperatorException(searchop[0], expression); } opval = this.operators[searchop]; // check for a - sign after this just in case. if ((parens != 0 || lowestop >= opval) && expression[pos + 1] != '-') { continue; } lowestop = opval; oppos = pos; oplength = searchop.Length - 1; symbol = searchop; } if (parens != 0) { throw new InvalidMathExpressionException(expression); } // No opperator was found, we are parsing something else if (oppos == -1) { decimal dbl; // We want to do octal parsing later on, so check this isn't an octal #. Otherwise, verify it's a decimal or 0. if ((expression[0] != '0' || expression.Length == 1 || expression[1] == '0' || expression[1] == '.') && decimal.TryParse(expression.Trim(), out dbl)) { return(new NumericMathNode(dbl)); } else // This isn't a number... So it must be a function or variable { // expression stores our function(args) var node = uniLeafFact.CreateUniLeafNode(expression.Trim(), this); if (null == node) { decimal val; // Check for a constant if not a function if (symbols.TryGetValue(expression.Trim(), out val)) { node = new NumericMathNode(val); } else { // Check for unit label if not a function nor a constant var result = UnitFactory.TryParse(expression, this); if (result != null) { return(result); } if (expression[0] == '-') { return(new MultiplicationBiLeafMathNode(new NumericMathNode(-1), this.Parse(expression.Substring(1)))); } else if (expression[0] == '~') { return(new NegateUniLeafMathNode(this.Parse(expression.Substring(1)))); } else if (expression[0] == '"' && expression.Last() == '"') { return(new StringMathNode(expression.Substring(1, expression.Length - 2))); } throw new InvalidMathExpressionException(expression); } } return(node); } } else { string left = String.Empty; if (oppos - 1 > 0) { left = expression.Substring(0, oppos - oplength); } else { left = expression[0].ToString(); } string right = expression.Substring(oppos + 1 + oplength, expression.Length - oppos - 1 - oplength); return(operFact.CreateOperatorNode(symbol, this.parse(left), this.parse(right))); } }