Spec-Zone.ru › Elisp

Получение узлов

Ниже приведены некоторые термины и соглашения, которые мы используем при описании функций tree-sitter.

Узел синтаксического дерева охватывает некоторую часть текста программы в буфере. Мы говорим, что узел «меньше» или «больше» другого узла, если он охватывает соответственно меньшую или большую часть текста буфера. Поскольку узлы, расположенные глубже («ниже») в дереве, являются потомками узлов, расположенных «выше», нижний узел всегда меньше узла, находящегося выше в иерархии узлов. Узел, расположенный выше в синтаксическом дереве, содержит один или несколько меньших узлов в качестве потомков и поэтому охватывает большую часть текста буфера.

Если функция не может найти узел, она возвращает nil. Для удобства все функции, которые принимают узел в качестве аргумента и возвращают узел, также принимают в качестве аргумента узел nil и в этом случае просто возвращают nil.

Узлы не обновляются автоматически при изменении связанного с ними буфера, и обновить уже полученный узел невозможно. Использование устаревшего узла вызывает ошибку treesit-node-outdated.

Печатное представление узла tree-sitter использует нотацию с решёткой, описанную в разделе Печатное представление и синтаксис чтения. Оно выглядит так: ‘#<treesit-node type in pos1-pos2>’, где type — тип узла (он определяется грамматикой tree-sitter, используемой буфером), а pos1 и pos2 — позиции в буфере, охватываемые узлом. У узлов tree-sitter нет синтаксиса чтения.

Получение узлов из синтаксического дерева

Функция: treesit-node-at pos &optional parser-or-lang named

Эта функция возвращает листовой узел в позиции pos буфера. Листовой узел — это узел, у которого нет дочерних узлов.

Функция пытается вернуть узел, охватывающий pos: начальная позиция узла меньше или равна pos, а конечная позиция узла больше или равна pos.

Если ни один листовой узел не охватывает pos (например, pos находится в пробеле между двумя листовыми узлами), функция возвращает первый листовой узел после pos.

Если после pos нет листовых узлов, возвращается первый листовой узел перед pos.

Если parser-or-lang — объект парсера, функция использует этот парсер; если parser-or-lang — язык, функция использует первый парсер для этого языка в текущем буфере или создаёт его, если такого нет; если parser-or-lang равен nil, функция пытается определить язык в позиции pos, вызывая treesit-language-at (см. раздел Разбор текста на нескольких языках).

Если эта функция не может найти подходящий узел, она возвращает nil.

Если named не равен nil, функция ищет только именованные узлы (см. раздел именованный узел).

Пример:

