Nino hat geschrieben:Sicro hat geschrieben:Nino hat geschrieben:Für mich ist es klar ein Bug im Makro-Preprocessor.
In der PB-Hilfe steht bei der Macro-Beschreibung nichts darüber, das Macros Namen von Variablen ersetzen (nehmen wir hier mal an, "*" wäre Bestandteil des Variable-Namens), sondern das der Macro-Name (Macro-Aufruf) durch den Macro-Inhalt ersetzt wird.
Ja und
Es kann also laut der Beschreibung in der PB-Hilfe schon kein Bug sein. Laut der Beschreibung könnte es auch sein, dass der PB-Compiler die Macro-Namen so ersetzt:
Code: Alles auswählen
ReplaceString(codeNachdemMacroDefinitionBlock$, macroName$, macroInhalt$)
Somit ist
entsprechend der Beschreibung korrekt.
Aber wir wissen es ja besser als die PB-Hilfe, dass die Macros Tokens ersetzen. Da stimmt ihr mir ja zu und das beweist auch dein nachfolgender Code, in dem die Variable "aXXX" nicht vom Macro "XXX" ersetzt wird.
Nino hat geschrieben:Der Makro-Name soll nur an den Stellen im Quelltext durch den Makro-Inhalt ersetzt werden, an denen er als eigenständiges Token auftaucht.
Deshalb wird auch im folgenden Code
Code: Alles auswählen
Macro XXX
YYY
.
EndMacro
Define aXXX ; Zeile 6
Define *XXX
in Zeile 6 der Makro-Name richtigerweise nicht durch den Makro-Inhalt ersetzt. Und in Zeile 7 sollte es ebenfalls nicht geschehen. Es passiert aber doch, das ist der Bug.
Die Macro-Aufrufe werden wie schon geschrieben nur auf Lexer-Ebene ersetzt, daher wird "*XXX" als zwei Tokens gelesen und das zweite Token ("XXX") passt zum Macro-Name.
https://en.wikipedia.org/wiki/Lexical_analysis
Wikipedia hat geschrieben:There are exceptions, however. Simple examples include: semicolon insertion in Go, which requires looking back one token; concatenation of consecutive string literals in Python,[10] which requires holding one token in a buffer before emitting it (to see if the next token is another string literal); and the off-side rule in Python, which requires maintaining a count of indent level (indeed, a stack of each indent level). These examples all only require lexical context, and while they complicate a lexer somewhat, they are invisible to the parser and later phases.
Sicro hat geschrieben:Wie einleitend geschrieben wird sind das aber Ausnahmen und nicht das normale Vorgehen von einem Lexer.
Ich war an diesem Tag wohl bereits zu müde, um das richtig zu verstehen. Als Überschrift steht dort "Context-sensitive lexing". Die rede ist also nicht von dem Lexer, sondern um den Prozess "Lexen". Es bleibt also ausnahmslos dabei: Ein Lexer erstellt Tokens und nur der Parser betrachtet Zusammenstellungen mehrerer Tokens. Für "Kontextabhängiges Lexen" kommt der Parser ins Spiel.
Nino hat geschrieben:Was Ausnahmen sind und was nicht ist eine Frage der Statistik, darum geht es hier überhaupt nicht. Wenn eine Situation eintritt, in welcher der Lexer zunächst nicht "weiß" welches Zeichen zu welchem Token gehört, so muss er halt Schritte unternehmen, um das herauszufinden. Was hat das damit zu tun wie häufig so eine Situation eintritt? Gar nichts.
"Was Ausnahmen sind und was nicht ist eine Frage der Statistik". Bis jetzt habe ich immer wieder nur gelesen, dass Lexer Zeichen zu Tokens gruppiert und nur der Parser mit Zusammenstellungen von Tokens arbeitet, nicht der Lexer. Somit sehe ich keine Kehrwendung von "Ausnahme" zu "neuem Standard".
Wenn es wirklich eine Lexer-Ausnahme gegeben hätte (siehe mein Missverständnis oben bezüglich "Context-sensitive lexing"), die den Lexer kontextabhängig arbeiten lässt, dann wäre das hier sehr wohl relevant gewesen, weil für das Lexen von "*PointerVariable" als ein Token der Lexer kontextabhängig und somit nach dem Ausnahme-Verfahren arbeiten müsste. Demnach wären eure Aussagen hier:
Lexer-Standard-Verfahren: Bug!
Lexer-Ausnahme-Verfahren: Richtig!
Wenn der Lexer ohne Kontext die Tokens nicht richtig zuordnen kann, hift der Parser:
https://en.wikipedia.org/wiki/The_lexer_hack
Beim Lexer meine ich mit Kontext die anderen Tokens, weil bei Zeichen darf sich der Lexer ja umschauen, nur nicht bei anderen Tokens.
Ich sehe deshalb nur ein Feature-Request für richtig, wenn ihr euch ein anderes Verhalten der Macro-Auflösung wünscht, und kein Bug-Report.
-------------
Ich habe noch etwas weiter nachgeforscht.
Kopiert mal folgenden Code in eure PB-IDE und führt in aus:
Code: Alles auswählen
Macro BinaryNumber
101
EndMacro
Macro HexNumber
A
EndMacro
Macro Identifier
TestIdentifier
EndMacro
Macro Identifier2
TestIdentifier2
EndMacro
Debug %BinaryNumber
Debug $HexNumber
Identifier$ = "StringVariable: Ein Test"
Debug TestIdentifier$
*Identifier = 123
Debug *TestIdentifier
;#Identifier = "Constant: Ein Test"
;Debug #TestIdentifier
Procedure Identifier()
Debug "Procedure: Ein Test"
EndProcedure
TestIdentifier()
Structure TestStruc
Array Identifier.i(0)
Identifier2.i[1]
EndStructure
Test.TestStruc
Test\TestIdentifier(0) = 123
Test\TestIdentifier2[0] = 456
Debug Test\TestIdentifier(0)
Debug Test\TestIdentifier2[0]
Das Verhalten ist auch bei den anderen Bezeichner-Prefixen/Suffixen durchgehend konsistent, außer bei den Konstanten.
Wenn "*PointerVariable" ein einzelnes Token wäre, könnte man mit einem Macro diese Variable nicht ersetzen, weil ein Macro-Name kein "*" enthalten darf.
Procedure/Array/List/Map-Namen könnte man ebenfalls nicht ersetzen, weil die öffnende Klammer Bestandteil des Tokens wäre und Macro-Namen aber nicht nur eine öffnende Klammer am Ende haben dürfen.
Nur normale Variablen könnte man dann mit Macros ersetzen, weil nur die im Namen Zeichen enthalten, die auch bei den Macro-Namen verwendet werden können.
Und ja, in der PureBasic-Sprache gehört das Sternzeichen zur Pointer-Variable und wird aber später beim Token weggelassen (Token-Typ auf "Pointer-Variable" stellen reicht ja), weil bei der ASM-Ausgabe ist das Sternchen wieder weg (siehe ASM-Ausgabe bei einem vorherigem Post von mir) und der PB-Compiler macht denke ich nicht sowas:
Code: Alles auswählen
asmPointerVariableName$ = ReplaceString(originalPointerVariableName$, "*", "p_")
Wir reden hier aber von der Macro-Verarbeitung und da sieht es anders aus.
Wie es wirklich unter der Haube läuft, wissen natürlich nur die PB-Entwickler.