Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 717

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

1

19.07.2017, 02:04

Was ist genau ein Token?

Hi,
wie der Titel schon verrät, versuche ich mich wieder daran einen Parser/Serializer zu schreiben.
Die Betonung liegt auf dem Versuch.

Aktuell arbeite ich an einem Tokenizer für eine Sprache, die wie folgt aussieht:

C-/C++-Quelltext

1
2
3
4
5
identifier:
    identifier1: 1234
    identifier2: "abcde"
    identifier3:
        identifier4: 1234


Ich bin mir aktuell nicht sicher, wie ich den Tokenizer schreiben soll, bzw. was ich als Token auffassen soll.

Was wäre da jetzt genau ein Token? Ein einzelnes Symbol z.B.: "i" aus Identifier oder
wäre "identifier" an sich ein Token?

Ich bin ziemlich planlos.
LG Julien

P.S.: An meiner Uni gibt es leider keinen Kurs "Compilerbau", daher versuche ich es mir selbst beizubringen.
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

19.07.2017, 06:49

https://en.m.wikipedia.org/wiki/Lexical_analysis#Token

Token, die ich bei dir sehe: Identifier, Doppelpunkt, String-Literal, Integer-Literal, Zeilenumbruch, Tab. Die letzten beiden sind deshalb Token, weil sie scheinbar eine Bedeutung haben (Zeilenumbruch als Abschluss der Wertzuweisung, Tab für Verschachtelung).

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

3

19.07.2017, 10:12

Token, die ich bei dir sehe: Identifier, Doppelpunkt, String-Literal, Integer-Literal, Zeilenumbruch, Tab. Die letzten beiden sind deshalb Token, weil sie scheinbar eine Bedeutung haben (Zeilenumbruch als Abschluss der Wertzuweisung, Tab für Verschachtelung).

Ich vermute dass soll eine Grammatik sein und die Sprache setzt sich aus den Literalen 1234 und "abcde" zusammen, wobei die Grammatik dann nicht eindeutig wäre da 1234 zwei verschiedene Ableitungen besitzt.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

19.07.2017, 10:31

Nee, das ist sicher keine Grammatik, sondern ein Beispiel für ein gültiges „Wort“ der Sprache.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

5

19.07.2017, 11:06

Nee, das ist sicher keine Grammatik, sondern ein Beispiel für ein gültiges „Wort“ der Sprache.

Stimmt. Er schreibt es sogar. Dann hast du natürlich recht.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

21.07.2017, 06:46

Bei den meisten Sprachen werden Token übrigens durch Leerzeichen getrennt. Man könnte bei diesen Sprachen sagen: Ein Token ist alles, wo du kein Leerzeichen mittendrin einfügen kannst, ohne das Programm zu verändern oder kaputt zu machen. In C/C++ sind beispielsweise sämtliche Keywords Token. return ist z. B. ein Token, denn wenn ich ret urn daraus mache, ändere ich das Programm. Ein Integer-Literal ist auch ein Token, denn 123456 und 12 34 56 sind für den Compiler nicht das gleiche.

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 717

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

7

21.07.2017, 07:05

Hi,
danke für die Antworten! :-)

Nee, das ist sicher keine Grammatik, sondern ein Beispiel für ein gültiges „Wort“ der Sprache.


Jep, das war nur ein Beispiel. Ich habe die Syntax mit EBNF "skizziert", d.h. es sind bestimmt noch Fehler drin.
Hier ein Umriss:

C-/C++-Quelltext

1
2
3
4
Identifier     := letter {(letter | digit)};
literal        := int_literal | string_literal;
int_literal    := digitWZ {digit};
string_literal  := '"' {(letter | digit)} '"';


Mein Ansatz soweit zum tokenizing sieht in etwa so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
std::string getIndentifier(const std::string& line, std::vector<Token>& outTokens);
std::string getValue(const std::string& line, std::vector<Token>& outTokens);

void        tokenizeLine(const std::string& line, std::vector<Token>& outTokens){
    std::string pipe{};
    pipe = getIdentifier(line, outTokens);
    pipe = getValue(line, outTokens);
}


Die Idee war, dass jede Zeile einzeln nach Tokens "transformiert" wird.
Ist dieser Ansatz richtig?

LG Julien
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Julién« (21.07.2017, 07:24)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

21.07.2017, 07:09

Kommt darauf an, was diese Funktionen machen!
Es heißt übrigens Identifier, nicht Indentifier. Das hat nichts mit Einrücken zu tun.

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 717

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

9

21.07.2017, 07:19

Sorry, Tippfehler.

Die Funktionen bearbeiten den übergebenen String und geben einen Substring ohne den Bestandteil zurück.
Wenn die Zeile beispielsweise einen Identifier enthält, dann gibt die Funktion die Zeile ohne den Identifier zurück, so dass für den nächsten Schritt nur noch Literale (oder im Falle einer Objektdefinition, nichts) übrig bleiben.
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

21.07.2017, 08:02

Da Whitespaces allgemein in deiner Grammatik keine Rolle zu spielen scheinen musst du eigentlich nur am Anfang alle Whitespaces verwerfen bis du auf ein anderes Zeichen triffst. Dann ließt du die Zeichen des aktuellen Tokens ein und bestimmt die Art des Token. Das ganze verpackst du dann in ein Objekt und gibst es zurück. Jetzt gibt es verschiedene Möglichkeiten. Dein Tokenizer (oft auch Scanner oder Lexer genannt) kann jetzt jeweils ein einzelnes Token zurück geben und sich die aktuelle Position im Quelltext merken, oder aber du ließt den gesamten Quelltext ein und gibst direkt eine Liste von deinen Tokens wieder. Der erste Ansatz hat ein paar Vorteile. Das ganze wird dann normalerweise von deinem Parser benutzt welcher die Tokens weiter verarbeitet. Für den Anfang ist es vielleicht ganz hilfreich wenn du dir mal ein flex & bison Tutorial ansiehst. Da werden Lexer und Parser zwar generiert, dir sollte aber klar werden wie du mit beiden Bausteinen zusammen arbeitest. Ansonsten solltest du mit den Stichworten Lexer und Scanner aber auch genug Material bei Google finden um zu sehen wie man so ein Teil von Hand baut.
Ich habe mal einen recht generischen Lexer geschrieben. Der hat einfach pro Token einen regulären Ausdruck und den zugehörigen Tokentyp bekommen und hat dann jeweils darauf geprüft und das passende Token zurück geliefert. Das ist zwar nicht besonders effizient, das war in dem Fall aber mehr als ausreichend.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige