Pour quelles langues la syntaxe-ppss est-elle appropriée?

12

J'ai cherché un moyen de détecter si un point se trouve sur un commentaire en examinant la façon dont le tampon actuel est police.

Smartparens définit sp-point-in-comment, qui s'appuie sur syntax-ppss. Cependant, il semble que syntax-ppsset parse-partial-sexppeut être utilisé pour des langages arbitraires, même s'ils n'utilisent pas d'expressions s.

Par exemple, ce Python:

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

Le placement du point à l'intérieur du commentaire et l'évaluation (if (nth 4 (syntax-ppss)) 'comment 'not-comment)fonctionnent correctement.

Fonctionne syntax-ppsspour n'importe quel mode de programmation? Pourquoi les docstrings discutent-elles des expressions s?

Wilfred Hughes
la source
1
Non pas que j'aie exploré cela à fond, mais je n'ai pas encore trouvé de langue dans laquelle cela ne fonctionne pas. Même dans les modes dérivés du texte tels que le latex, cela a bien fonctionné pour moi.
Malabarba

Réponses:

13

Eh bien, les expressions s sont essentiellement des «syntaxes abstraites», dans le sens où elles ne sont qu'une syntaxe concrète pour les arbres de syntaxe abstraite, et donc n'importe quel langage peut être représenté comme des expressions s et manipulé avec des commandes d'expression s. Par conséquent, syntax-ppssparler de «Sexps» est simplement la façon Lisp de parler des arbres de syntaxe abstraite.

En pratique, cependant, syntax-ppssne fonctionne généralement pour aucun mode. Il est fondamentalement destiné aux langages de type Lisp, et si le langage concret d'un langage s'écarte trop de Sexps, cela n'a plus beaucoup de sens d'utiliser des commandes Sexp pour manipuler le langage. Cela fonctionnerait, mais il y aurait un trop grand écart entre la représentation abstraite et la syntaxe concrète, ce qui rendrait la plupart des commandes contre-intuitives.

Cependant, une partie de l'infrastructure sous-jacente de syntax-ppssest assez générique. Les principaux modes s'efforcent généralement de s'y connecter, car cela les fait bien fonctionner avec de nombreuses fonctionnalités intégrées d'Emacs et fournit une interface générique pour d'autres packages tiers tels que Smartparens.

Notamment, syntax-ppsss'appuie sur les tables de syntaxe pour les chaînes et les commentaires. Les tableaux de syntaxe classent les caractères individuels par leur classe syntaxique. Il existe des classes pour les délimiteurs appariés, les délimiteurs de chaînes et les caractères de commentaire.

La structure des chaînes et des commentaires est assez similaire dans presque tous les langages de programmation: les chaînes sont normalement enfermées dans des délimiteurs spéciaux. Les commentaires peuvent également avoir des délimiteurs spéciaux, ou commencer par un certain caractère et s'étendre jusqu'à la fin de la ligne. Ces structures peuvent être facilement capturées dans des tables de syntaxe, et presque tous les modes principaux définissent des tables de syntaxe appropriées, ne serait-ce que pour profiter de la fortification syntaxique d'Emacs.

Par conséquent, syntax-ppssfonctionne bien pour les chaînes et les commentaires dans presque toutes les langues, mais le support et l '«utilité» des autres fonctionnalités varient.

lunaryorn
la source
4

Ajoutant à la réponse de @ lunaryorn, je pense que syntax-ppss s'appuie simplement sur la robustesse du système de table de syntaxe d'emacs, qui fonctionne pour les commentaires et les chaînes dans la plupart des langues. Mais si le langage a une syntaxe que la table de syntaxe ne peut pas capturer, et si le mode n'a pas construit un analyseur pour ajouter des propriétés de syntaxe aux bons endroits, syntax-ppssil échouerait.

Essayez ceci dans html-mode:

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

et appelez la commande suivante:

(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))

Seul aa est vrai, mais bb devrait également être vrai.

Lorsqu'il est dans nxml-mode, rien ne retourne vrai, mais au moins aa devrait être vrai.

Xah Lee
la source