Für welche Sprachen ist `syntax-ppss` geeignet?

12

Ich habe nach einer Möglichkeit gesucht, zu ermitteln, ob ein Punkt in einem Kommentar enthalten ist, indem untersucht wurde, wie der aktuelle Puffer beschriftet ist.

Smartparens definiert sp-point-in-comment, worauf es ankommt syntax-ppss. Es scheint jedoch, dass syntax-ppssund parse-partial-sexpfür beliebige Sprachen verwendet werden kann, auch wenn sie keine s-Ausdrücke verwenden.

Zum Beispiel diese Python:

x = 1
# I'm a comment
y = 2

Das Platzieren von Punkten innerhalb des Kommentars und das Auswerten (if (nth 4 (syntax-ppss)) 'comment 'not-comment)funktioniert ordnungsgemäß.

Funktioniert das syntax-ppssfür irgendeinen Programmiermodus? Warum diskutieren die Docstrings S-Ausdrücke?

Wilfred Hughes
quelle
1
Nicht, dass ich das gründlich untersucht hätte, aber ich habe noch keine Sprache gefunden, in der es nicht funktioniert. Sogar in von Texten abgeleiteten Modi wie Latex hat es für mich gut funktioniert.
Malabarba

Antworten:

13

Nun, S-Ausdrücke sind im Wesentlichen „abstrakte Syntax“ in dem Sinne, dass sie lediglich eine konkrete Syntax für abstrakte Syntaxbäume sind und daher jede Sprache als S-Ausdrücke dargestellt und mit S-Ausdrucksbefehlen manipuliert werden kann. Daher syntax-ppssist der „Sexps“ sprechen einfach die Lisp Art und Weise zu sprechen über abstrakte Syntaxbäume.

In der syntax-ppssRegel funktioniert dies jedoch in keinem Modus. Es ist grundsätzlich auf Lisp-ähnliche Sprachen ausgerichtet, und wenn die konkrete Sprache einer Sprache zu sehr von Sexps abweicht, ist es nicht mehr sinnvoll, Sexp-Befehle zur Manipulation der Sprache zu verwenden. Es würde funktionieren, aber es würde eine zu große Lücke zwischen der abstrakten Darstellung und der konkreten Syntax geben, was die meisten Befehle nicht intuitiv machen würde.

Ein Teil der zugrunde liegenden Infrastruktur syntax-ppssist jedoch ziemlich allgemein. Die wichtigsten Modi sind in der Regel sehr bemüht, eine Verbindung herzustellen, da sie mit vielen integrierten Emacs-Funktionen gut funktionieren und eine allgemeine Schnittstelle für andere Pakete von Drittanbietern wie Smartparens bieten.

Verlässt syntax-ppsssich insbesondere auf Syntaxtabellen für Zeichenfolgen und Kommentare. Syntaxtabellen kategorisieren einzelne Zeichen nach ihrer syntaktischen Klasse. Es gibt Klassen für gepaarte Begrenzer, Zeichenkettenbegrenzer und Kommentarzeichen.

Die Struktur von Zeichenfolgen und Kommentaren ist in fast allen Programmiersprachen ziemlich ähnlich: Zeichenfolgen werden normalerweise in spezielle Trennzeichen eingeschlossen. Kommentare können auch spezielle Trennzeichen haben oder mit einem bestimmten Zeichen beginnen und sich bis zum Ende der Zeile erstrecken. Diese Strukturen können leicht in Syntaxtabellen erfasst werden, und fast alle Hauptmodi definieren geeignete Syntaxtabellen, wenn auch nur, um von der syntaktischen Verstärkung von Emacs zu profitieren.

Funktioniert daher syntax-ppssgut für Zeichenfolgen und Kommentare in fast jeder Sprache, aber die Unterstützung und "Nützlichkeit" anderer Funktionen variiert.

Mondhorn
quelle
4

Neben der Antwort von @ lunaryorn verlässt sich syntax-ppss meiner Meinung nach nur auf die Robustheit des Syntaxtabellensystems von emacs, das in den meisten Sprachen für Kommentare und Zeichenfolgen funktioniert. Wenn die Sprache jedoch eine Syntax hat, die in der Syntaxtabelle nicht erfasst werden kann, und der Modus keinen Parser zum Hinzufügen von Syntaxeigenschaften an den richtigen Stellen erstellt hat, schlägt syntax-ppssdies fehl.

Versuchen Sie dies in html-mode:

<p class="aa" id='bb'>"cc" 'dd'</p>

und rufen Sie den folgenden Befehl auf:

(defun inside-string-p (&optional pos)
  "Return non-nil if inside string, else nil.
This depends on major mode having setup syntax table properly."
  (interactive)
  (let ((result (nth 3 (syntax-ppss pos))))
    (print result)
    result))

Nur aa ist wahr, aber bb sollte auch wahr sein.

Wenn in nxml-mode, gibt nichts davon wahr zurück, aber mindestens aa sollte wahr sein.

Xah Lee
quelle