public static ISILObject ExpressionParse(string functionspace, string unparsedArgs, List <ISILObject> equations) { unparsedArgs = unparsedArgs.Trim(); //Check if it is not an equation but a variable, otherwise recurse until it is a single object if (!SIL_Math.IsEquation(unparsedArgs) && !unparsedArgs.Contains('[')) { return(Retrieve_SIL_Object(functionspace, unparsedArgs, equations)); } int leftIndex = 0, rightIndex = 0; string deepestEquation; //parse arrays first if (unparsedArgs.Contains('[')) { deepestEquation = FindDeepest(unparsedArgs, '[', ']', ref rightIndex, ref leftIndex); ISILObject arrIndex = ProcessEquation(functionspace, deepestEquation, equations); string arrName = ""; leftIndex--; while (leftIndex > 0 ? (!SIL_Math.IsOperator(unparsedArgs[leftIndex - 1]) && unparsedArgs[leftIndex - 1] != '[' && unparsedArgs[leftIndex - 1] != '(') : false) { leftIndex--; arrName += unparsedArgs[leftIndex]; } arrName = Reverse(arrName).Trim(); int leftLength = leftIndex; string leftPart = leftLength > 0 ? unparsedArgs.Substring(0, leftLength) : ""; rightIndex = rightIndex == unparsedArgs.Length ? rightIndex : rightIndex + 1; int rightLength = unparsedArgs.Length - rightIndex; string rightPart = rightLength > 0 ? unparsedArgs.Substring(rightIndex, rightLength) : ""; equations.Add(new SILArrayElement(functionspace + "." + arrName, arrIndex)); unparsedArgs = leftPart + "{" + (equations.Count - 1).ToString() + "}" + rightPart; return(ExpressionParse(functionspace, unparsedArgs, equations)); } deepestEquation = FindDeepest(unparsedArgs, '(', ')', ref rightIndex, ref leftIndex); if (leftIndex > 1) { if (char.IsLetterOrDigit(unparsedArgs[leftIndex - 2])) { string functionName = ""; leftIndex--; while (leftIndex > 0 ? (!SIL_Math.IsOperator(unparsedArgs[leftIndex - 1]) && unparsedArgs[leftIndex - 1] != '[' && unparsedArgs[leftIndex - 1] != '(') : false) { leftIndex--; functionName += unparsedArgs[leftIndex]; } functionName = Reverse(functionName).Trim(); int leftLength = leftIndex; string leftPart = leftLength > 0 ? unparsedArgs.Substring(0, leftLength) : ""; rightIndex = rightIndex == unparsedArgs.Length ? rightIndex : rightIndex + 1; int rightLength = unparsedArgs.Length - rightIndex; string rightPart = rightLength > 0 ? unparsedArgs.Substring(rightIndex, rightLength) : ""; string function_s = unparsedArgs.Substring(leftLength, rightIndex - leftLength).Trim(); SILFunction function; object[] functionArgs = null; int linenumber = 0; CALL_Parse(functionspace, "CALL " + function_s, ref functionArgs, ref linenumber); function = (SILFunction)functionArgs[0]; equations.Add(function); unparsedArgs = leftPart + "{" + (equations.Count - 1).ToString() + "}" + rightPart; return(ExpressionParse(functionspace, unparsedArgs, equations)); } } if (!SIL_Math.IsEquation(deepestEquation)) { unparsedArgs = unparsedArgs.Replace("(" + deepestEquation + ")", deepestEquation.Trim()); } else { equations.Add((SILEquation)ProcessEquation(functionspace, deepestEquation, equations)); int leftLength = leftIndex > 0 ? leftIndex - 1 : 0; string leftPart = leftLength > 0 ? unparsedArgs.Substring(0, leftLength) : ""; rightIndex = rightIndex == unparsedArgs.Length ? rightIndex : rightIndex + 1; int rightLength = unparsedArgs.Length - rightIndex; string rightPart = rightLength > 0 ? unparsedArgs.Substring(rightIndex, rightLength) : ""; unparsedArgs = leftPart + "{" + (equations.Count - 1).ToString() + "}" + rightPart; } return(ExpressionParse(functionspace, unparsedArgs, equations)); }
/// <summary> /// Converts the input equation string into a SIL_Equation recursive datastructure /// </summary> /// <param name="equation">basic input eqaution, must NOT contain any brackets!</param> /// <returns>Converted equation class which can be calculated</returns> static ISILObject ProcessEquation(string functionspace, string equationString, List <ISILObject> equations) { //always returns equation if (!SIL_Math.IsEquation(equationString)) { return(Retrieve_SIL_Object(functionspace, equationString, equations)); } char[] separators = { '/', '*', '+', '-', '&', '|', '<', '>', '=' }; string leftVar = "", rightVar = "", equationSubstring = ""; int leftIndex = 0, rightIndex = 0; SILEquation equation = new SILEquation(); equationString = equationString.Trim(); //multiplication and division needs to be taken care of first! List <OperatorPosition> firstPos = new List <OperatorPosition>(); for (int i = 0; i < separators.Length; i++) { int pos = equationString.IndexOf(separators[i]); if (pos >= 0) { OperatorPosition op = new OperatorPosition(); op.position = pos; op.c = separators[i]; firstPos.Add(op); } if (i == 1 && firstPos.Count > 0) { break; } } firstPos.Sort(SortFirstOperators); equation.Operation = ConvertToOperator(firstPos[0].c); //now find the two terms this operation applies to and build new SIL_Equation class //find left variable for (int i = firstPos[0].position - 1; i >= 0; i--) { leftIndex = i; if (SIL_Math.IsOperator(equationString[i])) { if (i == 1) { leftIndex--; //allow negative numbers } break; } leftVar += equationString[i]; } leftVar = leftVar.Trim(); if (leftVar.Length == 0) { leftVar = "0"; } else { leftVar = Reverse(leftVar); //reverse the string b/c I read it from right to left } equation.Argument1 = Retrieve_SIL_Object(functionspace, leftVar, equations); //find right variable for (int i = firstPos[0].position + 1; i < equationString.Length; i++) { if (SIL_Math.IsOperator(equationString[i])) { break; } rightIndex = i; rightVar += equationString[i]; } rightIndex++; rightVar = rightVar.Trim(); if (rightVar.Length == 0) { rightVar = "0"; } equation.Argument2 = Retrieve_SIL_Object(functionspace, rightVar, equations); equationSubstring = equationString.Substring(leftIndex, rightIndex - leftIndex); string leftPart = leftIndex > 0 ? equationString.Substring(0, leftIndex + 1) : ""; int rightLength = equationString.Length - rightIndex; string rightPart = rightLength > 0 ? equationString.Substring(rightIndex, rightLength) : ""; equationString = leftPart + "{" + equations.Count.ToString() + "}" + rightPart; equations.Add(equation); return(ProcessEquation(functionspace, equationString, equations)); }
static ActionType CALL_Parse(string functionspace, string unparsedArgs, ref object[] parsedArgs, ref int lineNumber) { string parameters = unparsedArgs.Substring(5, unparsedArgs.Length - 5); if (!parameters.Contains("(")) { throw new Exception("\"(\" Expected!"); } string[] split = parameters.Split(new char[] { '(' }, StringSplitOptions.RemoveEmptyEntries); if (split.Length != 2) { throw new SyntaxErrorException(); } string functionName = split[0]; FunctionPrototype prototype = FunctionTable.Get(functionName); //Parse parameters & their types split[1] = split[1].Trim(); if (split[1][split[1].Length - 1] != ')') { throw new Exception("\")\" Expected!"); } split[1] = split[1].Substring(0, split[1].Length - 1); string[] split2 = split[1].Split(','); if (split2.Length == 1 && split2[0].Trim() == "") { split2 = new string[] { } } ; if (split2.Length != prototype.ParameterTypes.Length) { throw new Exception("Incorrect number of arguments!"); } List <ISILObject> functionParameters = new List <ISILObject>(); for (int i = 0; i < split2.Length; i++) { string parameter_s = split2[i].Trim(); if (parameter_s == "") { throw new Exception(string.Format("Missing parameter type and name for argument #{0}!", i)); } ISILObject parameter; if (SIL_Math.IsEquation(parameter_s)) { parameter = ExpressionParse(functionspace, parameter_s, new List <ISILObject>()); } else { parameter = Retrieve_SIL_Object(functionspace, parameter_s, null); } if ((prototype.ParameterTypes[i] == ObjectType.Array && parameter.Type != ObjectType.Array) || (prototype.ParameterTypes[i] == ObjectType.Integer && parameter.Type == ObjectType.Array)) { throw new Exception( string.Format("Incorrect type of parameter #{0}, {1} expexted!", i, Enum.GetName(typeof(ObjectType), prototype.ParameterTypes[i]))); } functionParameters.Add(parameter); } SILFunction function = new SILFunction(functionName, functionParameters.ToArray()); parsedArgs = new object[] { function }; return(ActionType.CALL); }