Lexer (Syntaxhighlighting) mit kontextsensitiven Schlüsselwörtern



  • Hallo,

    ich arbeite mit einer Sprache, welche kontextabhängige Schlüsselwörter kennt. Z.B. ist 'of' in dem Code Instance X of Y in diesem Kontext ein Schlüsselwort, im Kontext Var of = 42 jedoch nicht.

    Ich habe einen Lexer für die Sprache; daran können verschiedene Filter angekoppelt und Ausgabemodule aufgesetzt werden (ein Filter kann Tokens zurückweisen oder transformieren; ein Ausgabemodul arbeitet mit dem resultierenden Token-Strom weiter). Ein solches Modul soll nun ein HTML- (oder beliebiges anderes) Syntaxhighlighting erzeugen. Gut. Aber wie bekomme ich es hier hin, solche kontextabhängigen Schlüsselwörter korrekt darzustellen. Generell gibt es für jedes Schlüsselwort einen eigenen Token-Typ. 'of' ist da aber nicht enthalten, denn es kann ja auch ein ganz normaler Bezeichner sein. Für einen Parser wäre das natürlich kein Problem, ich möchte aber aus Effizienzgründen *keinen* Parser für das Syntax-Highlighting benutzen. Gibt es trotzdem irgend einen netten Trick, um solche bedingten Schlüsselwörter korrekt zu formatieren, *ohne* einen Parser für den entsprechenden Ausdruck implementieren zu müssen?

    Zusatz: Die Konstrukte sind leider nicht immer so einfach wie oben, denn sonst wäre das ja einfach; man merkt sich einfach, dass das vorletzte Token 'Instance' war. Allerdings kann an der Stelle von 'X' auch ein komplexer Ausdruck stehen.

    Ich befürchte, eine gute Lösung gibt es nicht aber vielleicht belehrt mich jemand eines anderen.



  • Naja, so rein intuitiv würde ich fast vermuten dass du die Information, in welchem Kontext du dich befindest, nicht verwenden kannst wenn du sie nicht hast.



  • finix schrieb:

    Naja, so rein intuitiv würde ich fast vermuten dass du die Information, in welchem Kontext du dich befindest, nicht verwenden kannst wenn du sie nicht hast.

    Klar. 😉 Aber in welchem Kontext ich bin, kann ich relativ prüfen indem ich einfach schaue, ob irgendwann ein 'Instance'-Token kommt, dann weiß ich ja, dass ein 'of' folgt, nur eben nicht genau *wo*; eben, weil das 'X' ein komplexer Typenbezeichner sein kann. Ich habe das jetzt so gelöst, dass ich einfach ab einem 'Instance'-Token die Position des 'of'-Tokens "rate", indem ich verschiedene Dinge (Klammerungstiefe …) heranziehe. Scheint zu klappen, ich bin mir aber nicht sicher, ob ich jeden Fall abgedeckt habe. Na ja, muss reichen.



  • hmm -für pygments könnte man einen passenden lexer schreiben



  • r0nny schrieb:

    hmm -für pygments könnte man einen passenden lexer schreiben

    Da hätte man doch aber dasselbe Problem; man müsste für das 'X' aus meinem Beispiel die gesamte hier anwendbare Produktion implementieren. Im Fall von Instance X of Y hält sich das noch in Grenzen. Für For X in Y ('in' ist ein bedingtes Schlüsselwort) ist das hingegen schon ganz schön kompliziert, denn anstelle von 'X' kann hier ein beliebiger L-Value oder eine Deklaration stehen.



  • Tja, dann musst du halt in deinem Lexer entsprechende Regeln erstellen, z.b. welche die dann ein Instance of halt komplett verarbeitet.



  • phlox81 schrieb:

    Tja, dann musst du halt in deinem Lexer entsprechende Regeln erstellen, z.b. welche die dann ein Instance of halt komplett verarbeitet.

    Ja, ich sehe schon, das wird wohl nix. Die Frage war ja eben, "Gibt es trotzdem irgend einen netten Trick, […] *ohne* einen Parser für den entsprechenden Ausdruck implementieren zu müssen?"



  • Eigentlich müsstest du mit einem Symboltable auskommen, aber in den meisten Programmiersprachen die ich kenne, sind schlüsselwörter halt
    nicht kontextsensitiv, sondern gelten entsprechend. Daher wirst du wohl zumindest den tokenizer etwas aufbohren müssen.



  • phlox81 schrieb:

    Eigentlich müsstest du mit einem Symboltable auskommen

    Huh? Kannst du das mal erläutern? Eine Symboltabelle bringt hier doch gar nichts.



  • finix schrieb:

    phlox81 schrieb:

    Eigentlich müsstest du mit einem Symboltable auskommen

    Huh? Kannst du das mal erläutern? Eine Symboltabelle bringt hier doch gar nichts.

    Wenns nicht kontextsensitiv wäre 😉



  • Ich versteh's immer noch nicht. Zum einen geht's hier gerade um die Kontextsensivität, zum anderen wäre eine Symboltabelle auch ansonsten sinnlos.


Anmelden zum Antworten