Learn R Programming

treesitter

treesitter provides R bindings to tree-sitter, an incremental parsing system. It can build a concrete syntax tree for a source file and efficiently update the syntax tree as the source file is edited. tree-sitter is useful for a number of things, including syntax highlighting, go-to definition, code reshaping, and more.

Installation

Install treesitter from CRAN with:

install.packages("treesitter")

This package does not provide bindings to a language specific tree-sitter grammar. To fully utilize the treesitter package, you will also need to install a grammar specific R package. Currently there is just one, for R:

install.packages("treesitter.r")

You can install the development version of treesitter from GitHub with:

# install.packages("pak")
pak::pak("DavisVaughan/r-tree-sitter")

Example

With treesitter, you can parse a string containing code for any language that you have a grammar for. Here’s an example with R code:

library(treesitter, warn.conflicts = FALSE)

# Language specific grammars come from extension packages
language <- treesitter.r::language()
parser <- parser(language)

# Imagine this is a source document
text <- "
1 + 2
"

# Parse the text and display the resulting syntax tree
parser_parse(parser, text)
#> <tree_sitter_tree>
#> 
#> ── Text ────────────────────────────────────────────────────────────────────────
#> 
#> 1 + 2
#> 
#> 
#> ── S-Expression ────────────────────────────────────────────────────────────────
#> (program [(0, 0), (2, 0)]
#>   (binary_operator [(1, 0), (1, 5)]
#>     lhs: (float [(1, 0), (1, 1)])
#>     operator: "+" [(1, 2), (1, 3)]
#>     rhs: (float [(1, 4), (1, 5)])
#>   )
#> )

Syntax trees can get pretty complex, here’s a larger example:

text <- "
mtcars |>
  mutate(y = x + 1)
"

tree <- parser_parse(parser, text)

Trees and nodes have a pretty nice print method that colors matching parentheses and dims the locations. If you were to print out tree in your R console, here’s what you’d see:

treesitter has a number of tools for navigating around and walking the tree:

# The right hand side of the pipe
node <- tree |>
  tree_root_node() |>
  node_child(1) |>
  node_child_by_field_name("rhs")

node_text(node)
#> [1] "mutate(y = x + 1)"

By default, printing a node in the tree will show both the anonymous nodes and the named nodes. Anonymous nodes help you see the full “concrete” syntax tree that tree-sitter builds. If you want to see something more akin to an abstract syntax tree, you can use node_show_s_expression(), which has a number of options for customizing the tree view:

# Full detail
node_show_s_expression(node)
#> (call [(2, 2), (2, 19)]
#>   function: (identifier [(2, 2), (2, 8)])
#>   arguments: (arguments [(2, 8), (2, 19)]
#>     open: "(" [(2, 8), (2, 9)]
#>     argument: (argument [(2, 9), (2, 18)]
#>       name: (identifier [(2, 9), (2, 10)])
#>       "=" [(2, 11), (2, 12)]
#>       value: (binary_operator [(2, 13), (2, 18)]
#>         lhs: (identifier [(2, 13), (2, 14)])
#>         operator: "+" [(2, 15), (2, 16)]
#>         rhs: (float [(2, 17), (2, 18)])
#>       )
#>     )
#>     close: ")" [(2, 18), (2, 19)]
#>   )
#> )

# Compact view, more like an AST
node_show_s_expression(
  node,
  show_anonymous = FALSE,
  show_locations = FALSE,
  dangling_parenthesis = FALSE
)
#> (call
#>   function: (identifier)
#>   arguments: (arguments
#>     argument: (argument
#>       name: (identifier)
#>       value: (binary_operator
#>         lhs: (identifier)
#>         rhs: (float)))))

Copy Link

Version

Install

install.packages('treesitter')

Monthly Downloads

1,423

Version

0.3.0

License

MIT + file LICENSE

Issues

Pull Requests

Stars

Forks

Maintainer

Davis Vaughan

Last Published

June 6th, 2025

Functions in treesitter (0.3.0)

node-field-name-for-child

Get a child's field name by index
language_field_name_for_id

Language field names
is_parser

Is x a parser?
TreeCursor

Tree cursors
is_language

Is x a language?
language_field_id_for_name

Language field identifiers
language_next_state

Language state advancement
node-grammar

Node grammar types and symbols
is_tree

Is x a tree?
language_state_count

Language state count
node-child-count

Get a node's child count
node_text

Get a node's underlying text
node_symbol

Node symbol
node-parse-state

Node parse states
node-metadata

Node metadata
parser-parse

Parse or reparse text
ranges

Ranges
node-first-child-byte

Get the first child that extends beyond the given byte offset
parser-adjustments

Parser adjustments
query

Queries
node_parent

Get a node's parent
node-child

Get a node's child by index
node_raw_s_expression

"Raw" S-expression
node_descendant_count

Node descendant count
node-sibling

Node sibling accessors
query-accessors

Query accessors
node_walk

Generate a TreeCursor iterator
text_parse

Parse a snippet of text
tree-accessors

Tree accessors
node_type

Node type
tree_root_node

Retrieve the root node of the tree
tree_root_node_with_offset

Retrieve an offset root node
node_show_s_expression

Pretty print a node's s-expression
tree_walk

Generate a TreeCursor iterator
node-location

Node byte and point accessors
treesitter-package

treesitter: Bindings to 'Tree-Sitter'
node-descendant

Node descendants
node-children

Get a node's children
parser

Create a new parser
query-matches-and-captures

Query matches and captures
points

Points
x_tree_sitter_query

Helper page for consistent documentation
x_tree_sitter_parser

Helper page for consistent documentation
x_tree_sitter_node

Helper page for consistent documentation
x_tree_sitter_tree

Helper page for consistent documentation
language_field_count

Language field count
is_query

Is x a query?
is_node

Is x a node?
language_name

Language name
language_symbol_name

Language symbol names
node-child-by-field

Get a node's child by field id or name
language_symbol_for_name

Language symbols
language_symbol_count

Language symbol count
node_language

Get a node's underlying language