Seite 3 von 3

Re: Unicode Strings

Verfasst: 13.04.2013, 21:33
von Krishty
Artificial Mind hat geschrieben:Reden wir von UTF-8 als Enkodierung oder von Unicode als Zeichensatz?
Richtige Frage! Niki?

Re: Unicode Strings

Verfasst: 13.04.2013, 21:36
von Niki
Artificial Mind hat geschrieben:Ok dann möchte ich auch sicher gehen: Was unterscheidet einen UTF8-Lexer von einem normalen Lexer?
Wenn ich UTF-8 Lexer sage, dann meine ich damit, dass der eingehende Zeichenstrom UTF-8-kodiert ist. Ein Lexer fummelt sich zeichenweise durch den Strom und muss sich pro Zeichen oft die folgenden ein oder zwei Zeichen anschauen um ein Token erkennen zu können. Da ist eine Kodierung mit variablen Längen etwas störend. Hat man natürlich auch bei UTF-16, aber da ist es wesentlich überschaubarer.

Re: Unicode Strings

Verfasst: 13.04.2013, 21:39
von Niki
Krishty hat geschrieben:
Artificial Mind hat geschrieben:Reden wir von UTF-8 als Enkodierung oder von Unicode als Zeichensatz?
Richtige Frage! Niki?
Ich rede eigentlich schon die ganze Zeit von der Kodierung.

Re: Unicode Strings

Verfasst: 13.04.2013, 21:40
von Artificial Mind
Niki hat geschrieben:
Artificial Mind hat geschrieben:Ok dann möchte ich auch sicher gehen: Was unterscheidet einen UTF8-Lexer von einem normalen Lexer?
Wenn ich UTF-8 Lexer sage, dann meine ich damit, dass der eingehende Zeichenstrom UTF-8-kodiert ist. Ein Lexer fummelt sich zeichenweise durch den Strom und muss sich pro Zeichen oft die folgenden ein oder zwei Zeichen anschauen um ein Token erkennen zu können. Da ist eine Kodierung mit variablen Längen etwas störend. Hat man natürlich auch bei UTF-16, aber da ist es wesentlich überschaubarer.
Gut, dann habe ich dich nicht missverstanden und bleibe bei meiner Aussage: das ist wesentlich einfacher als man vielleicht zuerst denkt. Insbesondere kann man der sehr schön als kleinen endlichen Automaten modellieren. Mir hilft es immer das anders herum zu betrachten: ich muss nicht in die Zukunft gucken sondern das Emittieren eines Zeichens verzögert sich potentiell um 4 chars.

Re: Unicode Strings

Verfasst: 13.04.2013, 21:47
von Niki
Hmmm, da frage ich mich wie du einen Lexer schreibst. Bei mir ist das ein Switch-Block mit cases der folgenden Art:

Code: Alles auswählen

            case '/': // /, //, /*, /=
            {
                if (*p == '=')
                {
                    p++;
                    EmitToken(p, TokenId_SlashEqual);
                }
                else if (*p == '/')
                {
                    p++;

                    if (*p == '/')
                    {
                        p++;
                        SkipDocumentationComment(p);
                    }
                    else    
                    {
                        SkipLineComment(p);
                    }
                }
                else if (*p == '*')
                {
                    p++;
                    SkipBlockComment(p);
                }
                else
                {
                    EmitToken(p, TokenId_Slash);
                }
                break;
            }
Aber damit kommen wir vom Thema ab :) Ist aber zugegebenermaßen meine eigene Schuld.

Re: Unicode Strings

Verfasst: 13.04.2013, 21:50
von Artificial Mind
Trotzdem mal als kurze Antwort:

Dein switch-case nimmt ja einzelne chars an. Du kannst es aber auch einfach ints (in UTF32) annehmen lassen. Dort kommen dann direkt die dekodierten utf8-chars rein.
Quasi so:

Code: Alles auswählen

processUtf8Input(char c); // lies einzelne utf8 Zeichen ein und immer wenn eins komplett dekodiert werden kann wird processCodePoint mit dem dekodierten aufgerufen
processCodePoint(int c); // deine Funktion mit dem switch(c)

Re: Unicode Strings

Verfasst: 13.04.2013, 21:54
von Niki
Artificial Mind hat geschrieben:Dein switch-case nimmt ja einzelne chars an.
Das sieht nur so aus. Diese Variable "p" ist bei mir in etwa so definiert:

Code: Alles auswählen

const UTF16 *& p = m_pSourceCurrent;
Zeichenkonstanten für z.B. '/' benutze ich nur für ASCII-7 Zeichen.