;; Find the node at point in a C parser's syntax tree.
(treesit-node-at (point) 'c)
  ⇒ #<treesit-node primitive_type in 23-27>
Функция: treesit-node-on beg end &optional parser-or-lang named

Эта функция возвращает наименьший узел, охватывающий область текста буфера между beg и end. Иными словами, начало узла находится перед beg или в этой позиции, а конец узла — после end или в этой позиции.

Внимание: вызов этой функции для пустой строки, не входящей ни в одну конструкцию верхнего уровня (определение функции и т. п.), скорее всего, вернёт корневой узел, поскольку он является наименьшим узлом, охватывающим эту пустую строку. В большинстве случаев вместо этого следует использовать treesit-node-at.

Если parser-or-lang — объект парсера, функция использует этот парсер; если parser-or-lang — язык, функция использует первый парсер для этого языка в текущем буфере или создаёт его, если такого нет; если parser-or-lang равен nil, функция пытается определить язык в позиции beg, вызывая treesit-language-at.

Если named не равен nil, функция ищет только именованные узлы (см. раздел именованный узел).

Функция: treesit-parser-root-node parser

Эта функция возвращает корневой узел синтаксического дерева, созданного парсером parser.

Функция: treesit-buffer-root-node &optional language

Эта функция находит первый парсер для языка language в текущем буфере или создаёт его, если такого нет, и возвращает корневой узел, созданный этим парсером. Если language не указан, функция использует первый парсер в списке парсеров. Если подходящий парсер найти не удаётся, функция возвращает nil.

Имея узел, программа на Lisp может получать другие узлы, начиная с него, или запрашивать сведения об этом узле.

Получение узлов из других узлов

По родственным связям

Функция: treesit-node-parent node

Эта функция возвращает непосредственный родительский узел для node.

Если node находится на глубине более 1000 уровней в дереве разбора, возвращаемое значение не определено. В настоящее время возвращается nil, но в будущем это может измениться.

Функция: treesit-node-child node n &optional named

Эта функция возвращает дочерний узел node с номером n. Если named не равен nil, учитываются только именованные узлы (см. раздел именованный узел).

Например, у узла, представляющего строку "text", есть три дочерних узла: открывающая кавычка ", текст строки text и закрывающая кавычка ". Среди этих узлов первым дочерним узлом является открывающая кавычка ", а первым именованным дочерним узлом — текст строки.

Если дочернего узла с номером n нет, функция возвращает nil. Значение n может быть отрицательным: например, −1 обозначает последний дочерний узел.

Функция: treesit-node-children node &optional named

Эта функция возвращает список всех дочерних узлов node. Если named не равен nil, функция получает только именованные узлы.

Функция: treesit-node-next-sibling node &optional named

Эта функция находит следующий соседний узел для node. Если named не равен nil, функция находит следующий именованный соседний узел.

Функция: treesit-node-prev-sibling node &optional named

Эта функция находит предыдущий соседний узел для node. Если named не равен nil, функция находит предыдущий именованный соседний узел.

По имени поля

Чтобы упростить анализ синтаксического дерева, во многих грамматиках языков дочерним узлам назначаются имена полей (см. раздел имя поля). Например, у узла function_definition могут быть дочерние узлы declarator и body.

Функция: treesit-node-child-by-field-name node field-name

Эта функция находит дочерний узел node с именем поля field-name, заданным строкой.

;; Get the child that has "body" as its field name.
(treesit-node-child-by-field-name node "body")
  ⇒ #<treesit-node compound_statement in 45-89>

По позиции

Функция: treesit-node-first-child-for-pos node pos &optional named

Эта функция находит первый дочерний узел node, который продолжается за позицией pos в буфере. «Продолжается за» означает, что конечная позиция дочернего узла больше или равна pos. Функция ищет только среди непосредственных дочерних узлов node и не проверяет узлы следующего уровня. Если named не равен nil, функция ищет первый именованный дочерний узел (см. раздел именованный узел).

Функция: treesit-node-descendant-for-range node beg end &optional named

Эта функция находит наименьший дочерний узел любого уровня для node, охватывающий область текста между позициями beg и end. Она похожа на treesit-node-at. Если named не равен nil, функция ищет наименьший именованный дочерний узел.

Поиск узлов

Функция: treesit-search-subtree node predicate &optional backward all depth

Эта функция обходит поддерево node (включая сам node) и ищет узел, для которого predicate возвращает значение, отличное от nil. Значением predicate может быть регулярное выражение, сопоставляемое с типом каждого узла, или функция-предикат, принимающая узел и возвращающая значение, отличное от nil, если узел соответствует условию. В качестве predicate также можно указать символ thing или определение thing (см. раздел Пользовательские «things» и навигация). Использование неопределённого thing не вызывает ошибку: функция просто возвращает nil.

Функция возвращает первый подходящий узел или nil, если ни один узел не соответствует predicate.

По умолчанию функция обходит только именованные узлы, но если all не равен nil, она обходит все узлы. Если backward не равен nil, обход выполняется в обратном порядке (то есть при движении вниз по дереву сначала посещается последний дочерний узел). Если depth не равен nil, он должен быть числом, ограничивающим обход дерева указанным количеством уровней. Если depth равен nil, по умолчанию он равен 1000.

Функция: treesit-search-forward start predicate &optional backward all

Как и treesit-search-subtree, эта функция обходит дерево разбора и проверяет каждый узел (кроме start) на соответствие predicate, которым может быть регулярное выражение или функция-предикат. В качестве predicate также можно указать символ thing или определение thing (см. раздел Пользовательские «things» и навигация). Использование неопределённого thing не вызывает ошибку: функция просто возвращает nil.

Для дерева, показанного ниже, где start обозначен символом ‘S’, функция выполняет обход в порядке, обозначенном числами от 1 до 12:

              12
              |
     S--------3----------11
     |        |          |
o--o-+--o  1--+--2    6--+-----10
|  |                  |        |
o  o                +-+-+   +--+--+
                    |   |   |  |  |
                    4   5   7  8  9

Обратите внимание, что эта функция не обходит поддерево start и всегда сначала посещает листовые узлы, а затем поднимается вверх.

Как и treesit-search-subtree, эта функция по умолчанию ищет только именованные узлы, но если all не равен nil, она ищет все узлы. Если backward не равен nil, поиск выполняется в обратном направлении.

В то время как treesit-search-subtree обходит поддерево узла, эта функция начинает с узла start и обходит все узлы, следующие за ним в порядке позиций в буфере, то есть узлы, начальные позиции которых находятся после конечной позиции start.

В показанном выше дереве treesit-search-subtree обходит узел ‘S’ (start) и узлы, обозначенные o, тогда как эта функция обходит узлы, обозначенные числами. Функция полезна для ответа на вопросы вроде «какой первый узел после start в буфере удовлетворяет некоторому условию?».

Функция: treesit-search-forward-goto node predicate &optional start backward all

Эта функция перемещает точку в начало или конец следующего после node узла в буфере, который соответствует predicate. Если start не равен nil, функция останавливается в начале узла, а не в конце.

Функция гарантирует, что найденный узел, который она возвращает, обеспечивает продвижение по буферу: начальная или конечная позиция возвращённого узла всегда больше соответствующей позиции node.

Аргументы predicate, backward и all имеют то же значение, что и в treesit-search-forward.

Функция: treesit-induce-sparse-tree root predicate &optional process-fn depth

Эта функция создаёт разреженное дерево из поддерева root.

Она берёт поддерево root и прореживает его, оставляя только узлы, соответствующие predicate. Как и в предыдущих функциях, в качестве predicate можно указать строку с регулярным выражением, сопоставляемым с типом каждого узла, или функцию, принимающую узел и возвращающую значение, отличное от nil, если он соответствует условию. В качестве predicate также можно указать символ thing или определение thing (см. раздел Пользовательские «things» и навигация). Использование неопределённого thing не вызывает ошибку: функция просто возвращает nil.

Например, если исходное поддерево слева содержит и числа, и буквы, а predicate задаёт условие «только буквы», возвращённым будет дерево справа.

    a                 a              a
    |                 |              |
+---+---+         +---+---+      +---+---+
|   |   |         |   |   |      |   |   |
b   1   2         b   |   |      b   c   d
    |   |     =>      |   |  =>      |
    c   +--+          c   +          e
    |   |  |          |   |
 +--+   d  4       +--+   d
 |  |              |
 e  5              e

Если process-fn не равен nil, функция не возвращает найденные узлы, а передаёт каждый узел в process-fn и использует возвращённое значение. Если depth не равен nil, он ограничивает количество уровней обхода, начиная с root. Если depth равен nil, по умолчанию он равен 1000.

Каждый узел возвращённого дерева имеет вид (tree-sitter-node . (child …)). Значение tree-sitter-node для корня этого дерева будет равно nil, если root не соответствует predicate. Если ни один узел не соответствует predicate, функция возвращает nil.

Дополнительные вспомогательные функции

Функция: treesit-node-get node instructions

Эта вспомогательная функция объединяет несколько функций доступа к узлам в цепочку. Например, чтобы получить текст второго дочернего узла следующего соседа родительского узла node:

(treesit-node-get node
   '((parent 1)
    (sibling 1 nil)
    (child 1 nil)
    (text nil)))

