Parser Problem



  • #include <gtkmm.h>
    #include <gtkmm/button.h>
    #include <gtkmm/window.h>
    #include <gtkmm/entry.h>
    using namespace Gtk;
    
    //#include <cmath>
    #include <cstdio>
    #include <vector>
    #include <sstream>
    #include <iostream> //[DEBUG]
    using namespace std;
    
    class rechner_win : public Window
    {
      VBox m_vbox;
      HBox m_hbox;
      Entry m_entry;
      Entry m_erg;
      Button m_quit;
      Button m_calc;
    
      void quit_pressed() { hide(); }
      void calc();
    public:
      rechner_win();
      virtual ~rechner_win() { }
    };
    
    rechner_win::rechner_win()
      : m_quit(Stock::CLOSE)
    {
      set_title("Rechner 0.01");
      set_border_width(25);
    
      add(m_vbox);
    
      m_entry.set_max_length(1000);
      m_erg.set_editable(false);
    
      m_vbox.pack_start(m_entry);
      m_vbox.pack_start(m_erg);
    
      m_vbox.add(m_hbox);
    
      m_quit.signal_clicked().connect( SigC::slot(*this, &rechner_win::quit_pressed) );
      m_hbox.pack_start(m_quit);
    
      m_calc.add_pixlabel("calc.xpm","Calculate");
      m_calc.signal_clicked().connect( SigC::slot(*this, &rechner_win::calc) );
      m_hbox.pack_start(m_calc);
    
      show_all_children();  
    }
    
    typedef enum
    {
      ADD,
      SUB,
      MUL,
      DIV,
      MOD,
      DIGIT
    } token_type;
    
    struct token
    {
      token_type tok;
      union
      {
        int number;
        char sign;
      };
      int prioritaet;
    };
    
    void rechner_win::calc()
    {
      const char *str=m_entry.get_text().c_str();
      vector<token> op;
      bool klammer=false;
      cout << str << endl; //[DEBUG]
      for(size_t i=0 ; str[i] ; ++i)
      {
        cout << str[i] << " - " << i << endl; //[DEBUG]
        if(isdigit(str[i]))
        {
          token buff;
          buff.number=atoi(str+i);
          buff.tok=DIGIT;
          buff.prioritaet=3;
          op.push_back(buff);
          cout << i << endl; //[DEBUG]
          for(;str[i]&&isdigit(str[i]);++i);
          --i;
          cout << i << endl; //[DEBUG]
        }
        else if(str[i]=='(')
          klammer=true;
        else if(str[i]==')')
        {
          if(!klammer)
          {
        m_erg.set_text("syntax error )");
        return;
          }
          klammer=false;
        }
        else if(str[i]=='+')
        {
          token buff;
          buff.sign='+';
          buff.tok=ADD;
          buff.prioritaet=klammer ? 0 : 2;
          op.push_back(buff);
        }
        else if(str[i]=='-')
        {
          token buff;
          buff.sign='-';
          buff.tok=SUB;
          buff.prioritaet=klammer ? 0 : 2;
          op.push_back(buff);
        }
        else if(str[i]=='*')
        {
          token buff;
          buff.sign='*';
          buff.tok=MUL;
          buff.prioritaet=klammer ? 0 : 1;
          op.push_back(buff);
        }
        else if(str[i]=='/')
        {
          token buff;
          buff.sign='/';
          buff.tok=DIV;
          buff.prioritaet=klammer ? 0 : 1;
          op.push_back(buff);
        }
        else if(str[i]=='%')
        {
          token buff;
          buff.sign='%';
          buff.tok=MOD;
          buff.prioritaet=klammer ? 0 : 1;
          op.push_back(buff);
        }
        else if(isspace(str[i]))
          continue;
        else
        {
          cout << "err: " << str[i] << endl; //[DEBUG]
          m_erg.set_text("syntax error");
          return;
        }
      }
      cout << endl; //[DEBUG]
      cout << op.size() << endl; //[DEBUG]
      for(int prior=0;prior<3;++prior)
      {
        for(vector<token>::iterator i=op.begin();i!=op.end();++i)
        {
          cout << "- " << i->tok << " " << i->number << " " << i->prioritaet << " " << prior << endl; //[DEBUG]
          if(i->prioritaet!=prior)
        continue;
          cout << "+ " << i->tok << " " << i->number << " " << i->prioritaet << " " << prior << endl; //[DEBUG]
          switch(i->tok)
          {
          case ADD:
          {
        vector<token>::iterator op1=i-1;
        vector<token>::iterator op2=++i;
        if(op1->tok!=DIGIT||op2->tok!=DIGIT)
            {
          m_erg.set_text("syntax error +");
          return;
        }
        op1->number=op2->number+=op1->number;
          }
          break;
          case SUB:
          {
        vector<token>::iterator op1=i-1;
        vector<token>::iterator op2=++i;
        if(op1->tok!=DIGIT||op2->tok!=DIGIT)
        {
          m_erg.set_text("syntax error -");
          return;
        }
        op2->number=op1->number-=op2->number;
          }
          break;
          case MUL:
          {
        vector<token>::iterator op1=i-1;
        vector<token>::iterator op2=++i;
        if(op1->tok!=DIGIT||op2->tok!=DIGIT)
            {
          m_erg.set_text("syntax error *");
          return;
        }
        op1->number=op2->number*=op1->number;
          }
          break;
          case DIV:
          {
        vector<token>::iterator op1=i-1;
        vector<token>::iterator op2=++i;
        if(op1->tok!=DIGIT||op2->tok!=DIGIT)
        {
          m_erg.set_text("syntax error /");
          return;
        }
        op2->number=op1->number/=op2->number;
          }
          break;
          case MOD:
          {
        vector<token>::iterator op1=i-1;
        vector<token>::iterator op2=++i;
        if(op1->tok!=DIGIT||op2->tok!=DIGIT)
        {
          m_erg.set_text("syntax error %");
          return;
        }
        op2->number=op1->number%=op2->number;
          }
          break;
          }
        }
      }
      stringstream s;
      s << (--op.end())->number;
      m_erg.set_text(s.str());
    }
    
    int main(int argc, char **argv)
    {
      Main rechner_main(argc,argv);
      rechner_win rwin;
      rechner_main.run(rwin);
    }
    

    irgend wie erhalte ich immer einen syntax error, wenn ich folgendes eingebe

    1+1*2

    Seht ihr den Fehler? Bin schon am verzweifeln 😞

    [ Dieser Beitrag wurde am 13.11.2002 um 21:27 Uhr von kingruedi editiert. ]

    [ Dieser Beitrag wurde am 13.11.2002 um 22:35 Uhr von kingruedi editiert. ]



  • Hallo

    Vermutlich liegt der Fehler darin, dass du das Argument "Klammer" erst nach der Abfrage auf false setzt.

    else if(str[i]==')')
    {
    if(klammer)
    {
    m_erg.set_text("syntax error )");
    return;
    }
    klammer=false;
    }

    gruss sam



  • hast recht, es müsste if(!klammer) heissen. Aber daran sollte es nicht liegen, da ich ja gar keine klammern benutze.



  • Komisch dass man dir als Mod sowas sagen muß, aber:
    Wieso reduzierst du das Problem nicht auf ein überschaubares Programm? Mit dem gtkmm-Kram kann ich nix anfangen, auch wenn ich den Fehler sonst vielleicht finden würde.
    Hast du's mal mit nem Debugger versucht? Du gibst an mehreren Stellen die gleiche Fehlermeldung aus, und weißt nicht ohne weiteres welche Stelle es denn nun war.



  • hatte ich auch vorhin schon gesagt, aber das schlimmste ist, das er diesen tipp ignoriert und sogar den beitrag noch gelöscht hat. 😞



  • ah, hat er ja doch weitestgehend rausgenommen. aber könntest du den source noch so umbauen das man ihn direkt benutzen und dran rumspielen kann?



  • Wo der Fehler genau ist weiss ich nicht, irgend wo in der Schleife. Da kamen mit dem Debugger nur merkwürdige Ergebnisse raus.

    Das Problem liegt aber wohl irgend wo bei GTKmm, da ich in der Konsolen Version keine Probleme habe.


Anmelden zum Antworten