Skip to main content

Providing the Code

Tree-sitter provides two main functions for parsing source code: one for simple strings and one for custom data structures.

Parsing Strings

The simplest way to parse source code is using ts_parser_parse_string:
TSParser*
required
The parser instance
const TSTree*
A previous syntax tree for incremental parsing (pass NULL for initial parse)
const char*
required
The UTF-8 encoded source code to parse
uint32_t
required
The length of the string in bytes

Parsing Custom Data Structures

You may want to parse source code that’s stored in a custom data structure, like a piece table or a rope. In this case, use the more general ts_parser_parse function:
The TSInput structure lets you provide your own function for reading text:
1

Define a read callback

Your callback receives a byte offset and position, and should return a pointer to text starting at that position.
2

Create the TSInput structure

3

Parse the document

Custom Text Encoding

If your text uses an encoding other than UTF-8 or UTF-16, you can provide a custom decode function:
The TSInputEncoding must be set to TSInputEncodingCustom for the decode function to be called.
The function should:
  1. Read bytes from string (up to length bytes)
  2. Write the decoded code point to code_point
  3. Return the number of bytes consumed

Syntax Nodes

Tree-sitter provides a DOM-style interface for inspecting syntax trees.

Node Type

A syntax node’s type is a string that indicates which grammar rule the node represents:

Node Position

Nodes store their position in the source code both in raw bytes and row/column coordinates:
In a TSPoint, rows and columns are zero-based. The row field represents the number of newlines before a given position, while column represents the number of bytes between the position and the beginning of the line. A newline is considered to be a single line feed (\n) character.

Retrieving Nodes

Root Node

Every tree has a root node:

Child Nodes

Once you have a node, you can access its children:

Siblings and Parent

You can also navigate to siblings and parent nodes:
These methods may return a null node to indicate that no such node exists (e.g., no next sibling). Always check if a node is null using ts_node_is_null(TSNode).

Named vs Anonymous Nodes

Tree-sitter produces concrete syntax trees — trees that contain nodes for every individual token in the source code, including things like commas and parentheses. This is important for use-cases like syntax highlighting. However, some types of code analysis are easier with an abstract syntax tree — a tree in which less important details have been removed. Tree-sitter supports both by making a distinction between named and anonymous nodes.

Example

Consider this grammar rule:
A syntax node representing an if_statement would have 5 children:
  • The condition expression (named)
  • The body statement (named)
  • The if, (, and ) tokens (anonymous)
The expression and statement are marked as named nodes because they have explicit names in the grammar. The if, (, and ) nodes are anonymous because they are represented as simple strings.

Checking if a Node is Named

Named-Only Navigation

You can skip over anonymous nodes by using the _named_ variants:
Using the _named_ methods makes the syntax tree function much like an abstract syntax tree.

Node Field Names

Many grammars assign unique field names to particular child nodes to make them easier to analyze.

Accessing Children by Field Name

Using Field IDs

Fields also have numeric IDs that you can use to avoid repeated string comparisons:

Next Steps

Advanced Parsing

Learn about incremental parsing and editing

Walking Trees

Use tree cursors for efficient traversal