Parser erstellen, nur wie?



  • Hallo Leute,
    ich muss einen Parser erstellen um einen Rechner zu erstellen.
    Seit mir bitte nicht böse, aber ich habe wirklich keinen einzigen Schimmer wo ich damit anfangen soll. Ich hoffe,dass ihr mir vielleicht auf die Sprünge helfen könnt.Ich habe einen Rechner schon mit WinApi erstellt, doch ich wollte es jetzt lieber erstmall in der Konsole lernen und danach mein wissen darauf übertragen.
    Also mein kleines(sehr klein) Programm:

    #include <iostream>
    #include <string>
    int main()
    {
    	std::string ha;
    	std::cin>>ha;
    	getchar();
    	return 0;
    }
    

    Wie ihr seht, seht ihr fast nichts 😃 .
    Ich wollte einfach das man z.b 5+5*2 oder 5 + 5 * 2 eingeben muss. Dann dies 'geparst' wird und dann ausgerechnet wird. Natürlich möchte ich noch viel längere Rechnungen als diese ausführen sonst könnte man ja einfach abfragen was Rechenzeichen 1 und was Rechenzeichen 2 ist.
    Ich habe auch schon viele Tutorials, Websites abgeklappert hab es trotzdem nie wirklich geschafft.
    MFG NameIstMeinerr



  • Hier im Forum gibt es einen Artikel darüber: http://www.c-plusplus.net/forum/268247-full



  • patrick246 schrieb:

    Hier im Forum gibt es einen Artikel darüber: http://www.c-plusplus.net/forum/268247-full

    Danke, werde ich mir mal anschauen.



  • Lies dir einfach mal die Artikel Interpreterbau - Ein Anfang und Compilerbau durch (beide behandeln einen Rechner als Beispiel).
    Ein Parser ist schon etwas Fortschrittlicheres (insb. da man auch die Theorie z.B. (E)BNF verstehen sollte).

    Wenn du das C++ Buch "Die C++ Programmiersprache" (v. Stroustrup) hast, auch dort ist ein Taschenrechner als Beispiel angegeben.


  • Mod

    Soll das auch noch Punkt vor Strich können? Oder Klammern? Das wäre zwar nicht extrem schwierig, aber dennoch vermutlich mehr, als du derzeit schaffen kannst. Wenn du auch noch die Korrektheit der Eingabe prüfen möchtest, wird es sogar halbwegs kompliziert.

    Wenn du bloß ein Token nach dem anderen Lesen und Verarbeiten möchtest, dann geht die ungefähre Idee so:
    Die formatierten Leseoperationen (sprich: operator>>) versuchen immer, möglichst viel einzulesen, was zu dem gewünschten Datentyp passt. Wenn ein Zeichen nicht mehr passt, hören sie auf. Leerzeichen (und anderer Whitespace) werden am Anfang standardmäßig übersprungen. Das heißt, du kannst immer abwechselnd Zahl und Rechenzeichen lesen und dieses dann verarbeiten.

    Ganz einfaches Beispiel (welches dein Vorhaben möglicherweise bereits komplett löst 🙂 ):

    #include <iostream>
    
    int main()
    {
      double lhs, rhs;
      char operand;
      std::cin >> lhs;
      while (std::cin >> operand >> rhs)
        {
          switch(operand)
            {
            case '+': lhs += rhs; break;
            case '-': lhs -= rhs; break;
            case '*': lhs *= rhs; break;
            case '/': lhs /= rhs; break;
            }
          std::cout << "Zwischenergebnis: " << lhs << '\n';
        }
    }
    

    http://ideone.com/w6PMXH

    P.S: Da war ich etwas langsamer als die Kollegen, weil das Programmieren des Beispiels doch ein paar Minuten benötigt hat 🙂 . Aber nun hast du auch ein paar Links, wie man das etwas fortschrittlicher angehen kann, wenn man mehr als nur simple binäre Operatoren von links nach rechts verarbeiten möchte.



  • Mach einen Rechner mit polnischer Notation, das macht es gleichzeitig einfacher und interessanter.



  • zu Reverse Polish:

    Shunting Yard: Infix -> Polish
    auf der Wikipediaseite kann man einen Pseudocode finden (auf der englischen Seite ist der simpler beschrieben (der Pseudocode))



  • Und hier findest Du ein fertiges Beispiel für einen Recursive Descent Parser, der solche arithmetische Ausdrücke parst.



  • Danke für die zahlreichen Antworten,
    ich bin fertig mit meinem Code und habe den Parser erstellt.
    Es kann (noch) keine Klammern aber die es kann punkt vor strich und beliebig lange Rechnungen durchführen( Naja bis zum Ende des Bildschirms ).


  • Mod

    NameIstMeinerr schrieb:

    beliebig lange Rechnungen durchführen( Naja bis zum Ende des Bildschirms ).

    Wie schafft man es denn, zu solch einer eigenartigen Begrenzung zu kommen? Ich wüsste ja spontan nicht einmal, wie ich diesen Effekt gezielt erreichen könnte, geschweige denn, wie ich ihn zufällig herbei führen könnte.

    P.S.: Falls die eigentlichen Botschaft meines Beitrags nicht klar geworden sein solle: Versuch mal einfach, eine längere Rechnung zu tippen und schau, was passiert.



  • SeppJ schrieb:

    NameIstMeinerr schrieb:

    beliebig lange Rechnungen durchführen( Naja bis zum Ende des Bildschirms ).

    Wie schafft man es denn, zu solch einer eigenartigen Begrenzung zu kommen? Ich wüsste ja spontan nicht einmal, wie ich diesen Effekt gezielt erreichen könnte, geschweige denn, wie ich ihn zufällig herbei führen könnte.

    P.S.: Falls die eigentlichen Botschaft meines Beitrags nicht klar geworden sein solle: Versuch mal einfach, eine längere Rechnung zu tippen und schau, was passiert.

    Eigentlich hast du Recht, ist aber egal, Thema kann auch geschlossen werden.


Anmelden zum Antworten