Macro ändert Pointernamen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Macro ändert Pointernamen

Beitrag von Josh »

Warum ändert ein Macro den Pointernamen?

Code: Alles auswählen

Macro XXX
  YYY
  .
EndMacro

Define *XXX
*XXX ist in Pb doch ein eigenständiger Bezeichner und hat überhaupt nicht mit XXX zu tun.
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: Macro ändert Pointernamen

Beitrag von #NULL »

Trifft auch auf $ zu (da das gerade im englischen Forum Thema war)

Code: Alles auswählen

Macro XXX
  YYY
  .
EndMacro

Define XXX$
Würde ich als Bug bezeichnen.
my pb stuff..
Bild..jedenfalls war das mal so.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Macro ändert Pointernamen

Beitrag von GPI »

Das mit * ist nicht so ganz einfach:
a=b*xxx

soll da verwandelt werden?

Man darf nicht vergessen: Macros sind quasi ein Preprocessor, der weiter nichts analysiert. Es schaut, ob der gesuchte Begriff zwischen Trennzeichen/Whitespaces auftaucht und ersetzt sie. Ob das jetzt ein Pointer oder sonstwas ist, wird nicht kontrolliert.

Edit: Generell würde ich empfehlen, gleiche Namen nicht überall zu nehmen, auch wenns möglich ist. Gebt den Zeug lieber eindeutige Namen und verwedet sie nicht bei Variablen, structuren, labels, Konstanten und Procedure/Listen gleichzeitig. Auch wenns möglich ist.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Macro ändert Pointernamen

Beitrag von Sicro »

Das ist schon richtig so, weil Macros Tokens ersetzen.

Code: Alles auswählen

Define *XXX
wird vom PB-Lexer zu folgenden Tokens verarbeitet:
  • Define
  • *
  • XXX

Code: Alles auswählen

Define XXX$ 
zu folgenden Tokens:
  • Define
  • XXX
  • $
Ob das "*"-Zeichen zu einer Pointer-Variable gehört oder ob es ein mathematischer Operator ist, bestimmt später der PB-Parser.

Dass das "$"-Zeichen ebenfalls ein separater Token ist, wusste ich noch nicht. Gut zu wissen. :)
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: Macro ändert Pointernamen

Beitrag von Josh »

Sicro hat geschrieben:Das ist schon richtig so, weil Macros Tokens ersetzen.
Es ist verständlich, aber richtig ist es deswegen noch lange nicht. Aufgrund des Vorgängertokens würde sich eindeutig feststellen lassen, dass es sich bei *XXX um einen Token handelt. In Pb ist das Sternchen vor einem Pointer eben kein Adressoperator sondern ist Bestandteil des Variablennamens.

Naja, auf einen Bugreport oder Eintrag in die Wishlist werde ich verzichten, ändern wird sich da nichts. Muss halt damit leben :lol:
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Macro ändert Pointernamen

Beitrag von Sicro »

Josh hat geschrieben:Aufgrund des Vorgängertokens würde sich eindeutig feststellen lassen, dass es sich bei *XXX um einen Token handelt.
Macros werden auf Lexer-Ebene (betrachtet jedes Token separat) ersetzt und nicht auf Parser-Ebene (betrachtet die Konstellation von Tokens), darum ist keine eindeutige Feststellung möglich.
Josh hat geschrieben:aber richtig ist es deswegen noch lange nicht
Es ist vielleicht nicht die beste Verarbeitungsart, aber falsch ist es nicht.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: Macro ändert Pointernamen

Beitrag von #NULL »

Ob das zwei separate Tokens sind oder ob sie zu einem gehören hängt doch auch vom Kontext ab und nicht nur vom Zeichen. Wenn das ganze innerhalb eines zuvor geöffneten Strings steht ist * ja auch kein Operator mehr. Selbst wenn im Fall von 'a=b*xxx' das 'b' ein Macro ist und zu 'x*' aufgelöst wird, dann ist der Kontext damit wieder klar und das zweite * kann dann kein Operator sein.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Macro ändert Pointernamen

Beitrag von Sicro »

#NULL hat geschrieben:Wenn das ganze innerhalb eines zuvor geöffneten Strings steht ist * ja auch kein Operator mehr.
Richtig. In dem Fall ist das "*"-Zeichen weder ein Operator noch ein Token und wird vom String-Token als normales Zeichen konsumiert. Bei Strings ist es aber auch einfach, weil der Lexer weiß, wo der String beginnt (beim öffnenden Anführungszeichen) und wo er aufhört (beim schließendem Anführungszeichen). Dazwischen wird jedes Zeichen konsumiert und als Teil des Strings interpretiert.
#NULL hat geschrieben:Ob das zwei separate Tokens sind oder ob sie zu einem gehören hängt doch auch vom Kontext ab und nicht nur vom Zeichen.

