Grundform eines Ausdruckes überprüfen
-
Hallo zusammen,
ich lese eine Zeile eines TRichEdit's aus, die der Benutzer eingibt. Jetzt möchte ich überprüfen, ob diese Zeile einer gewissen Grundstruktur entspricht.
Einfaches Beispiel: Eingabe der Zeile im TRE.
1. Zeile: a=4 2. Zeile: b=5 3. Zeile: c=addieren(a,b)a und b sind Variablen, die, wenn wie in Zeile 1 und 2 abgebildet eigegeben wurden, abgespeichert und als Items in einem TListView angezeigt werden.
Jetzt möchte ich die 3. Zeile auswerten, und zwar so, dass ich erst überprüfe, ob es die Grundstruktur 'Ergebnis=addieren(Platzhalter1,Platzhalter2)' entspricht.
Die Platzhalter können beliebige Variablennamen annehmen. Wenn die Grundstruktur stimmt, soll dann der Name für Platzhalter1 und Platzhalter2 angenommen werden, hier a und b. Danach wird überprüft, ob ein Eintrag im TListView für a und b existiert. Wenn ja, werden diese über LoadFromFile eingeladen und es soll das Ergebnis der Addition von a und b auf c abgespeichert werden.Mir geht es jetzt nur darum, wie ich die Grundstruktur überprüfen kann.
Das ich zum Beispiel im vorhinein ausschließen kann, dass der Benutzer etwa
'c=attition(a,b)' eingibt etc.. Damit würde sich im Weiteren viel Rechenzeit einsparen lassen, da man hier abbrechen und eine Fehlermeldung ausgeben könnte.Danke und liebe Grüße
Todd
-
Hallo
Am einfachsten mit den AnsiString-Methoden Pos und SubString. Siehe BCB-Hilfe.
bis bald
akari
-
Danke für deine Antwort.
Aber das mit den AnsiString Methoden mache ich schon die ganze Zeit. Für größere Ausdrücke wird das umso komplizierter.
Dann müsste das ganze ja in Etwa so aussehen:
double erg,var1,var2; bool bvar1,bvar2; int linecount=RichEdit1->Lines->Count-1; AnsiString str=RichEdit1->Lines->Strings[linecount]; TStringList *list1 = new TStringList(); TStringList *list2 = new TStringList(); try { AnsiString Ergebnis = str.SubString(1,str.Pos('=')-1); AnsiString Var1N = str.SubString(str.Pos('(',str.Pos(',')-str.Pos('(')); AnsiString Var2N = str.SubString(str.Pos(','),str.Pos(')')-str.Pos(',')); for (int i=0;i<ListView1->Items->Count;i++) { if (ListView1->Items->Item[i]->Caption==Var1N) {list1->LoadFromFile(...); var1=StrToFloat(list1->Strings[1].Trim()); bvar1=true; } else if (ListView1->Items->Item[i]->Caption==Var2N) {list2->LoadFromFile(...); var2=StrToFloat(list2->Strings[1].Trim()); bvar2=true; } else if (bvar1 && bvar2) {break;break;} } if (str.SubString(str.Pos('=')+1,str.Pos('(')-str.Pos('=')-1)=="addieren") {erg=var1+var2;RichEdit1->Lines->Add(FloatToStr(erg));} delete list1; delete list2; } catch(...) { ShowMessage("Fehler bei der Eingabe"); }Hab es jetzt nicht ausprobiert aber so in etwa wäre es für dieses einfache Beispiel.
Könnte mir aber vorstellen, dass es noch weitaus komplizierter werden könnte, wenn ich mehrere Kommatas in einer Anwendung habe, bzw. wenn die Variablen keine Zahlen sondern Matrizen sind.Wenn es keine einfachere Lösung gibt, dann werd ich mich wohl damit begnügen müssen...

Danke und liebe Grüße
Todd
-
Hallo
"Einfacher" geht es nicht. Du kannst aber den Hauptteil, nämlich das Parsen, aber an darauf speziallisierte Librarys abgeben. Leider hat der Builder (zumindestens mein 5er) keine RegEx-Unterstützung. Du könntest also eine externe Library suchen wie boost, das eine RegEx-Verarbeitung beherscht.
bis bald
akari
-
Okay.
Dann schau ich mich mal schlau, was das Thema angeht.
Danke und liebe Grüße
Todd
-
Hallo,
wenns wirklich nur darum geht zu schauen ob der Benutzer korrekte Angaben macht hilft dir folgendes vllt. ein wenig weiter

int pos = Edit1->Text.Pos("addieren("); int pos2 = Edit1->Text.Pos(")"); TStringList *test = new TStringList(); if (pos != 0 && pos2 > pos) //pos2 > pos --> um sicherzustellen das die ) - Klammer hinter der ( - Klammer steht { try { AnsiString inhalt = Edit1->Text.SubString(pos+9,pos2-10); //Alles zwischen den Klammern lesen test->CommaText = inhalt; for (int i = 0; i < test->Count; i++) { if (test->Strings[i] != "") sum += StrToInt(test->Strings[i]); } ShowMessage("Summe: " + (AnsiString)sum); } catch(...) { ShowMessage("Syntaxfehler"); } } else { ShowMessage("Syntaxfehler"); }Ich hoff' ich hab dich nicht falsch verstanden :)!
mfg, Micha!
-
Danke für deine Antwort.
Im Grunde genommen hast du mich richtig verstanden.
Aber deine Lösung wäre auch keine Lösung für mich da z.B. die Anwenderfehleingabe:
c=addieren(a,)b)
damit nicht abgefangen würde. Es gibt eben unzählig unsinnige Eingaben, die abgefangen werden müssen. Deshalb dachte ich an einen Art Parser der mir die Arbeit abnimmt.Wollte das ganze in mehrere Schritte aufteilen.
1. Schritt: Überprüfung des Gesamtgerüstes
Falls Ausdruck in der Form: aaa=funktionsname(bbb,ccc,ddd,eee) dann weiter zu
Schritt 2.2. Schritt: Überprüfung gültiger Varialben Name aaa
Falls aaa gültiger Variablenname (keine Sonderzeichen etc...) dann weiter zu Schritt 3.3. Schritt:Überprüfung Gültigkeit übergebene Parameter bbb,ccc,ddd,eee
...
...usw.
Damit ich einen logischen Aufbau des gesamten Ablaufes habe und entsprechend bei etwaigen Fehlerauftritts die entsprechenden Hinweise geben kann.Liebe Grüße
Todd
-
Hi,
wenn der Benutzer c=addieren(a,)b) eingibt wird in meinem Beispiel alles bis a, abgearbeitet und dann sie Summe aus a berechnet! Alles was hinter der geschlossenen Klammer steht wird einfach nicht mehr berücksichtigt.
mfg, Micha!
-
Ich glaube das einfachste wäre es wenn ich selbst einen Parser schreibe und ihn als dll auslagere.
MFG Todd