//--------------------------------------------------------------------------- private bool changeN(char c, NKT kt) { if (c == '(') { kt.setNkt(kt.getNkt() + 1); return(true); } if (c == ')') { kt.setNkt(kt.getNkt() - 1); return(true); } return(false); }
//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- private String pDivFlip(String q) { int i; NKT kt = new NKT(0); for (i = 0; i < q.Length; i++) { if (changeN(q[i], kt)) { continue; } if ((kt.getNkt() == 0) && (q[i] == '/')) { q = q.Substring(0, i) + "*" + q.Substring(i + 1); continue; } } return(q); }
//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- private int anzahlParameter(String q) { int i, Anzahl; NKT kt = new NKT(0); Anzahl = 0; for (i = 0; i < q.Length; i++) { if (changeN(q[i], kt)) { continue; } if ((kt.getNkt() == 0) && (q[i] == ',')) { Anzahl++; } } return(Anzahl); }
//--------------------------------------------------------------------------- /** * Dies ist die eigentliche Parser - Funktion. Hier wird Funktion analysiert * und geparst und in eine Auswertbare Form übertragen (Item in Liste) * hier werden keine Funktionswerte bestimmt, nur der * Funktionstext geparst * Die Vorgehnsweise ist rekursivin pr wird or an * verschiedenen Stellen neu aufgerufen */ private int pr(String q) { // Vorbereitungen int i, error, anzahl; String ca, cb, c1 = "", c2 = "", s; Double param; // NKT bedeutet nKlammertiefe NKT kt = new NKT(0); IsZahl isz = new IsZahl(false); q = q.Trim(); // wenn leer, dann gibts nichts zu parsen (Fehler) if (String.IsNullOrEmpty(q)) { return(21); } // Kann ein x sein if (q.ToUpper() == "X") { return(addItem(0, 0.0, -1, "x")); } // kann ein pi sein if (q.ToUpper() == "PI") { try { param = Math.PI; } catch (Exception ex) { return(1); } return(addItem(3, param, -1, "Pi")); } // kann die Eulerzahl sein if (q.ToUpper() == "E") { try { param = Math.E; } catch (Exception ex) { return(1); } return(addItem(3, param, -1, "e")); } // Leerzeichen eleminieren s = ""; for (i = 0; i < q.Length; i++) { if (q[i] != ' ') { s = s + q[i]; } } q = s; // zuviele Vorzeichen reduzieren auf das // eigentliche Vorzeichen while ((q.IndexOf("++") > 0) || (q.IndexOf("+-") > 0) || (q.IndexOf("-+") > 0) || (q.IndexOf("--") > 0)) { if (q.IndexOf("++") > 0) { q = q.Substring(0, q.IndexOf("++") + 1) + q.Substring(q.IndexOf("++") + 2); } if (q.IndexOf("-+") > 0) { q = q.Substring(0, q.IndexOf("-+") + 1) + q.Substring(q.IndexOf("-+") + 2); } if (q.IndexOf("+-") > 0) { q = q.Substring(0, q.IndexOf("+-")) + q.Substring(q.IndexOf("+-") + 1); } if (q.IndexOf("--") > 0) { q = q.Substring(0, q.IndexOf("--")) + "+" + q.Substring(q.IndexOf("--") + 2); } } // Pluszeichen am Anfang hat keine Bedeutung if (q[0] == '+') { return(pr(q.Substring(1))); } // Minuszeichen - den positiven teil analysieren und // zum Schluss mal (-1.0) nehmen if (q[0] == '-') { q = q.Substring(1); q = pMinusFlip(q); addItem(1, 0.0, -1, "("); // Rekursives Weitergehen nach Innen error = pr(q); if (error != 0) { return(error); } addItem(2, 0.0, -1, ")"); addItem(4, 0.0, 9, "*(-1.0)"); return(0); } // Mal und geteilt am Anfang ist Boedsinn - Fehler // '**' auch enthalten if ((q[0] == '*') || (q[0] == '/')) { // kein mathematischer Ausdruck return(3); } // Feststellen, ob es einfach nur ein Zahlenwert ist, // kein mathematischer Ausdruck (Term) error = pIsZahl(q, isz); if (error != 0) { return(error); } else { if (isz.getIsZahl()) { // Punkt muss durch Komma ersetzt werden // q = changePointToKomma( q ); try { // versuchen, aus dem Zahlenwert ein Double zu machen param = Double.Parse(q, CultureInfo.InvariantCulture); } catch (Exception ex) { return(1); } addItem(3, param, -1, q); return(0); } } // inn kt werden die Anzahl der offenen Klammer gezaehlt for (i = 0; i < q.Length; i++) { if (changeN(q[i], kt)) { continue; } // nur wenn kt gleich 0 ist, dann laesst sich Term // weiter analysieren in binäre oder mono - Operationen // erst + - Zeichen (Punktrechnugn vor Strichrechnung) // von Aussen nach Innen !! if ((kt.getNkt() == 0) && (q[i] == '+') && (q[i - 1] != '*') && (q[i - 1] != '/')) { if (i == 0) { return(3); } ca = q.Substring(0, i); cb = q.Substring(i + 1); if (String.IsNullOrEmpty(cb.Trim())) { // kein mathematischer Ausdruck return(3); } addItem(1, 0.0, -1, "("); // Rekursives Weitergehen nach Innen error = pr(ca); if (error != 0) { return(error); } // Rekursives Weitergehen nach Innen error = pr(cb); if (error != 0) { return(error); } addItem(2, 0.0, -1, ")"); addItem(4, 0.0, 0, "+"); return(0); } } if (kt.getNkt() != 0) { return(2); } for (i = 0; i < q.Length; i++) { if (changeN(q[i], kt)) { continue; } // - Zeichen wwie + Zeichen if ((kt.getNkt() == 0) && (q[i] == '-') && (q[i - 1] != '*') && (q[i - 1] != '/')) { if (i == 0) { return(3); } ca = q.Substring(0, i); cb = q.Substring(i + 1); if (String.IsNullOrEmpty(cb.Trim())) { // kein mathematischer Ausdruck return(3); } cb = pMinusFlip(cb); addItem(1, 0.0, -1, "("); error = pr(ca); if (error != 0) { return(error); } error = pr(cb); if (error != 0) { return(error); } addItem(2, 0.0, -1, ")"); addItem(4, 0.0, 1, "-"); return(0); } } if (kt.getNkt() != 0) { return(2); } for (i = 0; i < q.Length; i++) { if (changeN(q[i], kt)) { continue; } // * - Zeichen wie + Zeichen (kein Exponentieren!!) if ((kt.getNkt() == 0) && (q[i] == '*') && ((q.Substring(i, 2)) != "**") && ((q.Substring(i - 1, 2)) != "**")) { if (i == 0) { return(3); } ca = q.Substring(0, i); cb = q.Substring(i + 1); if (String.IsNullOrEmpty(cb.Trim())) { // kein mathematischer Ausdruck return(3); } addItem(1, 0.0, -1, "("); error = pr(ca); if (error != 0) { return(error); } error = pr(cb); if (error != 0) { return(error); } addItem(2, 0.0, -1, ")"); addItem(4, 0.0, 2, "*"); return(0); } } if (kt.getNkt() != 0) { return(2); } for (i = 0; i < q.Length; i++) { if (changeN(q[i], kt)) { continue; } // 'geteilt' Zeichen wie + Zeichen if ((kt.getNkt() == 0) && (q[i] == '/')) { if (i == 0) { return(3); } ca = q.Substring(0, i); cb = q.Substring(i + 1); if (String.IsNullOrEmpty(cb.Trim())) { // kein mathematischer Ausdruck return(3); } cb = pDivFlip(cb); addItem(1, 0.0, -1, "("); error = pr(ca); if (error != 0) { return(error); } error = pr(cb); if (error != 0) { return(error); } addItem(2, 0.0, -1, ")"); addItem(4, 0.0, 3, "/"); return(0); } } if (kt.getNkt() != 0) { return(2); } for (i = 0; i < q.Length; i++) { if (changeN(q[i], kt)) { continue; } // Exponentieren wwie + Zeichen if ((kt.getNkt() == 0) && (q.Substring(i, 2) == "**")) { if (i == 0) { return(3); } ca = q.Substring(0, i); cb = q.Substring(i + 2); if (String.IsNullOrEmpty(cb.Trim())) { // kein mathematischer Ausdruck return(3); } addItem(1, 0.0, -1, "("); error = pr(ca); if (error != 0) { return(error); } error = pr(cb); if (error != 0) { return(error); } addItem(2, 0.0, -1, ")"); addItem(4, 0.0, 10, "**"); return(0); } } // for ( i = 1; i<= q.Length(); i++) // kann nur eingeklammerter Bereich sein if ((q[0] == '(') && (q[q.Length - 1] == ')')) { ca = q.Substring(1, q.Length - 2); if (String.IsNullOrEmpty(ca.Trim())) { return(6); } error = pr(ca); if (error != 0) { return(error); } return(0); } // ab hier kann sich nur noch um Funktion handeln if (kt.getNkt() != 0) { return(2); } if ((q[q.Length - 1] != ')') || (q.IndexOf('(') < 0)) { return(8); } ca = q.Substring(q.IndexOf('(') + 1); ca = ca.Substring(0, ca.Length - 1); if (String.IsNullOrEmpty(ca.Trim())) { return(6); } addItem(1, 0.0, -1, "("); cb = q.Substring(0, q.IndexOf('(')); if (String.IsNullOrEmpty(cb.Trim())) { return(5); } anzahl = anzahlParameter(ca); if (anzahl > 1) { return(9); } if (anzahlParameter(ca) == 1) { // 2parametrige Funktion for (i = 0; i < ca.Length; i++) { if (changeN(ca[i], kt)) { continue; } if ((kt.getNkt() == 0) && (ca[i] == ',')) { c1 = ca.Substring(0, i); c2 = ca.Substring(i + 1); if ((String.IsNullOrEmpty(c1.Trim())) || (String.IsNullOrEmpty(c2.Trim()))) { // kein mathematischer Ausdruck return(4); } break; } } // for ( i = 1; i<= q.Length(); i++) if (kt.getNkt() != 0) { return(2); } if (cb.ToUpper() == "NK") { // jedesmal extra, da auch verschachtelte Funtionen möglich sind! error = pr(c1); if (error != 0) { return(error); } error = pr(c2); if (error != 0) { return(error); } addItem(2, 0.0, -1, ")"); addItem(4, 0.0, 11, "nk"); return(0); } // Error - unbekannte einparametrige Funktion return(10); } // if (ca.Pos(",")>0) error = pr(ca); if (error != 0) { return(error); } addItem(2, 0.0, -1, ")"); if (cb.ToUpper() == "SIN") { addItem(4, 0.0, 4, "sin"); return(0); } else if (cb.ToUpper() == "COS") { addItem(4, 0.0, 5, "cos"); return(0); } else if (cb.ToUpper() == "TAN") { addItem(4, 0.0, 6, "tan"); return(0); } else if (cb.ToUpper() == "E") { addItem(4, 0.0, 7, "e"); return(0); } else if (cb.ToUpper() == "LN") { addItem(4, 0.0, 8, "ln"); return(0); } else if (cb.ToUpper() == "ASIN") { addItem(4, 0.0, 12, "asin"); return(0); } else if (cb.ToUpper() == "ACOS") { addItem(4, 0.0, 13, "acos"); return(0); } else if (cb.ToUpper() == "ATAN") { addItem(4, 0.0, 14, "atan"); return(0); } return(5); }