EDIT: Bitte beachten das das im alten Code so ist. Ich weiß auch nicht ob ich den Script-Compiler porten werde. Schließlich ist das ein separates Tool.

Re: Unicode Strings

Verfasst: 13.04.2013, 21:57
von Artificial Mind
Gut, du hast die Vorwärst-Variante genommen. Da hilft es, sich eine "int currCodePoint()" und eine "nextCodePoint()" Funktion zu basteln. Auch "peek(int)"s sind recht beliebt.

Ich kann dir ansonsten das hier empfehlen: http://cppgm.com/pa1.html Wenn du diese Aufgabe durch hast wirst du viel über Lexer manuell schreiben gelernt haben ;)

Re: Unicode Strings

Verfasst: 13.04.2013, 22:06
von Niki
Artificial Mind hat geschrieben:Gut, du hast die Vorwärst-Variante genommen. Da hilft es, sich eine "int currCodePoint()" und eine "nextCodePoint()" Funktion zu basteln. Auch "peek(int)"s sind recht beliebt.
Peek, Get und was noch alles habe ich früher immer benutzt. Heute benutze ich die nur noch im Parser. Ich finde das simple "p" einfacher, aber das merkt man erst wenn man's so benutzt. Der selben Auffassung scheint Microsoft übrigens auch zu sein (siehe C# Lexer in http://www.microsoft.com/en-us/download ... px?id=4917). Das soll jetzt übrigens nicht die Aussage "Wenn MS das so macht, dann ist es besser" sein. Soll rein informativ sein, falls es für jemanden interessant ist.

Re: Unicode Strings

Verfasst: 13.04.2013, 22:29
von Artificial Mind
Deine Lösung ist halt sehr einfach und bequem und gut nachvollziehbar, wird aber bei einigen Features echt problematisch. Denk mal an folgende C++ Features: Line Splicing (Wenn auf ein / ein Newline folgt, so werden beide Zeichen ignoriert), Universal Character Names (ein \uXXXX oder \UXXXXXXXX im Code wird direkt durch das Unicodezeichen ersetzt) und Trigraphen (z. B. ein "??!" wird durch "|" im Source ersetzt). Wenn du die alle und in Kombination unterstützen willst, dann viel Spaß mit deinem System ;)

Über Zustandsautomaten und konkatenierte Streams ist das allerdings elegant und verständlich lösbar. Wenn du dir übrigens Compilerbau-Vorlesungen anguckst, dann werden Lexer meistens als endliche Automaten modelliert. Das von dir erwähnte Flex arbeitet beispielsweise auch mit DFAs (endlichen Automaten).

Re: Unicode Strings

Verfasst: 13.04.2013, 22:41
von Niki
Artificial Mind hat geschrieben:Wenn du dir übrigens Compilerbau-Vorlesungen anguckst, dann werden Lexer meistens als endliche Automaten modelliert. Das von dir erwähnte Flex arbeitet beispielsweise auch mit DFAs (endlichen Automaten).
Mein Lexer ist ein DFA. Fängt mit einem Zeichen an und fummelt sich bis zum Ende eines Tokens durch den Graphen.

Du hast natürlich absolut recht, dass es Konstrukte gibt, für die mein Lexer ungeeignet ist. Aber ich will ja kein C++ für eine Script-Sprache haben. Zwar habe ich Klassen, die sind aber eher wie in Java oder C#. Natürlich alles abgespeckt, und selbst das ist für die meisten Scripter wahrscheinlich noch zu viel.

Re: Unicode Strings

Verfasst: 13.04.2013, 22:43
von Artificial Mind
Ja stimmt schon, für viele Lexer reicht dein Ansatz. Als ich vor nen paar Jahren mal einen Lexer + Parser für die Programmiersprache D geschrieben habe, hab ich auch direkt deinen Ansatz verfolgt und das funktionierte auch erstaunlich gut.

Re: Unicode Strings

Verfasst: 13.04.2013, 22:57
von Niki
Artificial Mind hat geschrieben:... und das funktionierte auch erstaunlich gut.
Ja, das sollte es in der Regel :) Viele Schwierigkeiten mit den Tokens liegen ja eh im Parser und nicht im Lexer. Zum Beispiel rauszufummeln ob >> nun ein Shift-Right-Operator ist, oder ob es zwei Klammern für das Ende eines geschachtelten Generics sind.

Aber egal jetzt... ich habe heute noch nichts geschafft, weil ich den ganzen Tag gechattet habe. :D Zeit produktiv zu werden.