Threadnecromantie von: "liste von tokens analysieren" (geteilt)



  • Edit pumuckl: Uralt-Originalthread: http://www.c-plusplus.net/forum/162904

    DocJunioR schrieb:

    du kannst beispielsweise prüfen, ob das Folgetoken ein = ist. Ist dem so, dann nimmst du das vorhergehende Token als Name und die nächsten bis zum Semikolon als Wert, getrennt mit Leerzeichen.

    Kann mir jemand sagen wie ich sowas prüfe?
    Ich mach das im Moment so:

    void Scanner::start(){
      getNextToken();
      if(TokenType(TT_FUNC)){
        std::cout << "prototype";
      }
      if(TokenType(TT_DOT)){
        std::cout << ".";
      }
      if(TokenType(TT_PUBLIC)){
        std::cout << "function" << "\n";
      }
    }
    

    Allerdings macht der das ja nur für ein Token, also nur einmal und die Reihenfolge muss ich ja dann vorgeben. Vielleicht erklärt mir das oben beschriebene noch einmal jemand. Oder sagt mir wonach ich suchen soll.



  • Ich würde Leerzeichen vor und nach = beim Scannen komplett ignorieren (beim Interpretieren sowieso). Du iterierst also durch den ganzen Vektor, und bei jedem Element n schaust du, ob das nächste Element (also n+1 ) ein "=" ist. Wenn ja, dann ist n ein Schlüssel. Das bedeutet automatisch, dass n+2 der Wert ist. Zum Speichern von interpretierten Tokens eignen sich std::maps ganz gut.

    Spoiler:

    std::vector<std::string> tokens;
    std::map<std::string, std::string> keysAndValues;
    
    for (int i = 0; i < tokens.size(); ++i)
    {
        if (tokens.at(i+1) == '=')
            keyAndValues.insert (std::pair<std::string, std::string>(tokens[i], tokens[i+2]))
        i +=2;
    }
    


  • [Rewind] schrieb:

    Ich würde Leerzeichen vor und nach = beim Scannen komplett ignorieren (beim Interpretieren sowieso). Du iterierst also durch den ganzen Vektor, und bei jedem Element n schaust du, ob das nächste Element (also n+1 ) ein "=" ist. Wenn ja, dann ist n ein Schlüssel. Das bedeutet automatisch, dass n+2 der Wert ist. Zum Speichern von interpretierten Tokens eignen sich std::maps ganz gut.

    Spoiler:

    std::vector<std::string> tokens;
    std::map<std::string, std::string> keysAndValues;
    
    for (int i = 0; i < tokens.size(); ++i)
    {
        if (tokens.at(i+1) == '=')
            keyAndValues.insert (std::pair<std::string, std::string>(tokens[i], tokens[i+2]))
        i +=2;
    }
    

    Das sieht doch schon mal gut aus. 🙂 Hab zwar noch nicht mit maps gearbeitet aber das kann man ja nun änder. 😉
    BTW: Du hast ein Fehler drin. 🙂 Nichts mit copy und paste bei dir. 😃 keysAndValues keyAndValues Nur ein kleiner vertipper. 😃

    Danke jedenfalls. Das hat mir schon mal viel geholfen.



  • Enno schrieb:

    DocJunioR schrieb:

    du kannst beispielsweise prüfen, ob das Folgetoken ein = ist. Ist dem so, dann nimmst du das vorhergehende Token als Name und die nächsten bis zum Semikolon als Wert, getrennt mit Leerzeichen.

    Kann mir jemand sagen wie ich sowas prüfe?
    Ich mach das im Moment so:

    void Scanner::start(){
      getNextToken();
      if(TokenType(TT_FUNC)){
        std::cout << "prototype";
      }
      if(TokenType(TT_DOT)){
        std::cout << ".";
      }
      if(TokenType(TT_PUBLIC)){
        std::cout << "function" << "\n";
      }
    }
    

    Allerdings macht der das ja nur für ein Token, also nur einmal und die Reihenfolge muss ich ja dann vorgeben. Vielleicht erklärt mir das oben beschriebene noch einmal jemand. Oder sagt mir wonach ich suchen soll.

    Das was du da postest ist nicht mehr Aufgabe des Scanners, sondern des Parsers!

    Der Scanner zerlegt nur die Eingabe in ihre Tokens (das hast du ja schon). Du brauchst also jetzt eine Klasse Parser. Dieser Parser hat dann z.B. eine Funktion bool CheckToken(TokenType type); und diese Funktion überprüft dann, ob das Token korrekt ist und holt anschließend das nächste ab.

    Du hast dir ja den Artikel als Basis genommen, warum gehst du nicht danach vor? Es steht dort alles genau so beschrieben.

    Und der Code den [Rewind] gepostet hat, war nicht an dich gerichtet Enno, sondern an den Threadersteller...



  • ghjghj schrieb:

    Das was du da postest ist nicht mehr Aufgabe des Scanners, sondern des Parsers!

    Der Scanner zerlegt nur die Eingabe in ihre Tokens (das hast du ja schon). Du brauchst also jetzt eine Klasse Parser. Dieser Parser hat dann z.B. eine Funktion bool CheckToken(TokenType type); und diese Funktion überprüft dann, ob das Token korrekt ist und holt anschließend das nächste ab.

    Du hast dir ja den Artikel als Basis genommen, warum gehst du nicht danach vor? Es steht dort alles genau so beschrieben.

    Hmm... Ich versteh dadran allerdings nicht ganz warum ich prüfen muss ob die korrekt sind? Mir geht es ja dadrum sie zu übersetzen.

    ghjghj schrieb:

    Und der Code den [Rewind] gepostet hat, war nicht an dich gerichtet Enno, sondern an den Threadersteller...

    Ok allerdings wird der das nicht mehr brauchen. Ich hab den Thread ja wieder ausgegraben. Ich mein der ist von 2006 ... 🤡



  • Enno schrieb:

    Ich hab den Thread ja wieder ausgegraben. Ich mein der ist von 2006 ... 🤡

    Sowas tut man auch nicht. Neue Frage, neuer Thread. So einfach ist das.



  • pumuckl schrieb:

    Sowas tut man auch nicht. Neue Frage, neuer Thread. So einfach ist das.

    Wusste ich nicht. 😞
    Danke fürs ändern. 👍


Anmelden zum Antworten