Frage zur lexikalischen Syntax



  • Wie muss dieses Programm in Preprocessing Tokens zerlegt werden?

    012345678
    

    Laut Standard müsste es «01234567», «8» sein, jedenfalls finde ich nirgends eine extra Aussage darüber, wodurch Tokens getrennt werden, ausser durch Zeichen, die nicht mehr ins Muster passen. gcc liest dort nur ein Token und beschwert sich über ein unzulässiges Zeichen in einem Oktal-Literal.

    Mir ist klar, dass die Frage in höchstem Maße akademisch ist, weil beide Interpretationen zu einem nicht wohlgeformten Programm führen. Vielleicht überseh ich aber auch nur etwas.



  • Bashar schrieb:

    Wie muss dieses Programm in Preprocessing Tokens zerlegt werden?

    012345678
    

    Laut Standard müsste es «01234567», «8» sein, jedenfalls finde ich nirgends eine extra Aussage darüber, wodurch Tokens getrennt werden, ausser durch Zeichen, die nicht mehr ins Muster passen. gcc liest dort nur ein Token und beschwert sich über ein unzulässiges Zeichen in einem Oktal-Literal.

    Mir ist klar, dass die Frage in höchstem Maße akademisch ist, weil beide Interpretationen zu einem nicht wohlgeformten Programm führen. Vielleicht überseh ich aber auch nur etwas.

    Der endliche Automat zur Erkennung von Oktalzahlen wird halt durch die 8 in einen Fehlerzustand versetzt. Woher soll der Automat wissen, das jetzt bei der 8 eine neue Zahl beginnt?



  • meine interpretation ist folgende:
    er müsste 01234567 als token erkennen und 8 als token
    denn er liest soviel ein, wie das token nur haben kann.
    und 8 gehört definitiv nicht mehr zu 01234567



  • tobidope schrieb:

    Der endliche Automat zur Erkennung von Oktalzahlen wird halt durch die 8 in einen Fehlerzustand versetzt.

    Genauso wie er beispielsweise durch + oder Whitespace in einen Fehlerzustand versetzt wird. Er schließt damit die Tokenerkennung mit einem Zeichen vorher ab und behandelt die 8 als Start des nächsten Tokens.

    Woher soll der Automat wissen, das jetzt bei der 8 eine neue Zahl beginnt?

    8 ist ein gültiges erstes Zeichen für ein Dezimalzahlen- oder Float-Literal.

    BTW du brauchst nicht soviel zitieren, mein Beitrag läuft ja nicht weg.

    Shade: Aber was ist mit z.B. «45z». gcc parset das als ein Token. Würden es 2 Token sein, könnte man daraus mit einem #define z + 2 oder so sogar gültigen Code machen. Wo lesen die im Standard heraus, dass das nicht geht?



  • [quote="Bashar]
    Shade: Aber was ist mit z.B. «45z». gcc parset das als ein Token. Würden es 2 Token sein, könnte man daraus mit einem #define z + 2 oder so sogar gültigen Code machen. Wo lesen die im Standard heraus, dass das nicht geht?[/quote]

    Läuft eine komplette lexikalische Analyse nicht erst nach dem Präprozessor?



  • Bashar schrieb:

    Aber was ist mit z.B. «45z». gcc parset das als ein Token. Würden es 2 Token sein, könnte man daraus mit einem #define z + 2 oder so sogar gültigen Code machen. Wo lesen die im Standard heraus, dass das nicht geht?

    Ein preprocessing token ist im Wesentlichen immer die längste Zeichenkette, die ein preprocessing token darstellen könnte (6.4#4).

    45z ist eine preprocessing number, wie fast alles, das aus der Entfernung wie eine Zahl aussieht.

    Edit: Ich bezog mich auf die C-Norm, weil ich mich im C-Forum vermutete... Soll ich die entsprechenden Paragraphen aus der hier passenden Norm suchen?



  • Daniel E. schrieb:

    Ein preprocessing token ist im Wesentlichen immer die längste Zeichenkette, die ein preprocessing token darstellen könnte (6.4#4).

    45z kann aber kein preprocessing token darstellen. Es gibt keine Klasse, der es zugehörig wäre.

    45z ist eine preprocessing number, wie fast alles, das aus der Entfernung wie eine Zahl aussieht.

    «1 Preprocessing number tokens lexically include all integral literal
    tokens (_lex.icon_) and all floating literal tokens (_lex.fcon_).» -- 2.9p1 (wir unterhalten uns doch über C++*). Also nicht alles, was irgendwie nach Zahl aussieht.

    EDIT: 😉 Die C- und C++-Normen scheinen sich in diesem Punkt nicht zu unterscheiden, es werden sogar die gleichen Beispiele benutzt.



  • tobidope schrieb:

    Läuft eine komplette lexikalische Analyse nicht erst nach dem Präprozessor?

    Meinem Verständnis nach werden die PP-Tokens nach dem Präprozessor nochmal genauer identifiziert, aber es gibt nicht nochmal eine lexikalische Analyse.



  • Bashar schrieb:

    Daniel E. schrieb:

    Ein preprocessing token ist im Wesentlichen immer die längste Zeichenkette, die ein preprocessing token darstellen könnte (6.4#4).

    45z kann aber kein preprocessing token darstellen. Es gibt keine Klasse, der es zugehörig wäre.

    45z ist eine preprocessing number, wie fast alles, das aus der Entfernung wie eine Zahl aussieht.

    «1 Preprocessing number tokens lexically include all integral literal
    tokens (_lex.icon_) and all floating literal tokens (_lex.fcon_).» -- 2.9p1 (wir unterhalten uns doch über C++*). Also nicht alles, was irgendwie nach Zahl aussieht.

    Doch. Nur weil darsteht, das sie alle integralen und Fließkommazahlen enthalten, bedeutet das nicht, das sie nicht auch etwas anderes enthalten. 123abc ist, genau wie 45z eine preprocessing number. In der Grammatik greift der "nondigit"-Abschnitt.



  • Daniel E. schrieb:

    In der Grammatik greift der "nondigit"-Abschnitt.

    Wo kommt der auf einmal her?! 🙄 Das erklärt natürlich alles. Hintergrund: Ich bastel grad ein bisschen mit flex rum und wundere mich ... naja aber gut, dass wir mal drüber geredet haben, macht den Thread von mir aus zu 😉



  • Ich stimme Daniel E. zu
    denn soweit ich den Standard verstehe, ist 012345678 eine PP-Number

    um [lex.pptoken] zu zitieren

    [Example: The program fragment 1Ex is parsed as a preprocessing number token (one that is not a valid floating or integer literal token), even though a parse as the pair of preprocessing tokens 1 and Ex might produce a valid expression (for example, if Ex were a macro defined as +1). Similarly, the program fragment 1E1 is parsed as a preprocessing number (one that is a valid floatung literal token), wheter or not E is a macro name]


Anmelden zum Antworten