Code: Alles auswählen

c=a*b
Wie willst du bei dem obigem Code ermitteln, ob "*b" ein Pointer-Variable-Token oder ein Operator-Token ist, ohne zu prüfen, ob "a" ein Variable-Token ist (Aufgabe des Parsers, nicht des Lexers)?
#NULL hat geschrieben:Selbst wenn im Fall von 'a=b*xxx' das 'b' ein Macro ist und zu 'x*' aufgelöst wird, dann ist der Kontext damit wieder klar und das zweite * kann dann kein Operator sein.
Wie oben schon geschrieben: Ein Lexer betrachtet keine Konstellationen von Tokens. Das macht der Parser.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: Macro ändert Pointernamen

Beitrag von Josh »

Sicro hat geschrieben:

Code: Alles auswählen

c=a*b
Wie willst du bei dem obigem Code ermitteln, ob "*b" ein Pointer-Variable-Token oder ein Operator-Token ist, ohne zu prüfen, ob "a" ein Variable-Token ist (Aufgabe des Parsers, nicht des Lexers)?
Nein, das ist sehr wohl die Aufgabe des Lexers. Ein Lexer ordnet den Tokens zu, ob es sich um einen Bezeichner, Operator, Literal, Trennzeichen oder sonst was handelt. Da 'a' nur ein Bezeichner sein kann, kann kein weiterer Bezeichner folgen und somit ist das '*' ein Operator und 'b' in weiterer Folge wieder ein Bezeichner.

*AnyPointer ist genau so ein einziger Token wie 1.23 oder 1.234e5. Alles andere wäre auch widersinnig. Der Parser könnte z.B. nicht mehr erkennen, dass bei 'a = b + * AnyPointer' ein Syntax-Fehler auszugeben ist, da der Parser von Leerzeichen/Tabs nichts mehr weiß.
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Macro ändert Pointernamen

Beitrag von Sicro »

Josh hat geschrieben:Nein, das ist sehr wohl die Aufgabe des Lexers.
Ein Lexer prüft keine vorherigen oder nachfolgenden Tokens. Er arbeitet überhaupt nicht mit Tokens, sondern erstellt sie nur, und zwar aus Zeichenfolgen, die einem bestimmtem Muster verlaufen.
Der Parser verarbeitet danach nur noch die Tokens und keine einzelnen Zeichen mehr.
Josh hat geschrieben:Ein Lexer ordnet den Tokens zu, ob es sich um einen Bezeichner, Operator, Literal, Trennzeichen oder sonst was handelt.
Korrekt. Ich behaupte, aber nirgends was anderes.
Josh hat geschrieben:Da 'a' nur ein Bezeichner sein kann, kann kein weiterer Bezeichner folgen und somit ist das '*' ein Operator und 'b' in weiterer Folge wieder ein Bezeichner.
Dem Lexer ist es egal, ob die Syntax des Codes stimmt oder nicht. Er erstellt einfach die Tokens, ohne irgendetwas Weiteres zu prüfen. Das, was du im Zitat schreibst, prüft der Parser, nicht der Lexer.
Josh hat geschrieben:Alles andere wäre auch widersinnig. Der Parser könnte z.B. nicht mehr erkennen, dass bei 'a = b + * c' ein Syntax-Fehler auszugeben ist, da der Parser von Leerzeichen/Tabs nichts mehr weiß.
Es ist nicht so üblich, dass Lexer bei Leerzeichen Tokens erstellen, aber ausgeschlossen ist es nicht.
Hier kannst du es nachlesen: https://en.wikipedia.org/wiki/Lexical_analysis
Die deutsche Version des Wikipedia-Artikels ist leider nicht so umfangreich beschrieben.
In dem Wikipedia-Artikel findest du die relevanten Textstellen, wenn die Textsuchfunktion des Browsers mit "whitespace" fütterst.

[bezeichner_a] [operator_=] [bezeichner_b] [operator_+] [operator_*] [leerzeichen] [bezeichner_c]
"c" ist somit keine Pointer-Variable, weil zwischen "*" und Bezeichner kein Leerzeichen sein darf.
Zwischen den anderen Tokens können natürlich ebenfalls Leerzeichen-Tokens sein, habe ich jetzt aber der einfachheitshalber mal weggelassen, weil der Parser selber entscheiden kann, ob er das Leerzeichen-Token an dieser Position berücksichtigt oder ignoriert.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Antworten