Dla jakich języków odpowiedni jest `syntax-ppss`?

12

Patrzyłem na sposób wykrycia, czy punkt jest w komentarzu, patrząc na sposób fontowania bieżącego bufora.

Smartparens definiuje sp-point-in-comment, na czym polega syntax-ppss. Wydaje się jednak, że syntax-ppssi parse-partial-sexpmożna go używać w dowolnych językach, nawet jeśli nie używają wyrażeń s.

Na przykład ten Python:

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

Umieszczenie punktu w komentarzu i ocena (if (nth 4 (syntax-ppss)) 'comment 'not-comment)działa poprawnie.

Czy syntax-ppssdziała dla dowolnego trybu programowania? Dlaczego dokumenty opisują wyrażenia s?

Wilfred Hughes
źródło
1
Nie dlatego, że dokładnie to zbadałem, ale jeszcze nie znalazłem języka, w którym to nie działa. Nawet w trybach tekstowych, takich jak lateks, działało to dla mnie dobrze.
Malabarba

Odpowiedzi:

13

Cóż, wyrażenia s są zasadniczo „abstrakcyjną składnią”, w tym sensie, że są jedynie konkretną składnią abstrakcyjnych drzew składni, a zatem każdy język może być reprezentowany jako wyrażenia s i manipulowany za pomocą poleceń wyrażenia s. Dlatego syntax-ppssmówienie o „Sexps” jest po prostu sposobem Lispa na mówienie o abstrakcyjnych drzewach składniowych.

Praktycznie jednak syntax-ppssogólnie nie działa w żadnym trybie. Jest on zasadniczo ukierunkowany na języki podobne do Lisp, a jeśli konkretny język danego języka zbytnio odbiega od Sexps, nie ma już sensu używanie poleceń Sexp do manipulowania językiem. To działałoby, ale byłaby zbyt duża luka między abstrakcyjną reprezentacją a konkretną składnią, co powodowałoby, że większość poleceń byłaby sprzeczna z intuicją.

Jednak część podstawowej infrastruktury syntax-ppssjest dość ogólna. Główne tryby zwykle starają się podłączyć do niego, ponieważ sprawia, że ​​działają one dobrze z wieloma wbudowanymi funkcjami Emacsa i zapewniają ogólny interfejs dla innych pakietów innych firm, takich jak Smartparens.

W szczególności ciągi i komentarze syntax-ppssopierają się na tabelach składni . Tabele składniowe kategoryzują poszczególne znaki według ich klasy składniowej. Istnieją klasy dla sparowanych ograniczników, ograniczników ciągów i znaków komentarza.

Struktura ciągów i komentarzy jest dość podobna w prawie wszystkich językach programowania: Ciągi znaków są zwykle zamknięte w specjalnych ogranicznikach. Komentarze mogą mieć także specjalne ograniczniki lub zaczynać się od określonego znaku i rozciągać do końca linii. Struktury te można łatwo uchwycić w tabelach składniowych, a prawie wszystkie główne tryby definiują odpowiednie tabele składniowe, choćby po to, aby skorzystać z fortyfikacji składniowej Emacsa.

Dlatego syntax-ppssdziała dobrze dla ciągów i komentarzy w prawie każdym języku, ale obsługa i „użyteczność” innych funkcji jest różna.

księżycowy
źródło
4

Dodając do odpowiedzi @ lunaryorn, myślę, że syntax-ppss polegają tylko na solidności systemu tabel składniowych emacsa, który działa w przypadku komentarzy i napisów w większości języków. Ale jeśli język ma składnię, ta tabela składni nie może przechwytywać, a jeśli tryb nie zbuduje analizatora składni w celu dodania właściwości składni do odpowiednich miejsc, syntax-ppssnie powiedzie się.

Wypróbuj to w html-mode:

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

i wywołaj następujące polecenie:

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

Tylko aa jest prawdą, ale bb również powinno być prawdą.

Po nxml-modewejściu żaden z nich nie zwraca wartości true, ale przynajmniej aa powinna być prawdziwa.

Xah Lee
źródło