/// <summary> /// This method split the equation (string) into a tree of equations (string) according the parentheses /// </summary> /// <param name="eq">equation</param> /// <param name="index">starting index of the equation in the string</param> /// <returns>tree</returns> public static UnparsedEq DivideStr(string eq, ref int index) { UnparsedEq result = new UnparsedEq(); result.str = ""; result.subEqs = new List <UnparsedEq>(); int nbSubEq = 0; while (eq[index] != ')') { char current = eq[index]; if (current == '(') { index++; //We generate an unique id for each subtree to link it in the main string result.str += "%" + nbSubEq.ToString("000"); nbSubEq++; result.subEqs.Add(DivideStr(eq, ref index)); } else { result.str += current; } index++; } return(result); }
/// <summary> /// Returns an equation from the given string, and other stuff /// </summary> /// <param name="str">equation to parse</param> /// <param name="currentUnparsed">current tree</param> /// <param name="registeredVars">the variables</param> /// <returns>output equation</returns> public static Equation Parse(string str, UnparsedEq currentUnparsed, List <string> registeredVars) { //this is a recursive function that parse every level of a tree at a time //we operate everything according to the priority order from lower to higher priority int index = str.IndexOf("*");//<-> if (index == -1) { index = str.IndexOf("→"); if (index == -1) { index = str.IndexOf("|"); if (index == -1) { index = str.IndexOf("&"); if (index == -1) { //at this point there is no dual part operators index = 0; //we skip blanks chars to get to the first important char SkipBlank(str, ref index); if (str[index] == '!') { //if it's the not operator index++; var eq = new Not(); //we have to parse the inner equation everytime the current equation is NOT a constant eq.InternalEquation = Parse(str.Substring(index), currentUnparsed, registeredVars); return(eq); } else if (char.IsLetter(str[index])) { //if it starts with a letter, it's a constant var variableName = ""; char currentChar = str[index]; while (char.IsLetterOrDigit(currentChar) && index < str.Length) { //we extract the name of the constant variableName += currentChar; index++; if (index < str.Length) { currentChar = str[index]; } } SkipBlank(str, ref index); if (index < str.Length) { throw new Exception("Unexpected char :" + str[index]); } //we add the discovered constant if it doesn't already exists if (!registeredVars.Contains(variableName)) { registeredVars.Add(variableName); } var eq = new Constant(); eq.Name = variableName; return(eq); } else if (str[index] == '%') { //if it starts with %, it's a sub tree (parentheses) //we extract the id of the subtree var nbStr = str.Substring(index + 1, 3); index += 4; SkipBlank(str, ref index); if (index < str.Length) { throw new Exception("Unexpected char :" + str[index]); } var nextUnparsed = currentUnparsed.subEqs[int.Parse(nbStr)]; //aaaand we parse the subtree var eq = Parse(nextUnparsed.str, nextUnparsed, registeredVars); return(eq); } else { throw new Exception("wrong var starting char"); } } else { //we have to reverse the string because when there is an equal priority (same operator), we parse from left to right, and not the other way around //if we isolate the first item every time, it means we parse from right to left var strs = new List <string>(); foreach (var item in new string(str.Reverse().ToArray()).Split(new string[] { "&" }, 2, StringSplitOptions.None)) { strs.Add(new string(item.Reverse().ToArray())); } //and we just fill the parts of the equation, parsing each side var eq = new OperatorEquation(); eq.Operator = OperatorEquation.OperatorType.AND; eq.Right = Parse(strs[0], currentUnparsed, registeredVars); eq.Left = Parse(strs[1], currentUnparsed, registeredVars); return(eq); } } else { //same things for all the others operators var strs = new List <string>(); foreach (var item in new string(str.Reverse().ToArray()).Split(new string[] { "|" }, 2, StringSplitOptions.None)) { strs.Add(new string(item.Reverse().ToArray())); } var eq = new OperatorEquation(); eq.Operator = OperatorEquation.OperatorType.OR; eq.Right = Parse(strs[0], currentUnparsed, registeredVars); eq.Left = Parse(strs[1], currentUnparsed, registeredVars); return(eq); } } else { var strs = new List <string>(); foreach (var item in new string(str.Reverse().ToArray()).Split(new string[] { "→" }, 2, StringSplitOptions.None)) { strs.Add(new string(item.Reverse().ToArray())); } var eq = new OperatorEquation(); eq.Operator = OperatorEquation.OperatorType.INVOLVING; eq.Right = Parse(strs[0], currentUnparsed, registeredVars); eq.Left = Parse(strs[1], currentUnparsed, registeredVars); return(eq); } } else { //<-> var strs = new List <string>(); foreach (var item in new string(str.Reverse().ToArray()).Split(new string[] { "*" }, 2, StringSplitOptions.None)) { strs.Add(new string(item.Reverse().ToArray())); } var eq = new OperatorEquation(); eq.Operator = OperatorEquation.OperatorType.EQUIVALENT; eq.Right = Parse(strs[0], currentUnparsed, registeredVars); eq.Left = Parse(strs[1], currentUnparsed, registeredVars); return(eq); } }
public static Equation Parse(string str, UnparsedEq currentUnparsed, List <string> registeredVars) { int index = str.IndexOf("*"); if (index == -1) { index = str.IndexOf("→"); if (index == -1) { index = str.IndexOf("|"); if (index == -1) { index = str.IndexOf("&"); if (index == -1) { index = 0; SkipBlank(str, ref index); if (str[index] == '!') { index++; var eq = new Not(); eq.InternalEquation = Parse(str.Substring(index), currentUnparsed, registeredVars); return(eq); } else if (char.IsLetter(str[index])) { var variableName = ""; char currentChar = str[index]; while (char.IsLetterOrDigit(currentChar) && index < str.Length) { variableName += currentChar; index++; if (index < str.Length) { currentChar = str[index]; } } SkipBlank(str, ref index); if (index < str.Length) { throw new Exception("Unexpected char :" + str[index]); } if (!registeredVars.Contains(variableName)) { registeredVars.Add(variableName); } var eq = new Constant(); eq.Name = variableName; return(eq); } else if (str[index] == '%') { var nbStr = str.Substring(index + 1, 3); index += 4; SkipBlank(str, ref index); if (index < str.Length) { throw new Exception("Unexpected char :" + str[index]); } var nextUnparsed = currentUnparsed.subEqs[int.Parse(nbStr)]; var eq = Parse(nextUnparsed.str, nextUnparsed, registeredVars); return(eq); } else { throw new Exception("wrong var starting char"); } } else { var strs = new List <string>(); foreach (var item in new string(str.Reverse().ToArray()).Split(new string[] { "&" }, 2, StringSplitOptions.None)) { strs.Add(new string(item.Reverse().ToArray())); } var eq = new OperatorEquation(); eq.Operator = OperatorEquation.OperatorType.AND; eq.Right = Parse(strs[0], currentUnparsed, registeredVars); eq.Left = Parse(strs[1], currentUnparsed, registeredVars); return(eq); } } else { var strs = new List <string>(); foreach (var item in new string(str.Reverse().ToArray()).Split(new string[] { "|" }, 2, StringSplitOptions.None)) { strs.Add(new string(item.Reverse().ToArray())); } var eq = new OperatorEquation(); eq.Operator = OperatorEquation.OperatorType.OR; eq.Right = Parse(strs[0], currentUnparsed, registeredVars); eq.Left = Parse(strs[1], currentUnparsed, registeredVars); return(eq); } } else { var strs = new List <string>(); foreach (var item in new string(str.Reverse().ToArray()).Split(new string[] { "→" }, 2, StringSplitOptions.None)) { strs.Add(new string(item.Reverse().ToArray())); } var eq = new OperatorEquation(); eq.Operator = OperatorEquation.OperatorType.INVOLVING; eq.Right = Parse(strs[0], currentUnparsed, registeredVars); eq.Left = Parse(strs[1], currentUnparsed, registeredVars); return(eq); } } else { var strs = new List <string>(); foreach (var item in new string(str.Reverse().ToArray()).Split(new string[] { "*" }, 2, StringSplitOptions.None)) { strs.Add(new string(item.Reverse().ToArray())); } var eq = new OperatorEquation(); eq.Operator = OperatorEquation.OperatorType.EQUIVALENT; eq.Right = Parse(strs[0], currentUnparsed, registeredVars); eq.Left = Parse(strs[1], currentUnparsed, registeredVars); return(eq); } }