Suche Tester für Purebasic Tokenizer

Du brauchst Grafiken, gute Programme oder Leute die dir helfen? Frag hier.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Suche Tester für Purebasic Tokenizer

Beitrag von NicTheQuick »

Hallo Leute,

ich habe einen Tokenizer geschrieben, der einen einfachen Purebasic-Quellcode ohne Includes in seine Einzelteile zerlegt. Das heißt er erkennt nur sehr einfache Fehler, wie falsche Zahlenkonstanten und vor allem falsche Macro-Deklarationen.
Ich habe ihn zum Testen auf Linux x64 und Windows x64 kompiliert und es würde mich freuen, wenn ihr mal ein paar eurer Quellcodes drauf los lässt.
Ein Fehler ist mir eben aufgefallen, den ich aber noch nicht ausgemerzt habe. String-Variablen mit dem $ am Ende werden nicht erkannt. Da sucht mein Tokenizer vergeblich nach einer Hexadezimalzahl.
Der größte getestete Code meinerseits bestand aus 11877 Zeilen und lief problemlos durch. Komischerweise brauchte ein Code mit nur 742 Zeilen auf Windows fast 6 Sekunden und auf Linux gerade mal 120 ms, beides natürlich ohne Debugger. Ich weiß noch nicht, wo da der Flaschenhals ist. Das Windows-Executable lief sogar unter WINE mehr als doppelt so schnell als unter einem richtigen Windows.

Toll wäre es, wenn ihr mal ein paar Codes von euch durchjagt und schaut, ob alle problemlos durchlaufen, wenn Purebasic selbst sie auch kompilieren kann. Zusätzlich würde ich mich natürlich freuen, wenn ihr extra mal Fehler einbaut und schaut, was er daraus macht.

Hier die Binaries: Tokenizer

Hier noch ein paar mögliche Fehlermeldungen.
Binary value without digits
Character not terminated.
Constant name can not begin with a number:
Digits not allowed in exponent:
EndMacro missing.
Hexadecimal value without digits
Illegal character after constant name: ?
Illegal character as begin of constant name: ?
Illegal character in constant name: ?
Invalid character after Macro definition: ?. Expecting :, CR or LF.
Invalid character after Macro name: ?. Expecting (, LF, CR or :.
Invalid character after number: ?
Invalid character in Macro name: ?. Expecting a-z, A-Z, 0-9 or _.
Invalid character in Macro parameter: ?. Expecting a-z, A-Z, _, = or comma.
Invalid digit in binary value:
Invalid digit in hexadecimal value:
Invalid escape character in parameters default value: ?
Invalid escape sequence in literal string: \?
Literal string not terminated.
Low memory
Macro definition ends unexpectedly.
Macro has no body.
Macro name begins with illegal character: ?. Expecting a-z, A-Z or _.
Macro name is empty.
Macro parameter already exists.
Memory low.
Missing ) after parameter definition.
Missing =, ) or comma.
No constant name specified.
No CR or LF allowed inside of a string in parameter default value.
No exponent specified: ?
No parameter specified.
Only one period allowed in number.
Parameter name begins with invalid character: ?. Expecting a-z, A-Z or _.
String not terminated.
Unexpected end of string in parameter default value.
Bild
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Re: Suche Tester für Purebasic Tokenizer

Beitrag von Helle »

Hallo Nic,
da ich für Strings das Format "String$" verwende und sich doch bei mir die eine oder andere ASM-Instruktion in den Code verirrt :mrgreen: , läuft bei mir nichts durch. Grund: Dein Programm wird bei der ersten Fehlermeldung beendet. Kannst Du das nicht ändern? Z.B. die Error-Zeile durch Einrücken optisch markieren, aber dann fortsetzen. Wenn nach etwas Fehlendem gesucht wird, sollte ja (spätestens) beim Zeilenende Schluss sein.
Gruß
Helle
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Suche Tester für Purebasic Tokenizer

Beitrag von STARGÅTE »

Ein paar Sachen komisch:
  • negative Zahlen bestehen aus 2 Token (Vorzeichen und Zahl), gewollt?
  • Pointer werden auseinander gerissen (* und Name), gewollt?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Suche Tester für Purebasic Tokenizer

Beitrag von NicTheQuick »