instruction — это список ИНСТРУКЦИЙ вида (fn arg...). Поддерживаются следующие значения fn:

(child idx named)

Получить дочерний узел с индексом idx.

(parent n)

Перейти к родительскому узлу n раз.

(field-name)

Получить имя поля текущего узла.

(type)

Получить тип текущего узла.

(text no-property)

Получить текст текущего узла.

(children named)

Получить список дочерних узлов.

(sibling step named)

Получить соседний узел, отстоящий на step позиций: отрицательное значение означает предыдущий узел, положительное — следующий.

Обратите внимание, что аргументы вроде named и no-property нельзя опускать, в отличие от соответствующих исходных функций.

Функция: treesit-filter-child node predicate &optional named

Эта функция находит непосредственные дочерние узлы node, удовлетворяющие условию predicate.

Функция-предикат predicate принимает узел в качестве аргумента и должна возвращать значение, отличное от nil, чтобы указать, что узел следует оставить. Если named не равен nil, функция проверяет только именованные узлы.

Функция: treesit-parent-until node predicate &optional include-node

Эта функция последовательно ищет родителей node и возвращает первого родителя, удовлетворяющего условию predicate. Значением predicate может быть функция, принимающая узел и возвращающая t или nil, регулярное выражение для сопоставления с именами типов узлов или другой допустимый предикат, описанный в treesit-thing-settings. Если ни один родитель не удовлетворяет predicates, функция возвращает nil.

Обычно функция проверяет только родителей node, но не сам node. Однако если include-node не равен nil, функция возвращает node, если он удовлетворяет условию predicate.

Функция: treesit-parent-while node predicate

Эта функция поднимается по дереву, начиная с node, и продолжает это делать, пока узлы удовлетворяют условию predicate — функции, принимающей узел в качестве аргумента. Иными словами, функция возвращает самого верхнего родителя node, который всё ещё удовлетворяет условию predicate. Обратите внимание: если node удовлетворяет условию predicate, а его непосредственный родитель — нет, возвращается сам node.

Функция: treesit-node-top-level node &optional predicate include-node

Эта функция возвращает самого верхнего родителя node, имеющего тот же тип, что и node. Если такого родителя нет, функция возвращает nil. Поэтому эта функция также полезна для проверки, является ли node узлом верхнего уровня.

Если predicate равен nil, функция ищет родительский узел, используя тип node. Если predicate не равен nil, функция ищет родительский узел, удовлетворяющий условию predicate. Если include-node не равен nil, функция возвращает node, если он удовлетворяет условию predicate.

Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Retrieving-Nodes.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API