Для каких языков подходит `синтаксис-ppss`?

12

Я искал способ определить, находится ли точка в комментарии, посмотрев, как определяется текущий буфер.

Smartparens определяет sp-point-in-comment, на что опирается syntax-ppss. Однако кажется, что syntax-ppssи parse-partial-sexpможет использоваться для произвольных языков, даже если они не используют s-выражения.

Например, этот Python:

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

Размещение точки внутри комментария и оценка (if (nth 4 (syntax-ppss)) 'comment 'not-comment)работает правильно.

Работает ли syntax-ppssдля любого режима программирования? Почему строки документации обсуждают s-выражения?

Уилфред Хьюз
источник
1
Не то чтобы я тщательно это изучил, но мне еще предстоит найти язык, на котором он не работает. Даже в текстовых режимах, таких как латекс, он работал нормально для меня.
Малабарба

Ответы:

13

Что ж, s-выражения по сути являются «абстрактным синтаксисом», в том смысле, что они являются просто конкретным синтаксисом для деревьев абстрактного синтаксиса, и поэтому любой язык может быть представлен в виде s-выражений и управляться с помощью команд s-выражений. Следовательно, syntax-ppssговорить о «Sexps» - это просто способ Lisp говорить об абстрактных синтаксических деревьях.

Практически, однако, syntax-ppssобычно не работает ни для одного режима. Он в основном нацелен на Lisp-подобные языки, и если конкретный язык языка слишком сильно отличается от Sexps, больше не имеет смысла использовать команды Sexp для манипулирования языком. Это будет работать, но между абстрактным представлением и конкретным синтаксисом будет слишком большой разрыв, что сделает большинство команд нелогичными.

Тем не менее, некоторая базовая инфраструктура syntax-ppssявляется довольно общей. Основные режимы обычно стараются подключиться к нему, потому что он позволяет им хорошо работать со многими встроенными функциями Emacs и предоставляет общий интерфейс для других сторонних пакетов, таких как Smartparens.

В частности, syntax-ppssопирается на таблицы синтаксиса для строк и комментариев. Синтаксические таблицы классифицируют отдельные символы по их синтаксическому классу. Существуют классы для парных разделителей, разделителей строк и символов комментариев.

Структура строк и комментариев практически одинакова практически во всех языках программирования: строки обычно заключаются в специальные разделители. Комментарии также могут иметь специальные разделители или начинаться с определенного символа и продолжаться до конца строки. Эти структуры могут быть легко зафиксированы в синтаксических таблицах, и почти все основные режимы определяют соответствующие синтаксические таблицы, если только получают выгоду от синтаксического обогащения Emacs.

Следовательно, syntax-ppssхорошо работает со строками и комментариями практически на любом языке, но поддержка и «полезность» других функций варьируется.

lunaryorn
источник
4

В дополнение к ответу @ lunaryorn, я думаю, что syntax-ppss просто полагается на надежность системы таблиц синтаксиса emacs, которая работает для комментариев и строк в большинстве языков. Но если в языке есть синтаксис, который синтаксическая таблица не может записать, и если режим не создает синтаксический анализатор для добавления свойств синтаксиса в нужные места, syntax-ppssпроизойдет сбой.

Попробуйте это в html-mode:

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

и вызовите следующую команду:

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

Только aa верно, но bb также должно быть верно.

В случае nxml-mode, ничего из этого не возвращает истину, но, по крайней мере, aa должно быть истиной.

Ха Ли
источник