Helle hat geschrieben:Hallo Nic,
da ich für Strings das Format "String$" verwende und sich doch bei mir die eine oder andere ASM-Instruktion in den Code verirrt :mrgreen: , läuft bei mir nichts durch. Grund: Dein Programm wird bei der ersten Fehlermeldung beendet. Kannst Du das nicht ändern? Z.B. die Error-Zeile durch Einrücken optisch markieren, aber dann fortsetzen. Wenn nach etwas Fehlendem gesucht wird, sollte ja (spätestens) beim Zeilenende Schluss sein.
Ja, das kann ich mal machen. Ich mache einfach nach dem Error kein Break. :)
STARGÅTE hat geschrieben:Ein paar Sachen komisch:
  • negative Zahlen bestehen aus 2 Token (Vorzeichen und Zahl), gewollt?
  • Pointer werden auseinander gerissen (* und Name), gewollt?
Ja, ist beides gewollt. Darum kümmert sich dann der Parser. Der Tokenizer macht eben nur die Tokens. Da ist ein Minus ein eigenes Token, und ein * auch.
Aber bevor der Parser dran kommt, muss noch der Procompiler rein, der die Macros ersetzt. Ich definiere meine Macros allerdings ein klein wenig anders als PB, aber zum größten Teil sind sie kompatibel. Zum Beispiel sind bei mir als Default-Parameter für Macro-Parameter alle möglichen Zeichen möglich, man muss sie nur escapen. So kann in einem Default-Parameter zum Beispiel auch ein Komma. oder mehr geöffnete Klammern als geschlossene, vorkommen. Allerdings werden bei mir Parameternamen nicht ersetzt durch andere vorangegangene Macros. Das finde ich bei Purebasic sehr verwirrend und hat für mich auch keinen praktischen Nutzen.

Hier ist übrigens noch meine angedachte Feature-Liste. Sie ist noch nicht nach Priorität sortiert und teilweise verstehe wahrscheinlich nur ich, was ich damit meine. :lol:

Code: Alles auswählen

; TODO:
; String$-Variablen
; Nach EndMacro muss ein Trennzeichen kommen

; Features:
; - "%d %f" % (123, float.f)
; - ^ als integer pow
; - mehrzeilige strings, vielleicht auch mit """
; - Structuren und Interfaces als Procedure-Typen
; - named Parameters, ähnlich Python
; - optionale Parameter auch zwischendrin
;     Procedure test(a=0, b.i) : EndProcedure
;     test(,1) ; => test(0, 1)
; - Max(EnumerationName) gibt die höchste Zahl in dieser Enumeration an
; - Dim with optional initialisation
;     Dim primes.i() = {2, 3, 5, 7, 11, 13}
;   
; - Nested Modules, Procedures und Module
; - Nested Macros, solange enthaltene Macros in sich geschlossen sind.
; - String + Character = String + Chr(Character)
; - Else auch vor ElseIf möglich (unnötig?)
; - Automatische Declare überall
; - Scope, EndScope für eigene Scopes
; - Goto aus Select-Block
; - VAARGS in Macros
; - Tuple als Type für Procedures
;     Procedure.(s, i, f) get()
;       ProcedureReturn ("hi", 123, 0.456)
;     EndProcedure

; Scopes entstehen bei Module, Procedure, Method, Constructor, Class, Scope
; Konstanten wirken sich immer auf den aktuellen Scope und die darunter liegenden aus, können aber von Konstanten in Unterscopes überschrieben werden.
; Es gibt die folgenden Namensräume nach Priorität
; - Macros
; - Simple Macro, Variablen
; - Procedures
; - Enumerations
; - Modulename
; - Konstanten
; - Strukturen, Interfaces, Prototypes

; + Zeichen '(', ')', '\' und ',' als Default Parameter in Makros nutzbar machen -> Escapen

; Einschränkungen:
; - Macros mit dem Namen Macro sind nicht möglich
;     Macro Macro
;     EndMacro
;
; - Parameter in Macros behalten immer ihren Namen und werden nicht durch andere Macros ersetzt.
;     Macro foo : bar : EndMacro
;     Macro test(foo) : foo : EndMacro  ;foo wird nicht vom Precompiler ersetzt. Erst wenn test(12) aufgerufen wird.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Suche Tester für Purebasic Tokenizer

Beitrag von NicTheQuick »

Kann mir jemand den Geschwindigkeitsunterschied hier erklären? Das kann doch nicht nur an der VM liegen, oder?
Bild
String-Variablen mit $ am ende werden jetzt übrigens auch erkannt, Helle.
Bild
Benutzeravatar
Kiffi
Beiträge: 10620
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Suche Tester für Purebasic Tokenizer

Beitrag von Kiffi »

NicTheQuick hat geschrieben:Das kann doch nicht nur an der VM liegen, oder?
mh, auf meinem Rechner (Win10) benötigt Dein Tokenizer für rund 8000 Zeilen knapp 3 Minuten.

Grüße ... Peter
Hygge
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Suche Tester für Purebasic Tokenizer

Beitrag von STARGÅTE »

Warum es so langsam ist wundert mich auch.
Ist das nur die Ausgabe im Window?
Nutzt du reguläre Ausdrücke?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Suche Tester für Purebasic Tokenizer

Beitrag von NicTheQuick »

Ich habe mir ein paar InputStreams gebaut. Der erste liest aus der Datei aus, der zweite konvertiert UTF8 in Unicode, dann geht es in einen einfachen Tokenizer und dann in den speziell angepassten Purebasic-Tokenizer. Ich probiere später mal statt meines FileInputStreams den MemoryInputStream zu nutzen. Ich kann mir vorstellen, dass es da Probleme gibt.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Suche Tester für Purebasic Tokenizer

Beitrag von NicTheQuick »

Okay, zwei Sachen habe ich herausgefunden. Unter Windows scheint es sau lahm zu sein, wenn man Zeichen für Zeichen aus einer Datei ausliest. Puffert man die komplette Datei vorher in einem Speicherbereich, dauert es statt 55 Sekunden nur noch 200 ms. Schreibt man jetzt aber alles gleichzeitig noch in ein EditorGadget, wird es wieder sehr langsam. Linux scheint beides egal zu sein. Dann muss ich also schauen, dass ich bestimmte Sachen extra für Windows optimiere. Ätzend...
Bild
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Re: Suche Tester für Purebasic Tokenizer

Beitrag von Helle »

Aha, haste selbst schon gefunden. Kam mir jetzt beim testen irgendwie bekannt vor: Spielt man während der Ausgabe mit dem Scroll-Balken, geht es schneller. Das Problem der lahmen Ausgabe hatte ich anfangs bei meinem DisAssembler; dann hat mich edel (immer wieder Dank dafür!) auf den rechten Weg der Erkenntnis gebracht. Das Zauberwort heißt Callback! Für ein ListIconGadget habe ich dann daraus folgendes gemacht:

Code: Alles auswählen

Procedure ListIcon_Callback(hwnd, msg, wparam, lparam)     ;thanks to edel for the tip! 
  Protected *hdr.NMHDR
  Protected *di.NMLVDISPINFO
  Protected *cd.NMLVCUSTOMDRAW

  If msg = #WM_NOTIFY 
    *hdr = lparam
    If *hdr\code = #LVN_GETDISPINFO
      *di = lparam
      If *di\item\iSubItem = 0
        PStr.i = @Daten(*di\item\iItem)\Address
       ElseIf *di\item\iSubItem = 1
        PStr.i = @Daten(*di\item\iItem)\Opcode
       ElseIf *di\item\iSubItem = 2
        PStr.i = @Daten(*di\item\iItem)\Mnemonic
       Else      
        PStr.i = @Daten(*di\item\iItem)\ASCII
      EndIf
      *di\item\pszText = PStr
      ProcedureReturn #True
    EndIf

    *cd.NMLVCUSTOMDRAW = lparam 
    If *cd\nmcd\hdr\hWndFrom = GID And *cd\nmcd\hdr\code = #NM_CUSTOMDRAW 
      Select *cd\nmcd\dwDrawStage 
        Case #CDDS_PREPAINT 
          ProcedureReturn #CDRF_NOTIFYITEMDRAW 
        Case #CDDS_ITEMPREPAINT 
          If *cd\nmcd\dwItemSpec = ZeilePEP And FileExt = 0
            *cd\clrTextBk = $00FF00         ;green for program-entrypoint
           Else 
             *cd\clrTextBk = $CCFFFF        ;light-yellow for code       
          EndIf 
 
          ForEach Search()
            If *cd\nmcd\dwItemSpec = Search()
              *cd\clrTextBk = $0ECCBB       ;olive for found instruction
            EndIf
          Next

          ForEach DLLEP()
            If *cd\nmcd\dwItemSpec = DLLEP()
              *cd\clrTextBk = $EECCBB       ;light-blue for dll-entrypoint
            EndIf
          Next 

      EndSelect 
    EndIf 
  EndIf 
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 
....
SetWindowCallback(@ListIcon_Callback(), 0)
Es wird praktisch nur der jeweilige Bildschirm/Gadget-Inhalt angezeigt/benötigt. Seit dem lief es wie Hanne!

Gruß
Helle

P.S.: Nach Error weiter...?

Sorry, mein Betriebssystem: Windows7 Ultimate 64-Bit
Antworten