Showing preview only (525K chars total). Download the full file or copy to clipboard to get everything.
Repository: tree-sitter/tree-sitter-ruby
Branch: master
Commit: ad907a69da0c
Files: 67
Total size: 15.1 MB
Directory structure:
gitextract_arlgabw0/
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ └── feature_request.yml
│ └── workflows/
│ ├── ci.yml
│ ├── fuzz.yml
│ ├── lint.yml
│ └── publish.yml
├── .gitignore
├── CMakeLists.txt
├── Cargo.toml
├── LICENSE
├── Makefile
├── Package.resolved
├── Package.swift
├── README.md
├── binding.gyp
├── bindings/
│ ├── c/
│ │ ├── tree-sitter-ruby.h
│ │ └── tree-sitter-ruby.pc.in
│ ├── go/
│ │ ├── binding.go
│ │ └── binding_test.go
│ ├── node/
│ │ ├── binding.cc
│ │ ├── binding_test.js
│ │ ├── index.d.ts
│ │ └── index.js
│ ├── python/
│ │ ├── tests/
│ │ │ └── test_binding.py
│ │ └── tree_sitter_ruby/
│ │ ├── __init__.py
│ │ ├── __init__.pyi
│ │ ├── binding.c
│ │ └── py.typed
│ ├── rust/
│ │ ├── build.rs
│ │ └── lib.rs
│ └── swift/
│ ├── TreeSitterRuby/
│ │ └── ruby.h
│ └── TreeSitterRubyTests/
│ └── TreeSitterRubyTests.swift
├── eslint.config.mjs
├── go.mod
├── go.sum
├── grammar.js
├── package.json
├── pyproject.toml
├── queries/
│ ├── highlights.scm
│ ├── locals.scm
│ └── tags.scm
├── setup.py
├── src/
│ ├── grammar.json
│ ├── node-types.json
│ ├── parser.c
│ ├── scanner.c
│ └── tree_sitter/
│ ├── alloc.h
│ ├── array.h
│ └── parser.h
├── test/
│ ├── corpus/
│ │ ├── comments.txt
│ │ ├── control-flow.txt
│ │ ├── declarations.txt
│ │ ├── expressions.txt
│ │ ├── line-endings.txt
│ │ ├── literals.txt
│ │ ├── patterns.txt
│ │ ├── single-cr-as-whitespace.txt
│ │ └── statements.txt
│ └── highlight/
│ ├── classes.rb
│ ├── constants.rb
│ ├── literals.rb
│ ├── patterns.rb
│ └── variables.rb
└── tree-sitter.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*]
charset = utf-8
[*.{json,toml,yml,gyp}]
indent_style = space
indent_size = 2
[*.js]
indent_style = space
indent_size = 2
[*.scm]
indent_style = space
indent_size = 2
[*.{c,cc,h}]
indent_style = space
indent_size = 4
[*.rs]
indent_style = space
indent_size = 4
[*.{py,pyi}]
indent_style = space
indent_size = 4
[*.swift]
indent_style = space
indent_size = 4
[*.go]
indent_style = tab
indent_size = 8
[Makefile]
indent_style = tab
indent_size = 8
[parser.c]
indent_size = 2
[{alloc,array,parser}.h]
indent_size = 2
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
# Generated source files
src/*.json linguist-generated
src/parser.c linguist-generated
src/tree_sitter/* linguist-generated
# C bindings
bindings/c/* linguist-generated
CMakeLists.txt linguist-generated
Makefile linguist-generated
# Rust bindings
bindings/rust/* linguist-generated
Cargo.toml linguist-generated
Cargo.lock linguist-generated
# Node.js bindings
bindings/node/* linguist-generated
binding.gyp linguist-generated
package.json linguist-generated
package-lock.json linguist-generated
# Python bindings
bindings/python/** linguist-generated
setup.py linguist-generated
pyproject.toml linguist-generated
# Go bindings
bindings/go/* linguist-generated
go.mod linguist-generated
go.sum linguist-generated
# Swift bindings
bindings/swift/** linguist-generated
Package.swift linguist-generated
Package.resolved linguist-generated
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug Report
description: File a bug or issue
title: "bug: "
labels: [bug]
body:
- type: markdown
attributes:
value: |
**Before** reporting an issue, make sure to search [existing issues](https://github.com/tree-sitter/tree-sitter-c/issues). Usage questions such as ***"How do I...?"*** either belong in [Discussions](https://github.com/tree-sitter/tree-sitter/discussions) upstream or in our [Discord server](https://discord.gg/w7nTvsVJhm) and will be closed.
If your issue is related to a bug in your editor-experience because your editor *leverages* tree-sitter and this parser, then it is likely your issue does *NOT* belong here and belongs in the relevant editor's repository.
- type: checkboxes
attributes:
label: Did you check existing issues?
description: Make sure you've checked all of the below before submitting an issue
options:
- label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser
required: false
- label: I have searched the existing issues of tree-sitter-c
required: true
- type: input
attributes:
label: "Tree-Sitter CLI Version, if relevant (output of `tree-sitter --version`)"
placeholder: "tree-sitter 0.20.8 (6bbb50bef8249e6460e7d69e42cc8146622fa4fd)"
validations:
required: false
- type: textarea
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is. Please include any related errors you see such as parsing errors or tree-sitter cli errors.
validations:
required: true
- type: textarea
attributes:
label: Steps To Reproduce/Bad Parse Tree
description: Steps to reproduce the behavior. If you have a bad parse tree, please include it here. You can get this by running `tree-sitter parse <path-to-file>` and copying the output.
placeholder: |
1.
2.
3.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior/Parse Tree
description: A concise description of what you expected to happen, or in the case of a bad parse tree, the expected parse tree.
validations:
required: true
- type: textarea
attributes:
label: Repro
description: Minimal code to reproduce this issue. Ideally this should be reproducible with the C library or the tree-sitter cli, do not suggest an editor or external tool.
value: |
// Example code that causes the issue
void foo() {
// Code that fails to parse, or causes an error
}
render: C
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: Feature Request
description: Suggest a new feature
title: "feature: "
labels: [enhancement]
body:
- type: checkboxes
attributes:
label: Did you check the tree-sitter docs?
description: Make sure you read all the docs before submitting a feature request
options:
- label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser
required: false
- type: textarea
validations:
required: true
attributes:
label: Is your feature request related to a problem? Please describe.
description: A clear and concise description of what the problem is. Ex. I think the grammar models this rule incorrectly and can be improved, or the C spec has officially added a new feature that should be added to the grammar.
- type: textarea
validations:
required: true
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
- type: textarea
validations:
required: true
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
- type: textarea
validations:
required: false
attributes:
label: Additional context
description: Add any other context or screenshots about the feature request here. If your feature request is related to a new C feature, please include a link to the relevant **official** C documentation.
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches: [master]
paths:
- grammar.js
- src/**
- test/**
- bindings/**
- binding.gyp
pull_request:
paths:
- grammar.js
- src/**
- test/**
- bindings/**
- binding.gyp
concurrency:
group: ${{github.workflow}}-${{github.ref}}
cancel-in-progress: true
jobs:
test:
name: Test parser
runs-on: ${{matrix.os}}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-14]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up tree-sitter
uses: tree-sitter/setup-action/cli@v1
- name: Set up examples
run: |
git clone https://github.com/ruby/spec examples/ruby_spec --single-branch --depth=1 --filter=blob:none
- name: Run tests
uses: tree-sitter/parser-test-action@v2
with:
test-rust: true
test-node: true
test-python: true
test-go: true
test-swift: true
- name: Parse examples
uses: tree-sitter/parse-action@v4
with:
files: |
examples/*.rb
!examples/ruby_spec/command_line/fixtures/bad_syntax.rb
!examples/ruby_spec/command_line/fixtures/freeze_flag_required_diff_enc.rb
!examples/ruby_spec/core/enumerable/shared/inject.rb
!examples/ruby_spec/language/fixtures/freeze_magic_comment_required_diff_enc.rb
!examples/ruby_spec/language/string_spec.rb
!examples/ruby_spec/core/proc/ruby2_keywords_spec.rb
!examples/ruby_spec/language/fixtures/utf16-be-nobom.rb
!examples/ruby_spec/language/fixtures/utf16-le-nobom.rb
!examples/ruby_spec/language/lambda_spec.rb
================================================
FILE: .github/workflows/fuzz.yml
================================================
name: Fuzz Parser
on:
push:
branches: [master]
paths:
- src/scanner.c
pull_request:
paths:
- src/scanner.c
jobs:
fuzz:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run fuzzer
uses: tree-sitter/fuzz-action@v4
================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint
on:
push:
branches: [master]
paths:
- grammar.js
pull_request:
paths:
- grammar.js
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
cache: npm
node-version: ${{vars.NODE_VERSION}}
- name: Install modules
run: npm ci --legacy-peer-deps
- name: Run ESLint
run: npm run lint
================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish packages
on:
push:
tags: ["*"]
permissions:
contents: write
id-token: write
attestations: write
jobs:
github:
uses: tree-sitter/workflows/.github/workflows/release.yml@main
with:
generate: true
attestations: true
npm:
uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main
secrets:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
with:
generate: true
crates:
uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main
secrets:
CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_REGISTRY_TOKEN}}
with:
generate: true
pypi:
uses: tree-sitter/workflows/.github/workflows/package-pypi.yml@main
secrets:
PYPI_API_TOKEN: ${{secrets.PYPI_API_TOKEN}}
with:
generate: true
================================================
FILE: .gitignore
================================================
# Rust artifacts
target/
# Node artifacts
build/
prebuilds/
node_modules/
# Swift artifacts
.build/
# Go artifacts
_obj/
# Python artifacts
.venv/
dist/
*.egg-info
*.whl
# C artifacts
*.a
*.so
*.so.*
*.dylib
*.dll
*.pc
# Example dirs
/examples/*/
# Grammar volatiles
*.wasm
*.obj
*.o
# Archives
*.tar.gz
*.tgz
*.zip
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.13)
project(tree-sitter-ruby
VERSION "0.23.1"
DESCRIPTION "Ruby grammar for tree-sitter"
HOMEPAGE_URL "https://github.com/tree-sitter/tree-sitter-ruby"
LANGUAGES C)
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
option(TREE_SITTER_REUSE_ALLOCATOR "Reuse the library allocator" OFF)
set(TREE_SITTER_ABI_VERSION 14 CACHE STRING "Tree-sitter ABI version")
if(NOT ${TREE_SITTER_ABI_VERSION} MATCHES "^[0-9]+$")
unset(TREE_SITTER_ABI_VERSION CACHE)
message(FATAL_ERROR "TREE_SITTER_ABI_VERSION must be an integer")
endif()
find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI")
add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json"
COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json
--abi=${TREE_SITTER_ABI_VERSION}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Generating parser.c")
add_library(tree-sitter-ruby src/parser.c)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c)
target_sources(tree-sitter-ruby PRIVATE src/scanner.c)
endif()
target_include_directories(tree-sitter-ruby PRIVATE src)
target_compile_definitions(tree-sitter-ruby PRIVATE
$<$<BOOL:${TREE_SITTER_REUSE_ALLOCATOR}>:TREE_SITTER_REUSE_ALLOCATOR>
$<$<CONFIG:Debug>:TREE_SITTER_DEBUG>)
set_target_properties(tree-sitter-ruby
PROPERTIES
C_STANDARD 11
POSITION_INDEPENDENT_CODE ON
SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}"
DEFINE_SYMBOL "")
configure_file(bindings/c/tree-sitter-ruby.pc.in
"${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-ruby.pc" @ONLY)
include(GNUInstallDirs)
install(FILES bindings/c/tree-sitter-ruby.h
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/tree_sitter")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-ruby.pc"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig")
install(TARGETS tree-sitter-ruby
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
add_custom_target(ts-test "${TREE_SITTER_CLI}" test
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "tree-sitter test")
================================================
FILE: Cargo.toml
================================================
[package]
name = "tree-sitter-ruby"
description = "Ruby grammar for tree-sitter"
version = "0.23.1"
authors = [
"Max Brunsfeld <maxbrunsfeld@gmail.com>",
"Amaan Qureshi <amaanq12@gmail.com>",
]
license = "MIT"
readme = "README.md"
keywords = ["incremental", "parsing", "tree-sitter", "ruby"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/tree-sitter/tree-sitter-ruby"
edition = "2021"
autoexamples = false
build = "bindings/rust/build.rs"
include = ["LICENSE", "bindings/rust/*", "grammar.js", "queries/*", "src/*", "tree-sitter.json"]
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter-language = "0.1"
[build-dependencies]
cc = "1.1"
[dev-dependencies]
tree-sitter = "0.24"
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2016 Rob Rix
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Makefile
================================================
ifeq ($(OS),Windows_NT)
$(error Windows is not supported)
endif
LANGUAGE_NAME := tree-sitter-ruby
HOMEPAGE_URL := https://github.com/tree-sitter/tree-sitter-ruby
VERSION := 0.23.1
# repository
SRC_DIR := src
TS ?= tree-sitter
# install directory layout
PREFIX ?= /usr/local
INCLUDEDIR ?= $(PREFIX)/include
LIBDIR ?= $(PREFIX)/lib
PCLIBDIR ?= $(LIBDIR)/pkgconfig
# source/object files
PARSER := $(SRC_DIR)/parser.c
EXTRAS := $(filter-out $(PARSER),$(wildcard $(SRC_DIR)/*.c))
OBJS := $(patsubst %.c,%.o,$(PARSER) $(EXTRAS))
# flags
ARFLAGS ?= rcs
override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC
# ABI versioning
SONAME_MAJOR = $(shell sed -n 's/\#define LANGUAGE_VERSION //p' $(PARSER))
SONAME_MINOR = $(word 1,$(subst ., ,$(VERSION)))
# OS-specific bits
ifeq ($(shell uname),Darwin)
SOEXT = dylib
SOEXTVER_MAJOR = $(SONAME_MAJOR).$(SOEXT)
SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT)
LINKSHARED = -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER),-rpath,@executable_path/../Frameworks
else
SOEXT = so
SOEXTVER_MAJOR = $(SOEXT).$(SONAME_MAJOR)
SOEXTVER = $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR)
LINKSHARED = -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER)
endif
ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),)
PCLIBDIR := $(PREFIX)/libdata/pkgconfig
endif
all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc
lib$(LANGUAGE_NAME).a: $(OBJS)
$(AR) $(ARFLAGS) $@ $^
lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS)
$(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@
ifneq ($(STRIP),)
$(STRIP) $@
endif
$(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in
sed -e 's|@PROJECT_VERSION@|$(VERSION)|' \
-e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \
-e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \
-e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \
-e 's|@PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \
-e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@
$(PARSER): $(SRC_DIR)/grammar.json
$(TS) generate $^
install: all
install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)'
install -m644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h
install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a
install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER)
ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR)
ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT)
uninstall:
$(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \
'$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \
'$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \
'$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc
clean:
$(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT)
test:
$(TS) test
.PHONY: all install uninstall clean test
================================================
FILE: Package.resolved
================================================
{
"object": {
"pins": [
{
"package": "SwiftTreeSitter",
"repositoryURL": "https://github.com/ChimeHQ/SwiftTreeSitter",
"state": {
"branch": null,
"revision": "2599e95310b3159641469d8a21baf2d3d200e61f",
"version": "0.8.0"
}
}
]
},
"version": 1
}
================================================
FILE: Package.swift
================================================
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "TreeSitterRuby",
products: [
.library(name: "TreeSitterRuby", targets: ["TreeSitterRuby"]),
],
dependencies: [
.package(url: "https://github.com/ChimeHQ/SwiftTreeSitter", from: "0.8.0"),
],
targets: [
.target(
name: "TreeSitterRuby",
dependencies: [],
path: ".",
sources: [
"src/parser.c",
"src/scanner.c",
],
resources: [
.copy("queries")
],
publicHeadersPath: "bindings/swift",
cSettings: [.headerSearchPath("src")]
),
.testTarget(
name: "TreeSitterRubyTests",
dependencies: [
"SwiftTreeSitter",
"TreeSitterRuby",
],
path: "bindings/swift/TreeSitterRubyTests"
)
],
cLanguageStandard: .c11
)
================================================
FILE: README.md
================================================
# tree-sitter-ruby
[![CI][ci]](https://github.com/tree-sitter/tree-sitter-ruby/actions/workflows/ci.yml)
[![discord][discord]](https://discord.gg/w7nTvsVJhm)
[![matrix][matrix]](https://matrix.to/#/#tree-sitter-chat:matrix.org)
[![crates][crates]](https://crates.io/crates/tree-sitter-ruby)
[![npm][npm]](https://www.npmjs.com/package/tree-sitter-ruby)
[![pypi][pypi]](https://pypi.org/project/tree-sitter-ruby)
Ruby grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).
#### References
- [AST Format of the Whitequark parser](https://github.com/whitequark/parser/blob/master/doc/AST_FORMAT.md)
[ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter/tree-sitter-ruby/ci.yml?logo=github&label=CI
[discord]: https://img.shields.io/discord/1063097320771698699?logo=discord&label=discord
[matrix]: https://img.shields.io/matrix/tree-sitter-chat%3Amatrix.org?logo=matrix&label=matrix
[npm]: https://img.shields.io/npm/v/tree-sitter-ruby?logo=npm
[crates]: https://img.shields.io/crates/v/tree-sitter-ruby?logo=rust
[pypi]: https://img.shields.io/pypi/v/tree-sitter-ruby?logo=pypi&logoColor=ffd242
================================================
FILE: binding.gyp
================================================
{
"targets": [
{
"target_name": "tree_sitter_ruby_binding",
"dependencies": [
"<!(node -p \"require('node-addon-api').targets\"):node_addon_api_except",
],
"include_dirs": [
"src",
],
"sources": [
"bindings/node/binding.cc",
"src/parser.c",
"src/scanner.c",
],
"conditions": [
["OS!='win'", {
"cflags_c": [
"-std=c11",
],
}, { # OS == "win"
"cflags_c": [
"/std:c11",
"/utf-8",
],
}],
],
}
]
}
================================================
FILE: bindings/c/tree-sitter-ruby.h
================================================
#ifndef TREE_SITTER_RUBY_H_
#define TREE_SITTER_RUBY_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
const TSLanguage *tree_sitter_ruby(void);
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_RUBY_H_
================================================
FILE: bindings/c/tree-sitter-ruby.pc.in
================================================
prefix=@CMAKE_INSTALL_PREFIX@
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: tree-sitter-ruby
Description: @PROJECT_DESCRIPTION@
URL: @PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
Libs: -L${libdir} -ltree-sitter-ruby
Cflags: -I${includedir}
================================================
FILE: bindings/go/binding.go
================================================
package tree_sitter_ruby
// #cgo CFLAGS: -std=c11 -fPIC
// #include "../../src/parser.c"
// #include "../../src/scanner.c"
import "C"
import "unsafe"
// Get the tree-sitter Language for this grammar.
func Language() unsafe.Pointer {
return unsafe.Pointer(C.tree_sitter_ruby())
}
================================================
FILE: bindings/go/binding_test.go
================================================
package tree_sitter_ruby_test
import (
"testing"
tree_sitter "github.com/tree-sitter/go-tree-sitter"
tree_sitter_ruby "github.com/tree-sitter/tree-sitter-ruby/bindings/go"
)
func TestCanLoadGrammar(t *testing.T) {
language := tree_sitter.NewLanguage(tree_sitter_ruby.Language())
if language == nil {
t.Errorf("Error loading Ruby grammar")
}
}
================================================
FILE: bindings/node/binding.cc
================================================
#include <napi.h>
typedef struct TSLanguage TSLanguage;
extern "C" TSLanguage *tree_sitter_ruby();
// "tree-sitter", "language" hashed with BLAKE2
const napi_type_tag LANGUAGE_TYPE_TAG = {
0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16
};
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports["name"] = Napi::String::New(env, "ruby");
auto language = Napi::External<TSLanguage>::New(env, tree_sitter_ruby());
language.TypeTag(&LANGUAGE_TYPE_TAG);
exports["language"] = language;
return exports;
}
NODE_API_MODULE(tree_sitter_ruby_binding, Init)
================================================
FILE: bindings/node/binding_test.js
================================================
const assert = require("node:assert");
const { test } = require("node:test");
const Parser = require("tree-sitter");
test("can load grammar", () => {
const parser = new Parser();
assert.doesNotThrow(() => parser.setLanguage(require(".")));
});
================================================
FILE: bindings/node/index.d.ts
================================================
type BaseNode = {
type: string;
named: boolean;
};
type ChildNode = {
multiple: boolean;
required: boolean;
types: BaseNode[];
};
type NodeInfo =
| (BaseNode & {
subtypes: BaseNode[];
})
| (BaseNode & {
fields: { [name: string]: ChildNode };
children: ChildNode[];
});
type Language = {
name: string;
language: unknown;
nodeTypeInfo: NodeInfo[];
};
declare const language: Language;
export = language;
================================================
FILE: bindings/node/index.js
================================================
const root = require("path").join(__dirname, "..", "..");
module.exports =
typeof process.versions.bun === "string"
// Support `bun build --compile` by being statically analyzable enough to find the .node file at build-time
? require(`../../prebuilds/${process.platform}-${process.arch}/tree-sitter-ruby.node`)
: require("node-gyp-build")(root);
try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
} catch (_) {}
================================================
FILE: bindings/python/tests/test_binding.py
================================================
from unittest import TestCase
import tree_sitter, tree_sitter_ruby
class TestLanguage(TestCase):
def test_can_load_grammar(self):
try:
tree_sitter.Language(tree_sitter_ruby.language())
except Exception:
self.fail("Error loading Ruby grammar")
================================================
FILE: bindings/python/tree_sitter_ruby/__init__.py
================================================
"""Ruby grammar for tree-sitter"""
from importlib.resources import files as _files
from ._binding import language
def _get_query(name, file):
query = _files(f"{__package__}.queries") / file
globals()[name] = query.read_text()
return globals()[name]
def __getattr__(name):
if name == "HIGHLIGHTS_QUERY":
return _get_query("HIGHLIGHTS_QUERY", "highlights.scm")
if name == "LOCALS_QUERY":
return _get_query("LOCALS_QUERY", "locals.scm")
if name == "TAGS_QUERY":
return _get_query("TAGS_QUERY", "tags.scm")
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
__all__ = [
"language",
"HIGHLIGHTS_QUERY",
"LOCALS_QUERY",
"TAGS_QUERY",
]
def __dir__():
return sorted(__all__ + [
"__all__", "__builtins__", "__cached__", "__doc__", "__file__",
"__loader__", "__name__", "__package__", "__path__", "__spec__",
])
================================================
FILE: bindings/python/tree_sitter_ruby/__init__.pyi
================================================
from typing import Final
HIGHLIGHTS_QUERY: Final[str]
LOCALS_QUERY: Final[str]
TAGS_QUERY: Final[str]
def language() -> object: ...
================================================
FILE: bindings/python/tree_sitter_ruby/binding.c
================================================
#include <Python.h>
typedef struct TSLanguage TSLanguage;
TSLanguage *tree_sitter_ruby(void);
static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) {
return PyCapsule_New(tree_sitter_ruby(), "tree_sitter.Language", NULL);
}
static PyMethodDef methods[] = {
{"language", _binding_language, METH_NOARGS,
"Get the tree-sitter language for this grammar."},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "_binding",
.m_doc = NULL,
.m_size = -1,
.m_methods = methods
};
PyMODINIT_FUNC PyInit__binding(void) {
return PyModule_Create(&module);
}
================================================
FILE: bindings/python/tree_sitter_ruby/py.typed
================================================
================================================
FILE: bindings/rust/build.rs
================================================
fn main() {
let src_dir = std::path::Path::new("src");
let mut c_config = cc::Build::new();
c_config
.std("c11")
.include(src_dir)
.flag_if_supported("-Wno-unused-value");
#[cfg(target_env = "msvc")]
c_config.flag("-utf-8");
if std::env::var("TARGET").unwrap() == "wasm32-unknown-unknown" {
let Ok(wasm_headers) = std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS") else {
panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS must be set by the language crate");
};
let Ok(wasm_src) =
std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_SRC").map(std::path::PathBuf::from)
else {
panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_SRC must be set by the language crate");
};
c_config.include(&wasm_headers);
c_config.files([
wasm_src.join("stdio.c"),
wasm_src.join("stdlib.c"),
wasm_src.join("string.c"),
wasm_src.join("wctype.c"),
]);
}
let parser_path = src_dir.join("parser.c");
c_config.file(&parser_path);
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
let scanner_path = src_dir.join("scanner.c");
c_config.file(&scanner_path);
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
c_config.compile("tree-sitter-ruby");
}
================================================
FILE: bindings/rust/lib.rs
================================================
//! This crate provides Ruby language support for the [tree-sitter][] parsing library.
//!
//! Typically, you will use the [LANGUAGE][] constant to add this language to a
//! tree-sitter [Parser][], and then use the parser to parse some code:
//!
//! ```
//! use tree_sitter::Parser;
//!
//! let code = r#"
//! def hello(name)
//! puts "Hello, #{name}!"
//! end
//! "#;
//! let mut parser = Parser::new();
//! let language = tree_sitter_ruby::LANGUAGE;
//! parser
//! .set_language(&language.into())
//! .expect("Error loading Ruby parser");
//! let tree = parser.parse(code, None).unwrap();
//! assert!(!tree.root_node().has_error());
//! ```
//!
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
//! [tree-sitter]: https://tree-sitter.github.io/
use tree_sitter_language::LanguageFn;
extern "C" {
fn tree_sitter_ruby() -> *const ();
}
/// The tree-sitter [`LanguageFn`][LanguageFn] for this grammar.
///
/// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html
pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_ruby) };
/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
/// The syntax highlighting query for this language.
pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
/// The local-variable syntax highlighting query for this language.
pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm");
/// The symbol tagging query for this language.
pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");
#[cfg(test)]
mod tests {
#[test]
fn test_can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
parser
.set_language(&super::LANGUAGE.into())
.expect("Error loading Ruby parser");
}
}
================================================
FILE: bindings/swift/TreeSitterRuby/ruby.h
================================================
#ifndef TREE_SITTER_RUBY_H_
#define TREE_SITTER_RUBY_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
const TSLanguage *tree_sitter_ruby(void);
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_RUBY_H_
================================================
FILE: bindings/swift/TreeSitterRubyTests/TreeSitterRubyTests.swift
================================================
import XCTest
import SwiftTreeSitter
import TreeSitterRuby
final class TreeSitterRubyTests: XCTestCase {
func testCanLoadGrammar() throws {
let parser = Parser()
let language = Language(language: tree_sitter_ruby())
XCTAssertNoThrow(try parser.setLanguage(language),
"Error loading Ruby grammar")
}
}
================================================
FILE: eslint.config.mjs
================================================
import treesitter from 'eslint-config-treesitter';
export default [
...treesitter,
];
================================================
FILE: go.mod
================================================
module github.com/tree-sitter/tree-sitter-ruby
go 1.22
require github.com/tree-sitter/go-tree-sitter v0.24.0
require github.com/mattn/go-pointer v0.0.1 // indirect
================================================
FILE: go.sum
================================================
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tree-sitter/go-tree-sitter v0.24.0 h1:kRZb6aBNfcI/u0Qh8XEt3zjNVnmxTisDBN+kXK0xRYQ=
github.com/tree-sitter/go-tree-sitter v0.24.0/go.mod h1:x681iFVoLMEwOSIHA1chaLkXlroXEN7WY+VHGFaoDbk=
github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb h1:A8425heRM8mylnv4H58FPUiH+aYivyitre0PzxrfmWs=
github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb/go.mod h1:dOF6gtQiF9UwNh995T5OphYmtIypkjsp3ap7r9AN/iA=
github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148 h1:AfFPZwtwGN01BW1jDdqBVqscTwetvMpydqYZz57RSlc=
github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148/go.mod h1:Bh6U3viD57rFXRYIQ+kmiYtr+1Bx0AceypDLJJSyi9s=
github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33 h1:TwqSV3qLp3tKSqirGLRHnjFk9Tc2oy57LIl+FQ4GjI4=
github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33/go.mod h1:CvCKCt3v04Ufos1zZnNCelBDeCGRpPucaN8QczoUsN4=
github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012 h1:Xvxck3tE5FW7F7bTS97iNM2ADMyCMJztVqn5HYKdJGo=
github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012/go.mod h1:T40D0O1cPvUU/+AmiXVXy1cncYQT6wem4Z0g4SfAYvY=
github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0 h1:c46K6uh5Dz00zJeU9BfjXdb8I+E4RkUdfnWJpQADXFo=
github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0/go.mod h1:hcNt/kOJHcIcuMvouE7LJcYdeFUFbVpBJ6d4wmOA+tU=
github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495 h1:jrt4qbJVEFs4H93/ITxygHc6u0TGqAkkate7TQ4wFSA=
github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495/go.mod h1:oyaR7fLnRV0hT9z6qwE9GkaeTom/hTDwK3H2idcOJFc=
github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5 h1:om4X9AVg3asL8gxNJDcz4e/Wp+VpQj1PY3uJXKr6EOg=
github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5/go.mod h1:nNqgPoV/h9uYWk6kYEFdEAhNVOacpfpRW5SFmdaP4tU=
github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5 h1:pfV3G3k7NCKqKk8THBmyuh2zA33lgYHS3GVrzRR8ry4=
github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5/go.mod h1:GbMKRjLfk0H+PI7nLi1Sx5lHf5wCpLz9al8tQYSxpEk=
github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1 h1:ZXZMDwE+IhUtGug4Brv6NjJWUU3rfkZBKpemf6RY8/g=
github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1/go.mod h1:UKCLuYnJ312Mei+3cyTmGOHzn0YAnaPRECgJmHtzrqs=
github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb h1:EXEM82lFM7JjJb6qiKZXkpIDaCcbV2obNn82ghwj9lw=
github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb/go.mod h1:lXCF1nGG5Dr4J3BTS0ObN4xJCCICiSu/b+Xe/VqMV7g=
github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447 h1:o9alBu1J/WjrcTKEthYtXmdkDc5OVXD+PqlvnEZ0Lzc=
github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447/go.mod h1:1Oh95COkkTn6Ezp0vcMbvfhRP5gLeqqljR0BYnBzWvc=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
================================================
FILE: grammar.js
================================================
/// <reference types="tree-sitter-cli/dsl" />
// @ts-check
const PREC = {
COMMENT: -2,
CURLY_BLOCK: 1,
DO_BLOCK: -1,
AND: -2,
OR: -2,
NOT: 5,
DEFINED: 10,
ALIAS: 11,
ASSIGN: 15,
RESCUE: 16,
CONDITIONAL: 20,
RANGE: 25,
BOOLEAN_OR: 30,
BOOLEAN_AND: 35,
RELATIONAL: 40,
COMPARISON: 45,
BITWISE_OR: 50,
BITWISE_AND: 55,
CALL: 56,
SHIFT: 60,
ADDITIVE: 65,
MULTIPLICATIVE: 70,
UNARY_MINUS: 75,
EXPONENTIAL: 80,
COMPLEMENT: 85,
};
const IDENTIFIER_CHARS = /[^\x00-\x1F\s:;`"'@$#.,|^&<=>+\-*/\\%?!~()\[\]{}]*/;
const LOWER_ALPHA_CHAR = /[^\x00-\x1F\sA-Z0-9:;`"'@$#.,|^&<=>+\-*/\\%?!~()\[\]{}]/;
const ALPHA_CHAR = /[^\x00-\x1F\s0-9:;`"'@$#.,|^&<=>+\-*/\\%?!~()\[\]{}]/;
module.exports = grammar({
name: 'ruby',
inline: $ => [$._arg_rhs, $._call_operator],
externals: $ => [
$._line_break,
$._no_line_break,
// Delimited literals
$.simple_symbol,
$._string_start,
$._symbol_start,
$._subshell_start,
$._regex_start,
$._string_array_start,
$._symbol_array_start,
$._heredoc_body_start,
$.string_content,
$.heredoc_content,
$._string_end,
$.heredoc_end,
$.heredoc_beginning,
// Tokens that require lookahead
'/',
$._block_ampersand,
$._splat_star,
$._unary_minus,
$._unary_minus_num,
$._binary_minus,
$._binary_star,
$._singleton_class_left_angle_left_langle,
$.hash_key_symbol,
$._identifier_suffix,
$._constant_suffix,
$._hash_splat_star_star,
$._binary_star_star,
$._element_reference_bracket,
$._short_interpolation,
],
extras: $ => [
$.comment,
$.heredoc_body,
/\s/,
/\\\r?\n/,
],
word: $ => $.identifier,
supertypes: $ => [
$._statement,
$._arg,
$._call_operator,
$._method_name,
$._expression,
$._variable,
$._primary,
$._simple_numeric,
$._lhs,
$._nonlocal_variable,
$._pattern_top_expr_body,
$._pattern_expr,
$._pattern_expr_basic,
$._pattern_primitive,
$._pattern_constant,
],
rules: {
program: $ => seq(
optional($._statements),
optional(
choice(
seq(/__END__/, $.uninterpreted),
),
),
),
uninterpreted: _ => /(.|\s)*/,
block_body: $ => $._statements,
_statements: $ => choice(
seq(
repeat1(choice(
seq($._statement, $._terminator),
$.empty_statement,
)),
optional($._statement),
),
$._statement,
),
begin_block: $ => seq('BEGIN', '{', optional($._statements), '}'),
end_block: $ => seq('END', '{', optional($._statements), '}'),
_statement: $ => choice(
$.undef,
$.alias,
$.if_modifier,
$.unless_modifier,
$.while_modifier,
$.until_modifier,
$.rescue_modifier,
$.begin_block,
$.end_block,
$._expression,
),
method: $ => seq('def', $._method_rest),
singleton_method: $ => seq(
'def',
seq(
choice(
field('object', $._variable),
seq('(', field('object', $._arg), ')'),
),
choice('.', '::'),
),
$._method_rest,
),
_method_rest: $ => seq(
field('name', $._method_name),
choice(
$._body_expr,
seq(
field('parameters', alias($.parameters, $.method_parameters)),
choice(
seq(optional($._terminator), optional(field('body', $.body_statement)), 'end'),
$._body_expr,
),
),
seq(
optional(
field('parameters', alias($.bare_parameters, $.method_parameters)),
),
$._terminator,
optional(field('body', $.body_statement)),
'end',
),
),
),
rescue_modifier_arg: $ => prec(PREC.RESCUE,
seq(
field('body', $._arg),
'rescue',
field('handler', $._arg),
),
),
rescue_modifier_expression: $ => prec(PREC.RESCUE,
seq(
field('body', $._expression),
'rescue',
field('handler', $._arg),
),
),
_body_expr: $ =>
seq(
'=',
field('body',
choice(
$._arg,
alias($.rescue_modifier_arg, $.rescue_modifier),
)),
),
parameters: $ => seq(
'(',
commaSep($._formal_parameter),
')',
),
bare_parameters: $ => seq(
$._simple_formal_parameter,
repeat(seq(',', $._formal_parameter)),
),
block_parameters: $ => seq(
'|',
seq(commaSep($._formal_parameter), optional(',')),
optional(seq(';', sep1(field('locals', $.identifier), ','))), // Block shadow args e.g. {|; a, b| ...}
'|',
),
_formal_parameter: $ => choice(
$._simple_formal_parameter,
alias($.parameters, $.destructured_parameter),
),
_simple_formal_parameter: $ => choice(
$.identifier,
$.splat_parameter,
$.hash_splat_parameter,
$.hash_splat_nil,
$.forward_parameter,
$.block_parameter,
$.keyword_parameter,
$.optional_parameter,
),
forward_parameter: _ => '...',
splat_parameter: $ => prec.right(-2, seq(
'*',
field('name', optional($.identifier)),
)),
hash_splat_parameter: $ => seq(
'**',
field('name', optional($.identifier)),
),
hash_splat_nil: _ => seq('**', 'nil'),
block_parameter: $ => seq(
'&',
field('name', optional($.identifier)),
),
keyword_parameter: $ => prec.right(PREC.BITWISE_OR + 1, seq(
field('name', $.identifier),
token.immediate(':'),
field('value', optional($._arg)),
)),
optional_parameter: $ => prec(PREC.BITWISE_OR + 1, seq(
field('name', $.identifier),
'=',
field('value', $._arg),
)),
class: $ => seq(
'class',
field('name', choice($.constant, $.scope_resolution)),
choice(
seq(field('superclass', $.superclass), $._terminator),
optional($._terminator),
),
optional(field('body', $.body_statement)),
'end',
),
superclass: $ => seq('<', $._expression),
singleton_class: $ => seq(
'class',
alias($._singleton_class_left_angle_left_langle, '<<'),
field('value', $._arg),
$._terminator,
optional(field('body', $.body_statement)),
'end',
),
module: $ => seq(
'module',
field('name', choice($.constant, $.scope_resolution)),
optional($._terminator),
optional(field('body', $.body_statement)),
'end',
),
return_command: $ => prec.left(seq('return', alias($.command_argument_list, $.argument_list))),
yield_command: $ => prec.left(seq('yield', alias($.command_argument_list, $.argument_list))),
break_command: $ => prec.left(seq('break', alias($.command_argument_list, $.argument_list))),
next_command: $ => prec.left(seq('next', alias($.command_argument_list, $.argument_list))),
return: $ => prec.left(seq('return', optional($.argument_list))),
yield: $ => prec.left(seq('yield', optional($.argument_list))),
break: $ => prec.left(seq('break', optional($.argument_list))),
next: $ => prec.left(seq('next', optional($.argument_list))),
redo: $ => prec.left(seq('redo', optional($.argument_list))),
retry: $ => prec.left(seq('retry', optional($.argument_list))),
if_modifier: $ => prec(PREC.RESCUE, seq(
field('body', $._statement),
'if',
field('condition', $._expression),
)),
unless_modifier: $ => prec(PREC.RESCUE, seq(
field('body', $._statement),
'unless',
field('condition', $._expression),
)),
while_modifier: $ => prec(PREC.RESCUE, seq(
field('body', $._statement),
'while',
field('condition', $._expression),
)),
until_modifier: $ => prec(PREC.RESCUE, seq(
field('body', $._statement),
'until',
field('condition', $._expression),
)),
rescue_modifier: $ => prec(PREC.RESCUE, seq(
field('body', $._statement),
'rescue',
field('handler', $._expression),
)),
while: $ => seq(
'while',
field('condition', $._statement),
field('body', $.do),
),
until: $ => seq(
'until',
field('condition', $._statement),
field('body', $.do),
),
for: $ => seq(
'for',
field('pattern', choice($._lhs, $.left_assignment_list)),
field('value', $.in),
field('body', $.do),
),
in: $ => seq('in', $._arg),
do: $ => seq(
choice('do', $._terminator),
optional($._statements),
'end',
),
case: $ => seq(
'case',
optional(seq(optional($._line_break), field('value', $._statement))),
optional($._terminator),
repeat($.when),
optional($.else),
'end',
),
case_match: $ => seq(
'case',
seq(optional($._line_break), field('value', $._statement)),
optional($._terminator),
repeat1(field('clauses', $.in_clause)),
optional(field('else', $.else)),
'end',
),
when: $ => seq(
'when',
commaSep1(field('pattern', $.pattern)),
choice($._terminator, field('body', $.then)),
),
in_clause: $ => seq(
'in',
field('pattern', $._pattern_top_expr_body),
field('guard', optional($._guard)),
choice($._terminator, field('body', $.then)),
),
pattern: $ => choice($._arg, $.splat_argument),
_guard: $ => choice(
$.if_guard,
$.unless_guard,
),
if_guard: $ => seq(
'if',
field('condition', $._expression),
),
unless_guard: $ => seq(
'unless',
field('condition', $._expression),
),
_pattern_top_expr_body: $ => prec(-1, choice(
$._pattern_expr,
alias($._array_pattern_n, $.array_pattern),
alias($._find_pattern_body, $.find_pattern),
alias($._hash_pattern_body, $.hash_pattern),
)),
_array_pattern_n: $ => prec.right(choice(
seq($._pattern_expr, alias(',', $.splat_parameter)),
seq($._pattern_expr, ',', choice($._pattern_expr, $._array_pattern_n)),
seq($.splat_parameter, repeat(seq(',', $._pattern_expr))),
)),
_pattern_expr: $ => choice(
$.as_pattern,
$._pattern_expr_alt,
),
as_pattern: $ => seq(field('value', $._pattern_expr), '=>', field('name', $.identifier)),
_pattern_expr_alt: $ => choice(
$.alternative_pattern,
$._pattern_expr_basic,
),
alternative_pattern: $ => seq(field('alternatives', $._pattern_expr_basic), repeat1(seq('|', field('alternatives', $._pattern_expr_basic)))),
_array_pattern_body: $ => choice(
$._pattern_expr,
$._array_pattern_n,
),
array_pattern: $ => prec.right(-1, choice(
seq('[', optional($._array_pattern_body), ']'),
seq(field('class', $._pattern_constant), token.immediate('['), optional($._array_pattern_body), ']'),
seq(field('class', $._pattern_constant), token.immediate('('), optional($._array_pattern_body), ')'),
)),
_find_pattern_body: $ => seq($.splat_parameter, repeat1(seq(',', $._pattern_expr)), ',', $.splat_parameter),
find_pattern: $ => choice(
seq('[', $._find_pattern_body, ']'),
seq(field('class', $._pattern_constant), token.immediate('['), $._find_pattern_body, ']'),
seq(field('class', $._pattern_constant), token.immediate('('), $._find_pattern_body, ')'),
),
_hash_pattern_body: $ => prec.right(choice(
seq(commaSep1($.keyword_pattern), optional(',')),
seq(commaSep1($.keyword_pattern), ',', $._hash_pattern_any_rest),
$._hash_pattern_any_rest,
)),
keyword_pattern: $ => prec.right(-1, seq(
field('key',
choice(
alias($.identifier, $.hash_key_symbol),
alias($.constant, $.hash_key_symbol),
alias($.identifier_suffix, $.hash_key_symbol),
alias($.constant_suffix, $.hash_key_symbol),
$.string,
),
),
token.immediate(':'),
optional(field('value', $._pattern_expr)),
)),
_hash_pattern_any_rest: $ => choice($.hash_splat_parameter, $.hash_splat_nil),
hash_pattern: $ => prec.right(-1, choice(
seq('{', optional($._hash_pattern_body), '}'),
seq(field('class', $._pattern_constant), token.immediate('['), $._hash_pattern_body, ']'),
seq(field('class', $._pattern_constant), token.immediate('('), $._hash_pattern_body, ')'),
)),
_pattern_expr_basic: $ => prec.right(-1, choice(
$._pattern_value,
$.identifier,
$.array_pattern,
$.find_pattern,
$.hash_pattern,
$.parenthesized_pattern,
)),
parenthesized_pattern: $ => seq('(', $._pattern_expr, ')'),
_pattern_value: $ => prec.right(-1, choice(
$._pattern_primitive,
alias($._pattern_range, $.range),
$.variable_reference_pattern,
$.expression_reference_pattern,
$._pattern_constant,
)),
_pattern_range: $ => {
const begin = field('begin', $._pattern_primitive);
const end = field('end', $._pattern_primitive);
const operator = field('operator', choice('..', '...'));
return choice(
seq(begin, operator, end),
seq(operator, end),
seq(begin, operator),
);
},
_pattern_primitive: $ => choice(
$._pattern_literal,
$._pattern_lambda,
),
_pattern_lambda: $ => prec.right(-1, $.lambda),
_pattern_literal: $ => prec.right(-1, choice(
$._literal,
$.string,
$.subshell,
$.heredoc_beginning,
$.regex,
$.string_array,
$.symbol_array,
$._keyword_variable,
)),
_keyword_variable: $ => prec.right(-1, choice(
$.nil,
$.self,
$.true,
$.false,
$.line,
$.file,
$.encoding,
)),
line: _ => '__LINE__',
file: _ => '__FILE__',
encoding: _ => '__ENCODING__',
variable_reference_pattern: $ => seq('^', field('name', choice($.identifier, $._nonlocal_variable))),
expression_reference_pattern: $ => seq('^', '(', field('value', $._expression), ')'),
_pattern_constant: $ => prec.right(-1, choice(
$.constant,
alias($._pattern_constant_resolution, $.scope_resolution),
)),
_pattern_constant_resolution: $ => seq(
optional(field('scope', $._pattern_constant)),
'::',
field('name', $.constant),
),
if: $ => seq(
'if',
field('condition', $._statement),
choice($._terminator, field('consequence', $.then)),
field('alternative', optional(choice($.else, $.elsif))),
'end',
),
unless: $ => seq(
'unless',
field('condition', $._statement),
choice($._terminator, field('consequence', $.then)),
field('alternative', optional(choice($.else, $.elsif))),
'end',
),
elsif: $ => seq(
'elsif',
field('condition', $._statement),
choice($._terminator, field('consequence', $.then)),
field('alternative', optional(choice($.else, $.elsif))),
),
else: $ => seq(
'else',
optional($._terminator),
optional($._statements),
),
then: $ => choice(
seq(
$._terminator,
$._statements,
),
seq(
optional($._terminator),
'then',
optional($._statements),
),
),
begin: $ => seq('begin', optional($._terminator), optional($._body_statement), 'end'),
ensure: $ => seq('ensure', optional($._statements)),
rescue: $ => seq(
'rescue',
field('exceptions', optional($.exceptions)),
field('variable', optional($.exception_variable)),
choice(
$._terminator,
field('body', $.then),
),
),
exceptions: $ => commaSep1(choice($._arg, $.splat_argument)),
exception_variable: $ => seq('=>', $._lhs),
body_statement: $ => $._body_statement,
_body_statement: $ => choice(
seq($._statements, repeat(choice($.rescue, $.else, $.ensure))),
seq(optional($._statements), repeat1(choice($.rescue, $.else, $.ensure))),
),
// Method calls without parentheses (aka "command calls") are only allowed
// in certain positions, like the top-level of a statement, the condition
// of a postfix control-flow operator like `if`, or as the value of a
// control-flow statement like `return`. In many other places, they're not
// allowed.
//
// Because of this distinction, a lot of rules have two variants: the
// normal variant, which can appear anywhere that an expression is valid,
// and the "command" varaint, which is only valid in a more limited set of
// positions, because it can contain "command calls".
//
// The `_expression` rule can appear in relatively few places, but can
// contain command calls. The `_arg` rule can appear in many more places,
// but cannot contain command calls (unless they are wrapped in parens).
// This naming convention is based on Ruby's standard grammar.
_expression: $ => choice(
alias($.command_binary, $.binary),
alias($.command_unary, $.unary),
alias($.command_assignment, $.assignment),
alias($.command_operator_assignment, $.operator_assignment),
alias($.command_call, $.call),
alias($.command_call_with_block, $.call),
prec.left(alias($._chained_command_call, $.call)),
alias($.return_command, $.return),
alias($.yield_command, $.yield),
alias($.break_command, $.break),
alias($.next_command, $.next),
$.match_pattern,
$.test_pattern,
$._arg,
),
match_pattern: $ => prec(100, seq(field('value', $._arg), '=>', field('pattern', $._pattern_top_expr_body))),
test_pattern: $ => prec(100, seq(field('value', $._arg), 'in', field('pattern', $._pattern_top_expr_body))),
_arg: $ => choice(
alias($._unary_minus_pow, $.unary),
$._primary,
$.assignment,
$.operator_assignment,
$.conditional,
$.range,
$.binary,
$.unary,
),
_unary_minus_pow: $ => seq(field('operator', alias($._unary_minus_num, '-')), field('operand', alias($._pow, $.binary))),
_pow: $ => prec.right(PREC.EXPONENTIAL, seq(field('left', $._simple_numeric), field('operator', alias($._binary_star_star, '**')), field('right', $._arg))),
_primary: $ => choice(
$.parenthesized_statements,
$._lhs,
alias($._function_identifier_call, $.call),
$.call,
$.array,
$.string_array,
$.symbol_array,
$.hash,
$.subshell,
$._literal,
$.string,
$.character,
$.chained_string,
$.regex,
$.lambda,
$.method,
$.singleton_method,
$.class,
$.singleton_class,
$.module,
$.begin,
$.while,
$.until,
$.if,
$.unless,
$.for,
$.case,
$.case_match,
$.return,
$.yield,
$.break,
$.next,
$.redo,
$.retry,
alias($.parenthesized_unary, $.unary),
$.heredoc_beginning,
),
parenthesized_statements: $ => seq('(', optional($._statements), ')'),
element_reference: $ => prec.left(1, seq(
field('object', $._primary),
alias($._element_reference_bracket, '['),
optional($._argument_list_with_trailing_comma),
']',
optional(field('block', choice($.block, $.do_block))),
)),
scope_resolution: $ => prec.left(PREC.CALL + 1, seq(
choice(
'::',
seq(field('scope', $._primary), token.immediate('::')),
),
field('name', $.constant),
)),
_call_operator: _ => choice('.', '&.', token.immediate('::')),
_call: $ => prec.left(PREC.CALL, seq(
field('receiver', $._primary),
field('operator', $._call_operator),
field('method', choice($.identifier, $.operator, $.constant, $._function_identifier)),
)),
command_call: $ => seq(
choice(
$._call,
$._chained_command_call,
field('method', choice(
$._variable,
$._function_identifier,
)),
),
field('arguments', alias($.command_argument_list, $.argument_list)),
),
command_call_with_block: $ => {
const receiver = choice(
$._call,
field('method', choice($._variable, $._function_identifier)),
);
const args = field('arguments', alias($.command_argument_list, $.argument_list));
const block = field('block', $.block);
const doBlock = field('block', $.do_block);
return choice(
seq(receiver, prec(PREC.CURLY_BLOCK, seq(args, block))),
seq(receiver, prec(PREC.DO_BLOCK, seq(args, doBlock))),
);
},
_chained_command_call: $ => seq(
field('receiver', alias($.command_call_with_block, $.call)),
field('operator', $._call_operator),
field('method', choice($.identifier, $._function_identifier, $.operator, $.constant)),
),
call: $ => {
const receiver = choice(
$._call,
field('method', choice(
$._variable, $._function_identifier,
)),
);
const args = field('arguments', $.argument_list);
const receiverArguments =
seq(
choice(
receiver,
prec.left(PREC.CALL, seq(
field('receiver', $._primary),
field('operator', $._call_operator),
)),
),
args,
);
const block = field('block', $.block);
const doBlock = field('block', $.do_block);
return choice(
receiverArguments,
prec(PREC.CURLY_BLOCK, seq(receiverArguments, block)),
prec(PREC.DO_BLOCK, seq(receiverArguments, doBlock)),
prec(PREC.CURLY_BLOCK, seq(receiver, block)),
prec(PREC.DO_BLOCK, seq(receiver, doBlock)),
);
},
command_argument_list: $ => prec.right(commaSep1($._argument)),
argument_list: $ => prec.right(seq(
token.immediate('('),
optional($._argument_list_with_trailing_comma),
')',
)),
_argument_list_with_trailing_comma: $ => prec.right(seq(
commaSep1($._argument),
optional(','),
)),
_argument: $ => prec.left(choice(
$._expression,
$.splat_argument,
$.hash_splat_argument,
$.forward_argument,
$.block_argument,
$.pair,
)),
forward_argument: _ => '...',
splat_argument: $ => prec.right(seq(alias($._splat_star, '*'), optional($._arg))),
hash_splat_argument: $ => prec.right(seq(alias($._hash_splat_star_star, '**'), optional($._arg))),
block_argument: $ => prec.right(seq(alias($._block_ampersand, '&'), optional($._arg))),
do_block: $ => seq(
'do',
optional($._terminator),
optional(seq(
field('parameters', $.block_parameters),
optional($._terminator),
)),
optional(field('body', $.body_statement)),
'end',
),
block: $ => prec(PREC.CURLY_BLOCK, seq(
'{',
field('parameters', optional($.block_parameters)),
optional(field('body', $.block_body)),
'}',
)),
_arg_rhs: $ => choice($._arg, alias($.rescue_modifier_arg, $.rescue_modifier)),
assignment: $ => prec.right(PREC.ASSIGN, choice(
seq(
field('left', choice($._lhs, $.left_assignment_list)),
'=',
field('right', choice(
$._arg_rhs,
$.splat_argument,
$.right_assignment_list,
)),
),
)),
command_assignment: $ => prec.right(PREC.ASSIGN,
seq(
field('left', choice($._lhs, $.left_assignment_list)),
'=',
field('right', choice($._expression, alias($.rescue_modifier_expression, $.rescue_modifier))),
),
),
operator_assignment: $ => prec.right(PREC.ASSIGN, seq(
field('left', $._lhs),
field('operator', choice('+=', '-=', '*=', '**=', '/=', '||=', '|=', '&&=', '&=', '%=', '>>=', '<<=', '^=')),
field('right', $._arg_rhs),
)),
command_operator_assignment: $ => prec.right(PREC.ASSIGN, seq(
field('left', $._lhs),
field('operator', choice('+=', '-=', '*=', '**=', '/=', '||=', '|=', '&&=', '&=', '%=', '>>=', '<<=', '^=')),
field('right', choice($._expression, alias($.rescue_modifier_expression, $.rescue_modifier))),
)),
conditional: $ => prec.right(PREC.CONDITIONAL, seq(
field('condition', $._arg),
'?',
field('consequence', $._arg),
':',
field('alternative', $._arg),
)),
range: $ => {
const begin = field('begin', $._arg);
const end = field('end', $._arg);
const operator = field('operator', choice('..', '...'));
return prec.right(PREC.RANGE, choice(
seq(begin, operator, end),
seq(operator, end),
seq(begin, operator),
));
},
binary: $ => {
const operators = [
[prec.left, PREC.AND, 'and'],
[prec.left, PREC.OR, 'or'],
[prec.left, PREC.BOOLEAN_OR, '||'],
[prec.left, PREC.BOOLEAN_AND, '&&'],
[prec.left, PREC.SHIFT, choice('<<', '>>')],
[prec.left, PREC.COMPARISON, choice('<', '<=', '>', '>=')],
[prec.left, PREC.BITWISE_AND, '&'],
[prec.left, PREC.BITWISE_OR, choice('^', '|')],
[prec.left, PREC.ADDITIVE, choice('+', alias($._binary_minus, '-'))],
[prec.left, PREC.MULTIPLICATIVE, choice('/', '%', alias($._binary_star, '*'))],
[prec.right, PREC.RELATIONAL, choice('==', '!=', '===', '<=>', '=~', '!~')],
[prec.right, PREC.EXPONENTIAL, alias($._binary_star_star, '**')],
];
// @ts-ignore
return choice(...operators.map(([fn, precedence, operator]) => fn(precedence, seq(
field('left', $._arg),
// @ts-ignore
field('operator', operator),
field('right', $._arg),
))));
},
command_binary: $ => prec.left(seq(
field('left', $._expression),
field('operator', choice('or', 'and')),
field('right', $._expression),
)),
unary: $ => {
const operators = [
[prec, PREC.DEFINED, 'defined?'],
[prec.right, PREC.NOT, 'not'],
[prec.right, PREC.UNARY_MINUS, choice(alias($._unary_minus, '-'), alias($._binary_minus, '-'), '+')],
[prec.right, PREC.COMPLEMENT, choice('!', '~')],
];
// @ts-ignore
return choice(...operators.map(([fn, precedence, operator]) => fn(precedence, seq(
// @ts-ignore
field('operator', operator),
field('operand', $._arg),
))));
},
command_unary: $ => {
const operators = [
[prec, PREC.DEFINED, 'defined?'],
[prec.right, PREC.NOT, 'not'],
[prec.right, PREC.UNARY_MINUS, choice(alias($._unary_minus, '-'), '+')],
[prec.right, PREC.COMPLEMENT, choice('!', '~')],
];
// @ts-ignore
return choice(...operators.map(([fn, precedence, operator]) => fn(precedence, seq(
// @ts-ignore
field('operator', operator),
field('operand', $._expression),
))));
},
parenthesized_unary: $ => prec(PREC.CALL, seq(
field('operator', choice('defined?', 'not')),
field('operand', $.parenthesized_statements),
)),
unary_literal: $ => prec.right(PREC.UNARY_MINUS, seq(
field('operator', choice(alias($._unary_minus_num, '-'), '+')),
field('operand', $._simple_numeric),
)),
_literal: $ => choice(
$.simple_symbol,
$.delimited_symbol,
$._numeric,
),
_numeric: $ => choice(
$._simple_numeric,
alias($.unary_literal, $.unary),
),
_simple_numeric: $ =>
choice(
$.integer,
$.float,
$.complex,
$.rational,
),
right_assignment_list: $ => prec(-1, commaSep1(choice($._arg, $.splat_argument))),
left_assignment_list: $ => $._mlhs,
_mlhs: $ => prec.left(-1, seq(
commaSep1(choice($._lhs, $.rest_assignment, $.destructured_left_assignment)),
optional(','),
)),
destructured_left_assignment: $ => prec(-1, seq('(', $._mlhs, ')')),
rest_assignment: $ => prec(-1, seq('*', optional($._lhs))),
_function_identifier: $ => choice(alias($.identifier_suffix, $.identifier), alias($.constant_suffix, $.constant)),
_function_identifier_call: $ => prec.left(field('method', $._function_identifier)),
_lhs: $ => prec.left(choice(
$._variable,
$.true,
$.false,
$.nil,
$.scope_resolution,
$.element_reference,
alias($._call, $.call),
)),
_variable: $ => prec.right(choice(
$.self,
$.super,
$._nonlocal_variable,
$.identifier,
$.constant,
)),
operator: _ => choice(
'..', '|', '^', '&', '<=>', '==', '===', '=~', '>', '>=', '<', '<=', '+', '!=',
'-', '*', '/', '%', '!', '!~', '**', '<<', '>>', '~', '+@', '-@', '~@', '[]', '[]=', '`',
),
_method_name: $ => choice(
$.identifier,
$._function_identifier,
$.constant,
$.setter,
$.simple_symbol,
$.delimited_symbol,
$.operator,
$._nonlocal_variable,
),
_nonlocal_variable: $ => choice(
$.instance_variable,
$.class_variable,
$.global_variable,
),
setter: $ => seq(field('name', $.identifier), token.immediate('=')),
undef: $ => seq('undef', commaSep1($._method_name)),
alias: $ => seq(
'alias',
field('name', $._method_name),
field('alias', $._method_name),
),
comment: _ => token(prec(PREC.COMMENT, choice(
seq('#', /.*/),
seq(
/=begin.*\r?\n/,
repeat(choice(
/[^=]/,
/=[^e]/,
/=e[^n]/,
/=en[^d]/,
)),
/[\s*]*=end.*/,
),
))),
integer: _ => /0[bB][01](_?[01])*|0[oO]?[0-7](_?[0-7])*|(0[dD])?\d(_?\d)*|0[xX][0-9a-fA-F](_?[0-9a-fA-F])*/,
_int_or_float: $ => choice($.integer, $.float),
float: _ => /\d(_?\d)*(\.\d)?(_?\d)*([eE][\+-]?\d(_?\d)*)?/,
complex: $ => choice(
seq($._int_or_float, token.immediate('i')),
seq(alias($._int_or_float, $.rational), token.immediate('ri')),
),
rational: $ => seq($._int_or_float, token.immediate('r')),
super: _ => 'super',
self: _ => 'self',
true: _ => 'true',
false: _ => 'false',
nil: _ => 'nil',
constant: _ => token(seq(/[A-Z]/, IDENTIFIER_CHARS)),
constant_suffix: $ => choice(token(seq(/[A-Z]/, IDENTIFIER_CHARS, /[?]/)), $._constant_suffix),
identifier: _ => token(seq(LOWER_ALPHA_CHAR, IDENTIFIER_CHARS)),
identifier_suffix: $ => choice(token(seq(LOWER_ALPHA_CHAR, IDENTIFIER_CHARS, /[?]/)), $._identifier_suffix),
instance_variable: _ => token(seq('@', ALPHA_CHAR, IDENTIFIER_CHARS)),
class_variable: _ => token(seq('@@', ALPHA_CHAR, IDENTIFIER_CHARS)),
global_variable: _ => /\$(-[a-zA-Z0-9_]|[!@&`'+~=/\\,;.<>*$?:"]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)/,
chained_string: $ => seq($.string, repeat1($.string)),
character: _ => /\?(\\\S(\{[0-9A-Fa-f]*\}|[0-9A-Fa-f]*|-\S([MC]-\S)?)?|\S)/,
interpolation: $ => choice(
seq('#{', optional($._statements), '}'),
seq($._short_interpolation, $._nonlocal_variable),
),
string: $ => seq(
alias($._string_start, '"'),
optional($._literal_contents),
alias($._string_end, '"'),
),
subshell: $ => seq(
alias($._subshell_start, '`'),
optional($._literal_contents),
alias($._string_end, '`'),
),
string_array: $ => seq(
alias($._string_array_start, '%w('),
optional(/\s+/),
sep(alias($._literal_contents, $.bare_string), /\s+/),
optional(/\s+/),
alias($._string_end, ')'),
),
symbol_array: $ => seq(
alias($._symbol_array_start, '%i('),
optional(/\s+/),
sep(alias($._literal_contents, $.bare_symbol), /\s+/),
optional(/\s+/),
alias($._string_end, ')'),
),
delimited_symbol: $ => seq(
alias($._symbol_start, ':"'),
optional($._literal_contents),
alias($._string_end, '"'),
),
regex: $ => seq(
alias($._regex_start, '/'),
optional($._literal_contents),
alias($._string_end, '/'),
),
heredoc_body: $ => seq(
$._heredoc_body_start,
repeat(choice(
$.heredoc_content,
$.interpolation,
$.escape_sequence,
)),
$.heredoc_end,
),
_literal_contents: $ => repeat1(choice(
$.string_content,
$.interpolation,
$.escape_sequence,
)),
// https://ruby-doc.org/core-2.5.0/doc/syntax/literals_rdoc.html#label-Strings
escape_sequence: _ => token(seq(
'\\',
choice(
/[^ux0-7]/, // single character
/x[0-9a-fA-F]{1,2}/, // hex code
/[0-7]{1,3}/, // octal
/u[0-9a-fA-F]{4}/, // single unicode
/u\{[0-9a-fA-F ]+\}/, // multiple unicode
),
)),
array: $ => seq(
'[',
optional($._argument_list_with_trailing_comma),
']',
),
hash: $ => seq(
'{',
optional(seq(
commaSep1(choice($.pair, $.hash_splat_argument)),
optional(','),
)),
'}',
),
pair: $ => prec.right(choice(
seq(
field('key', $._arg),
'=>',
field('value', $._arg),
),
seq(
field('key', choice(
$.string,
)),
token.immediate(':'),
field('value', $._arg),
),
seq(
field('key', choice(
$.hash_key_symbol,
alias($.identifier, $.hash_key_symbol),
alias($.constant, $.hash_key_symbol),
alias($.identifier_suffix, $.hash_key_symbol),
alias($.constant_suffix, $.hash_key_symbol),
)),
token.immediate(':'),
choice(
field('value', optional($._arg)),
// This alternative never matches, because '_no_line_break' tokens do not exist.
// The purpose is give a hint to the scanner that it should not produce any line-break
// terminators at this point.
$._no_line_break),
),
)),
lambda: $ => seq(
'->',
field('parameters', optional(choice(
alias($.parameters, $.lambda_parameters),
alias($.bare_parameters, $.lambda_parameters),
))),
field('body', choice($.block, $.do_block)),
),
empty_statement: _ => prec(-1, ';'),
_terminator: $ => choice(
$._line_break,
';',
),
},
});
/**
* Creates a rule to optionally match one or more of the rules separated by `separator`
*
* @param {RuleOrLiteral} rule
*
* @param {RuleOrLiteral} separator
*
* @returns {ChoiceRule}
*/
function sep(rule, separator) {
return optional(sep1(rule, separator));
}
/**
* Creates a rule to match one or more of the rules separated by `separator`
*
* @param {RuleOrLiteral} rule
*
* @param {RuleOrLiteral} separator
*
* @returns {SeqRule}
*/
function sep1(rule, separator) {
return seq(rule, repeat(seq(separator, rule)));
}
/**
* Creates a rule to match one or more of the rules separated by a comma
*
* @param {RuleOrLiteral} rule
*
* @returns {SeqRule}
*/
function commaSep1(rule) {
return sep1(rule, ',');
}
/**
* Creates a rule to optionally match one or more of the rules separated by a comma
*
* @param {RuleOrLiteral} rule
*
* @returns {ChoiceRule}
*/
function commaSep(rule) {
return optional(commaSep1(rule));
}
================================================
FILE: package.json
================================================
{
"name": "tree-sitter-ruby",
"version": "0.23.1",
"description": "Ruby grammar for tree-sitter",
"repository": "https://github.com/tree-sitter/tree-sitter-ruby",
"license": "MIT",
"author": {
"name": "Rob Rix",
"email": "rob.rix@gmail.com"
},
"contributors": [
{
"name": "Timothy Clem",
"email": "timothy.clem@gmail.com"
},
{
"name": "Max Brunsfeld",
"email": "maxbrunsfeld@gmail.com"
},
{
"name": "Arthur Baars",
"email": "aibaars@github.com"
},
{
"name": "Amaan Qureshi",
"email": "amaanq12@gmail.com"
}
],
"maintainers": [
{
"name": "Amaan Qureshi",
"email": "amaanq12@gmail.com"
}
],
"main": "bindings/node",
"types": "bindings/node",
"keywords": [
"incremental",
"parsing",
"tree-sitter",
"ruby"
],
"files": [
"grammar.js",
"tree-sitter.json",
"binding.gyp",
"prebuilds/**",
"bindings/node/*",
"queries/*",
"src/**",
"*.wasm"
],
"dependencies": {
"node-addon-api": "^8.2.2",
"node-gyp-build": "^4.8.2"
},
"devDependencies": {
"eslint": ">=9.14.0",
"eslint-config-treesitter": "^1.0.2",
"prebuildify": "^6.0.1",
"tree-sitter-cli": "^0.24.4"
},
"peerDependencies": {
"tree-sitter": "^0.21.1"
},
"peerDependenciesMeta": {
"tree-sitter": {
"optional": true
}
},
"scripts": {
"install": "node-gyp-build",
"prestart": "tree-sitter build --wasm",
"start": "tree-sitter playground",
"test": "node --test bindings/node/*_test.js"
}
}
================================================
FILE: pyproject.toml
================================================
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "tree-sitter-ruby"
description = "Ruby grammar for tree-sitter"
version = "0.23.1"
keywords = ["incremental", "parsing", "tree-sitter", "ruby"]
classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Topic :: Software Development :: Compilers",
"Topic :: Text Processing :: Linguistic",
"Typing :: Typed",
]
authors = [
{ name = "Max Brunsfeld", email = "maxbrunsfeld@gmail.com" },
{ name = "Amaan Qureshi", email = "amaanq12@gmail.com" },
]
requires-python = ">=3.9"
license.text = "MIT"
readme = "README.md"
[project.urls]
Homepage = "https://github.com/tree-sitter/tree-sitter-ruby"
[project.optional-dependencies]
core = ["tree-sitter~=0.22"]
[tool.cibuildwheel]
build = "cp39-*"
build-frontend = "build"
================================================
FILE: queries/highlights.scm
================================================
(identifier) @variable
((identifier) @function.method
(#is-not? local))
[
"alias"
"and"
"begin"
"break"
"case"
"class"
"def"
"do"
"else"
"elsif"
"end"
"ensure"
"for"
"if"
"in"
"module"
"next"
"or"
"rescue"
"retry"
"return"
"then"
"unless"
"until"
"when"
"while"
"yield"
] @keyword
((identifier) @keyword
(#match? @keyword "^(private|protected|public)$"))
(constant) @constructor
; Function calls
"defined?" @function.method.builtin
(call
method: [(identifier) (constant)] @function.method)
((identifier) @function.method.builtin
(#eq? @function.method.builtin "require"))
; Function definitions
(alias (identifier) @function.method)
(setter (identifier) @function.method)
(method name: [(identifier) (constant)] @function.method)
(singleton_method name: [(identifier) (constant)] @function.method)
; Identifiers
[
(class_variable)
(instance_variable)
] @property
((identifier) @constant.builtin
(#match? @constant.builtin "^__(FILE|LINE|ENCODING)__$"))
(file) @constant.builtin
(line) @constant.builtin
(encoding) @constant.builtin
(hash_splat_nil
"**" @operator) @constant.builtin
((constant) @constant
(#match? @constant "^[A-Z\\d_]+$"))
[
(self)
(super)
] @variable.builtin
(block_parameter (identifier) @variable.parameter)
(block_parameters (identifier) @variable.parameter)
(destructured_parameter (identifier) @variable.parameter)
(hash_splat_parameter (identifier) @variable.parameter)
(lambda_parameters (identifier) @variable.parameter)
(method_parameters (identifier) @variable.parameter)
(splat_parameter (identifier) @variable.parameter)
(keyword_parameter name: (identifier) @variable.parameter)
(optional_parameter name: (identifier) @variable.parameter)
; Literals
[
(string)
(bare_string)
(subshell)
(heredoc_body)
(heredoc_beginning)
] @string
[
(simple_symbol)
(delimited_symbol)
(hash_key_symbol)
(bare_symbol)
] @string.special.symbol
(regex) @string.special.regex
(escape_sequence) @escape
[
(integer)
(float)
] @number
[
(nil)
(true)
(false)
] @constant.builtin
(interpolation
"#{" @punctuation.special
"}" @punctuation.special) @embedded
(comment) @comment
; Operators
[
"="
"=>"
"->"
] @operator
[
","
";"
"."
] @punctuation.delimiter
[
"("
")"
"["
"]"
"{"
"}"
"%w("
"%i("
] @punctuation.bracket
================================================
FILE: queries/locals.scm
================================================
((method) @local.scope
(#set! local.scope-inherits false))
[
(lambda)
(block)
(do_block)
] @local.scope
(block_parameter (identifier) @local.definition)
(block_parameters (identifier) @local.definition)
(destructured_parameter (identifier) @local.definition)
(hash_splat_parameter (identifier) @local.definition)
(lambda_parameters (identifier) @local.definition)
(method_parameters (identifier) @local.definition)
(splat_parameter (identifier) @local.definition)
(keyword_parameter name: (identifier) @local.definition)
(optional_parameter name: (identifier) @local.definition)
(identifier) @local.reference
(assignment left: (identifier) @local.definition)
(operator_assignment left: (identifier) @local.definition)
(left_assignment_list (identifier) @local.definition)
(rest_assignment (identifier) @local.definition)
(destructured_left_assignment (identifier) @local.definition)
================================================
FILE: queries/tags.scm
================================================
; Method definitions
(
(comment)* @doc
.
[
(method
name: (_) @name) @definition.method
(singleton_method
name: (_) @name) @definition.method
]
(#strip! @doc "^#\\s*")
(#select-adjacent! @doc @definition.method)
)
(alias
name: (_) @name) @definition.method
(setter
(identifier) @ignore)
; Class definitions
(
(comment)* @doc
.
[
(class
name: [
(constant) @name
(scope_resolution
name: (_) @name)
]) @definition.class
(singleton_class
value: [
(constant) @name
(scope_resolution
name: (_) @name)
]) @definition.class
]
(#strip! @doc "^#\\s*")
(#select-adjacent! @doc @definition.class)
)
; Module definitions
(
(module
name: [
(constant) @name
(scope_resolution
name: (_) @name)
]) @definition.module
)
; Calls
(call method: (identifier) @name) @reference.call
(
[(identifier) (constant)] @name @reference.call
(#is-not? local)
(#not-match? @name "^(lambda|load|require|require_relative|__FILE__|__LINE__)$")
)
================================================
FILE: setup.py
================================================
from os.path import isdir, join
from platform import system
from setuptools import Extension, find_packages, setup
from setuptools.command.build import build
from wheel.bdist_wheel import bdist_wheel
class Build(build):
def run(self):
if isdir("queries"):
dest = join(self.build_lib, "tree_sitter_ruby", "queries")
self.copy_tree("queries", dest)
super().run()
class BdistWheel(bdist_wheel):
def get_tag(self):
python, abi, platform = super().get_tag()
if python.startswith("cp"):
python, abi = "cp39", "abi3"
return python, abi, platform
setup(
packages=find_packages("bindings/python"),
package_dir={"": "bindings/python"},
package_data={
"tree_sitter_ruby": ["*.pyi", "py.typed"],
"tree_sitter_ruby.queries": ["*.scm"],
},
ext_package="tree_sitter_ruby",
ext_modules=[
Extension(
name="_binding",
sources=[
"bindings/python/tree_sitter_ruby/binding.c",
"src/parser.c",
"src/scanner.c",
],
extra_compile_args=[
"-std=c11",
"-fvisibility=hidden",
] if system() != "Windows" else [
"/std:c11",
"/utf-8",
],
define_macros=[
("Py_LIMITED_API", "0x03090000"),
("PY_SSIZE_T_CLEAN", None),
("TREE_SITTER_HIDE_SYMBOLS", None),
],
include_dirs=["src"],
py_limited_api=True,
)
],
cmdclass={
"build": Build,
"bdist_wheel": BdistWheel
},
zip_safe=False
)
================================================
FILE: src/grammar.json
================================================
{
"$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json",
"name": "ruby",
"word": "identifier",
"rules": {
"program": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "PATTERN",
"value": "__END__"
},
{
"type": "SYMBOL",
"name": "uninterpreted"
}
]
}
]
},
{
"type": "BLANK"
}
]
}
]
},
"uninterpreted": {
"type": "PATTERN",
"value": "(.|\\s)*"
},
"block_body": {
"type": "SYMBOL",
"name": "_statements"
},
"_statements": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_statement"
},
{
"type": "SYMBOL",
"name": "_terminator"
}
]
},
{
"type": "SYMBOL",
"name": "empty_statement"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statement"
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "SYMBOL",
"name": "_statement"
}
]
},
"begin_block": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "BEGIN"
},
{
"type": "STRING",
"value": "{"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "}"
}
]
},
"end_block": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "END"
},
{
"type": "STRING",
"value": "{"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "}"
}
]
},
"_statement": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "undef"
},
{
"type": "SYMBOL",
"name": "alias"
},
{
"type": "SYMBOL",
"name": "if_modifier"
},
{
"type": "SYMBOL",
"name": "unless_modifier"
},
{
"type": "SYMBOL",
"name": "while_modifier"
},
{
"type": "SYMBOL",
"name": "until_modifier"
},
{
"type": "SYMBOL",
"name": "rescue_modifier"
},
{
"type": "SYMBOL",
"name": "begin_block"
},
{
"type": "SYMBOL",
"name": "end_block"
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
},
"method": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "def"
},
{
"type": "SYMBOL",
"name": "_method_rest"
}
]
},
"singleton_method": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "def"
},
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "object",
"content": {
"type": "SYMBOL",
"name": "_variable"
}
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "FIELD",
"name": "object",
"content": {
"type": "SYMBOL",
"name": "_arg"
}
},
{
"type": "STRING",
"value": ")"
}
]
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "."
},
{
"type": "STRING",
"value": "::"
}
]
}
]
},
{
"type": "SYMBOL",
"name": "_method_rest"
}
]
},
"_method_rest": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "_method_name"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_body_expr"
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "parameters",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "parameters"
},
"named": true,
"value": "method_parameters"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "body_statement"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
},
{
"type": "SYMBOL",
"name": "_body_expr"
}
]
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "parameters",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "bare_parameters"
},
"named": true,
"value": "method_parameters"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "body_statement"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
}
]
}
]
},
"rescue_modifier_arg": {
"type": "PREC",
"value": 16,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_arg"
}
},
{
"type": "STRING",
"value": "rescue"
},
{
"type": "FIELD",
"name": "handler",
"content": {
"type": "SYMBOL",
"name": "_arg"
}
}
]
}
},
"rescue_modifier_expression": {
"type": "PREC",
"value": 16,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "STRING",
"value": "rescue"
},
{
"type": "FIELD",
"name": "handler",
"content": {
"type": "SYMBOL",
"name": "_arg"
}
}
]
}
},
"_body_expr": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "="
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_arg"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "rescue_modifier_arg"
},
"named": true,
"value": "rescue_modifier"
}
]
}
}
]
},
"parameters": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_formal_parameter"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_formal_parameter"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ")"
}
]
},
"bare_parameters": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_simple_formal_parameter"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_formal_parameter"
}
]
}
}
]
},
"block_parameters": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_formal_parameter"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_formal_parameter"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ";"
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "locals",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "FIELD",
"name": "locals",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
}
]
}
}
]
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "|"
}
]
},
"_formal_parameter": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_simple_formal_parameter"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "parameters"
},
"named": true,
"value": "destructured_parameter"
}
]
},
"_simple_formal_parameter": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "SYMBOL",
"name": "splat_parameter"
},
{
"type": "SYMBOL",
"name": "hash_splat_parameter"
},
{
"type": "SYMBOL",
"name": "hash_splat_nil"
},
{
"type": "SYMBOL",
"name": "forward_parameter"
},
{
"type": "SYMBOL",
"name": "block_parameter"
},
{
"type": "SYMBOL",
"name": "keyword_parameter"
},
{
"type": "SYMBOL",
"name": "optional_parameter"
}
]
},
"forward_parameter": {
"type": "STRING",
"value": "..."
},
"splat_parameter": {
"type": "PREC_RIGHT",
"value": -2,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "*"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "BLANK"
}
]
}
}
]
}
},
"hash_splat_parameter": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "**"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "BLANK"
}
]
}
}
]
},
"hash_splat_nil": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "**"
},
{
"type": "STRING",
"value": "nil"
}
]
},
"block_parameter": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "&"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "BLANK"
}
]
}
}
]
},
"keyword_parameter": {
"type": "PREC_RIGHT",
"value": 51,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": ":"
}
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_arg"
},
{
"type": "BLANK"
}
]
}
}
]
}
},
"optional_parameter": {
"type": "PREC",
"value": 51,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
},
{
"type": "STRING",
"value": "="
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_arg"
}
}
]
}
},
"class": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "class"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "constant"
},
{
"type": "SYMBOL",
"name": "scope_resolution"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "superclass",
"content": {
"type": "SYMBOL",
"name": "superclass"
}
},
{
"type": "SYMBOL",
"name": "_terminator"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "body_statement"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
},
"superclass": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "<"
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
},
"singleton_class": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "class"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_singleton_class_left_angle_left_langle"
},
"named": false,
"value": "<<"
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_arg"
}
},
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "body_statement"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
},
"module": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "module"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "constant"
},
{
"type": "SYMBOL",
"name": "scope_resolution"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "body_statement"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
},
"return_command": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "return"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_argument_list"
},
"named": true,
"value": "argument_list"
}
]
}
},
"yield_command": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "yield"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_argument_list"
},
"named": true,
"value": "argument_list"
}
]
}
},
"break_command": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "break"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_argument_list"
},
"named": true,
"value": "argument_list"
}
]
}
},
"next_command": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "next"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_argument_list"
},
"named": true,
"value": "argument_list"
}
]
}
},
"return": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "return"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "argument_list"
},
{
"type": "BLANK"
}
]
}
]
}
},
"yield": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "yield"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "argument_list"
},
{
"type": "BLANK"
}
]
}
]
}
},
"break": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "break"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "argument_list"
},
{
"type": "BLANK"
}
]
}
]
}
},
"next": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "next"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "argument_list"
},
{
"type": "BLANK"
}
]
}
]
}
},
"redo": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "redo"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "argument_list"
},
{
"type": "BLANK"
}
]
}
]
}
},
"retry": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "retry"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "argument_list"
},
{
"type": "BLANK"
}
]
}
]
}
},
"if_modifier": {
"type": "PREC",
"value": 16,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "STRING",
"value": "if"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
"unless_modifier": {
"type": "PREC",
"value": 16,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "STRING",
"value": "unless"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
"while_modifier": {
"type": "PREC",
"value": 16,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "STRING",
"value": "while"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
"until_modifier": {
"type": "PREC",
"value": 16,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "STRING",
"value": "until"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
"rescue_modifier": {
"type": "PREC",
"value": 16,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "STRING",
"value": "rescue"
},
{
"type": "FIELD",
"name": "handler",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
"while": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "while"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "do"
}
}
]
},
"until": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "until"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "do"
}
}
]
},
"for": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "for"
},
{
"type": "FIELD",
"name": "pattern",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_lhs"
},
{
"type": "SYMBOL",
"name": "left_assignment_list"
}
]
}
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "in"
}
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "do"
}
}
]
},
"in": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "in"
},
{
"type": "SYMBOL",
"name": "_arg"
}
]
},
"do": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "do"
},
{
"type": "SYMBOL",
"name": "_terminator"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
},
"case": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "case"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_line_break"
},
{
"type": "BLANK"
}
]
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "when"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "else"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
},
"case_match": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "case"
},
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_line_break"
},
{
"type": "BLANK"
}
]
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "REPEAT1",
"content": {
"type": "FIELD",
"name": "clauses",
"content": {
"type": "SYMBOL",
"name": "in_clause"
}
}
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "else",
"content": {
"type": "SYMBOL",
"name": "else"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
},
"when": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "when"
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "pattern",
"content": {
"type": "SYMBOL",
"name": "pattern"
}
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "FIELD",
"name": "pattern",
"content": {
"type": "SYMBOL",
"name": "pattern"
}
}
]
}
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "then"
}
}
]
}
]
},
"in_clause": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "in"
},
{
"type": "FIELD",
"name": "pattern",
"content": {
"type": "SYMBOL",
"name": "_pattern_top_expr_body"
}
},
{
"type": "FIELD",
"name": "guard",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_guard"
},
{
"type": "BLANK"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "then"
}
}
]
}
]
},
"pattern": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_arg"
},
{
"type": "SYMBOL",
"name": "splat_argument"
}
]
},
"_guard": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "if_guard"
},
{
"type": "SYMBOL",
"name": "unless_guard"
}
]
},
"if_guard": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "if"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
},
"unless_guard": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "unless"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
},
"_pattern_top_expr_body": {
"type": "PREC",
"value": -1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_expr"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_array_pattern_n"
},
"named": true,
"value": "array_pattern"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_find_pattern_body"
},
"named": true,
"value": "find_pattern"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_hash_pattern_body"
},
"named": true,
"value": "hash_pattern"
}
]
}
},
"_array_pattern_n": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_expr"
},
{
"type": "ALIAS",
"content": {
"type": "STRING",
"value": ","
},
"named": true,
"value": "splat_parameter"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_expr"
},
{
"type": "STRING",
"value": ","
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_expr"
},
{
"type": "SYMBOL",
"name": "_array_pattern_n"
}
]
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "splat_parameter"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_pattern_expr"
}
]
}
}
]
}
]
}
},
"_pattern_expr": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "as_pattern"
},
{
"type": "SYMBOL",
"name": "_pattern_expr_alt"
}
]
},
"as_pattern": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_pattern_expr"
}
},
{
"type": "STRING",
"value": "=>"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
}
]
},
"_pattern_expr_alt": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "alternative_pattern"
},
{
"type": "SYMBOL",
"name": "_pattern_expr_basic"
}
]
},
"alternative_pattern": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "alternatives",
"content": {
"type": "SYMBOL",
"name": "_pattern_expr_basic"
}
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "FIELD",
"name": "alternatives",
"content": {
"type": "SYMBOL",
"name": "_pattern_expr_basic"
}
}
]
}
}
]
},
"_array_pattern_body": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_expr"
},
{
"type": "SYMBOL",
"name": "_array_pattern_n"
}
]
},
"array_pattern": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_array_pattern_body"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "]"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "class",
"content": {
"type": "SYMBOL",
"name": "_pattern_constant"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "["
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_array_pattern_body"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "]"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "class",
"content": {
"type": "SYMBOL",
"name": "_pattern_constant"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "("
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_array_pattern_body"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ")"
}
]
}
]
}
},
"_find_pattern_body": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "splat_parameter"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_pattern_expr"
}
]
}
},
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "splat_parameter"
}
]
},
"find_pattern": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "SYMBOL",
"name": "_find_pattern_body"
},
{
"type": "STRING",
"value": "]"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "class",
"content": {
"type": "SYMBOL",
"name": "_pattern_constant"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "["
}
},
{
"type": "SYMBOL",
"name": "_find_pattern_body"
},
{
"type": "STRING",
"value": "]"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "class",
"content": {
"type": "SYMBOL",
"name": "_pattern_constant"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "("
}
},
{
"type": "SYMBOL",
"name": "_find_pattern_body"
},
{
"type": "STRING",
"value": ")"
}
]
}
]
},
"_hash_pattern_body": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "keyword_pattern"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "keyword_pattern"
}
]
}
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "keyword_pattern"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "keyword_pattern"
}
]
}
}
]
},
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_hash_pattern_any_rest"
}
]
},
{
"type": "SYMBOL",
"name": "_hash_pattern_any_rest"
}
]
}
},
"keyword_pattern": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "key",
"content": {
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "identifier"
},
"named": true,
"value": "hash_key_symbol"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "constant"
},
"named": true,
"value": "hash_key_symbol"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "identifier_suffix"
},
"named": true,
"value": "hash_key_symbol"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "constant_suffix"
},
"named": true,
"value": "hash_key_symbol"
},
{
"type": "SYMBOL",
"name": "string"
}
]
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": ":"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_pattern_expr"
}
},
{
"type": "BLANK"
}
]
}
]
}
},
"_hash_pattern_any_rest": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "hash_splat_parameter"
},
{
"type": "SYMBOL",
"name": "hash_splat_nil"
}
]
},
"hash_pattern": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "{"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_hash_pattern_body"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "}"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "class",
"content": {
"type": "SYMBOL",
"name": "_pattern_constant"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "["
}
},
{
"type": "SYMBOL",
"name": "_hash_pattern_body"
},
{
"type": "STRING",
"value": "]"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "class",
"content": {
"type": "SYMBOL",
"name": "_pattern_constant"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "("
}
},
{
"type": "SYMBOL",
"name": "_hash_pattern_body"
},
{
"type": "STRING",
"value": ")"
}
]
}
]
}
},
"_pattern_expr_basic": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_value"
},
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "SYMBOL",
"name": "array_pattern"
},
{
"type": "SYMBOL",
"name": "find_pattern"
},
{
"type": "SYMBOL",
"name": "hash_pattern"
},
{
"type": "SYMBOL",
"name": "parenthesized_pattern"
}
]
}
},
"parenthesized_pattern": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "_pattern_expr"
},
{
"type": "STRING",
"value": ")"
}
]
},
"_pattern_value": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_primitive"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_pattern_range"
},
"named": true,
"value": "range"
},
{
"type": "SYMBOL",
"name": "variable_reference_pattern"
},
{
"type": "SYMBOL",
"name": "expression_reference_pattern"
},
{
"type": "SYMBOL",
"name": "_pattern_constant"
}
]
}
},
"_pattern_range": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "begin",
"content": {
"type": "SYMBOL",
"name": "_pattern_primitive"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ".."
},
{
"type": "STRING",
"value": "..."
}
]
}
},
{
"type": "FIELD",
"name": "end",
"content": {
"type": "SYMBOL",
"name": "_pattern_primitive"
}
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ".."
},
{
"type": "STRING",
"value": "..."
}
]
}
},
{
"type": "FIELD",
"name": "end",
"content": {
"type": "SYMBOL",
"name": "_pattern_primitive"
}
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "begin",
"content": {
"type": "SYMBOL",
"name": "_pattern_primitive"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ".."
},
{
"type": "STRING",
"value": "..."
}
]
}
}
]
}
]
},
"_pattern_primitive": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_literal"
},
{
"type": "SYMBOL",
"name": "_pattern_lambda"
}
]
},
"_pattern_lambda": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "SYMBOL",
"name": "lambda"
}
},
"_pattern_literal": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "string"
},
{
"type": "SYMBOL",
"name": "subshell"
},
{
"type": "SYMBOL",
"name": "heredoc_beginning"
},
{
"type": "SYMBOL",
"name": "regex"
},
{
"type": "SYMBOL",
"name": "string_array"
},
{
"type": "SYMBOL",
"name": "symbol_array"
},
{
"type": "SYMBOL",
"name": "_keyword_variable"
}
]
}
},
"_keyword_variable": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "nil"
},
{
"type": "SYMBOL",
"name": "self"
},
{
"type": "SYMBOL",
"name": "true"
},
{
"type": "SYMBOL",
"name": "false"
},
{
"type": "SYMBOL",
"name": "line"
},
{
"type": "SYMBOL",
"name": "file"
},
{
"type": "SYMBOL",
"name": "encoding"
}
]
}
},
"line": {
"type": "STRING",
"value": "__LINE__"
},
"file": {
"type": "STRING",
"value": "__FILE__"
},
"encoding": {
"type": "STRING",
"value": "__ENCODING__"
},
"variable_reference_pattern": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "^"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "SYMBOL",
"name": "_nonlocal_variable"
}
]
}
}
]
},
"expression_reference_pattern": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "^"
},
{
"type": "STRING",
"value": "("
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"_pattern_constant": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "constant"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_pattern_constant_resolution"
},
"named": true,
"value": "scope_resolution"
}
]
}
},
"_pattern_constant_resolution": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "scope",
"content": {
"type": "SYMBOL",
"name": "_pattern_constant"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "::"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "constant"
}
}
]
},
"if": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "if"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "FIELD",
"name": "consequence",
"content": {
"type": "SYMBOL",
"name": "then"
}
}
]
},
{
"type": "FIELD",
"name": "alternative",
"content": {
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "else"
},
{
"type": "SYMBOL",
"name": "elsif"
}
]
},
{
"type": "BLANK"
}
]
}
},
{
"type": "STRING",
"value": "end"
}
]
},
"unless": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "unless"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "FIELD",
"name": "consequence",
"content": {
"type": "SYMBOL",
"name": "then"
}
}
]
},
{
"type": "FIELD",
"name": "alternative",
"content": {
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "else"
},
{
"type": "SYMBOL",
"name": "elsif"
}
]
},
{
"type": "BLANK"
}
]
}
},
{
"type": "STRING",
"value": "end"
}
]
},
"elsif": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "elsif"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "FIELD",
"name": "consequence",
"content": {
"type": "SYMBOL",
"name": "then"
}
}
]
},
{
"type": "FIELD",
"name": "alternative",
"content": {
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "else"
},
{
"type": "SYMBOL",
"name": "elsif"
}
]
},
{
"type": "BLANK"
}
]
}
}
]
},
"else": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
}
]
},
"then": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "SYMBOL",
"name": "_statements"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "then"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
}
]
}
]
},
"begin": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "begin"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_body_statement"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
},
"ensure": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "ensure"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
}
]
},
"rescue": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "rescue"
},
{
"type": "FIELD",
"name": "exceptions",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "exceptions"
},
{
"type": "BLANK"
}
]
}
},
{
"type": "FIELD",
"name": "variable",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "exception_variable"
},
{
"type": "BLANK"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "then"
}
}
]
}
]
},
"exceptions": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_arg"
},
{
"type": "SYMBOL",
"name": "splat_argument"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_arg"
},
{
"type": "SYMBOL",
"name": "splat_argument"
}
]
}
]
}
}
]
},
"exception_variable": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "=>"
},
{
"type": "SYMBOL",
"name": "_lhs"
}
]
},
"body_statement": {
"type": "SYMBOL",
"name": "_body_statement"
},
"_body_statement": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "rescue"
},
{
"type": "SYMBOL",
"name": "else"
},
{
"type": "SYMBOL",
"name": "ensure"
}
]
}
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
},
{
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "rescue"
},
{
"type": "SYMBOL",
"name": "else"
},
{
"type": "SYMBOL",
"name": "ensure"
}
]
}
}
]
}
]
},
"_expression": {
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_binary"
},
"named": true,
"value": "binary"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_unary"
},
"named": true,
"value": "unary"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_assignment"
},
"named": true,
"value": "assignment"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_operator_assignment"
},
"named": true,
"value": "operator_assignment"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_call"
},
"named": true,
"value": "call"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_call_with_block"
},
"named": true,
"value": "call"
},
{
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_chained_command_call"
},
"named": true,
"value": "call"
}
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "return_command"
},
"named": true,
"value": "return"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "yield_command"
},
"named": true,
"value": "yield"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "break_command"
},
"named": true,
"value": "break"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "next_command"
},
"named": true,
"value": "next"
},
{
"type": "SYMBOL",
"name": "match_pattern"
},
{
"type": "SYMBOL",
"name": "test_pattern"
},
{
"type": "SYMBOL",
"name": "_arg"
}
]
},
"match_pattern": {
"type": "PREC",
"value": 100,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_arg"
}
},
{
"type": "STRING",
"value": "=>"
},
{
"type": "FIELD",
"name": "pattern",
"content": {
"type": "SYMBOL",
"name": "_pattern_top_expr_body"
}
}
]
}
},
"test_pattern": {
"type": "PREC",
"value": 100,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_arg"
}
},
{
"type": "STRING",
"value": "in"
},
{
"type": "FIELD",
"name": "pattern",
"content": {
"type": "SYMBOL",
"name": "_pattern_top_expr_body"
}
}
]
}
},
"_arg": {
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_unary_minus_pow"
},
"named": true,
"value": "unary"
},
{
"type": "SYMBOL",
"name": "_primary"
},
{
"type": "SYMBOL",
"name": "assignment"
},
{
"type": "SYMBOL",
"name": "operator_assignment"
},
{
"type": "SYMBOL",
"name": "conditional"
},
{
"type": "SYMBOL",
"name": "range"
},
{
"type": "SYMBOL",
"name": "binary"
},
{
"type": "SYMBOL",
"name": "unary"
}
]
},
"_unary_minus_pow": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_unary_minus_num"
},
"named": false,
"value": "-"
}
},
{
"type": "FIELD",
"name": "operand",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_pow"
},
"named": true,
"value": "binary"
}
}
]
},
"_pow": {
"type": "PREC_RIGHT",
"value": 80,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_simple_numeric"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_binary_star_star"
},
"named": false,
"value": "**"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_arg"
}
}
]
}
},
"_primary": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "parenthesized_statements"
},
{
"type": "SYMBOL",
"name": "_lhs"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_function_identifier_call"
},
"named": true,
"value": "call"
},
{
"type": "SYMBOL",
"name": "call"
},
{
"type": "SYMBOL",
"name": "array"
},
{
"type": "SYMBOL",
"name": "string_array"
},
{
"type": "SYMBOL",
"name": "symbol_array"
},
{
"type": "SYMBOL",
"name": "hash"
},
{
"type": "SYMBOL",
"name": "subshell"
},
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "string"
},
{
"type": "SYMBOL",
"name": "character"
},
{
"type": "SYMBOL",
"name": "chained_string"
},
{
"type": "SYMBOL",
"name": "regex"
},
{
"type": "SYMBOL",
"name": "lambda"
},
{
"type": "SYMBOL",
"name": "method"
},
{
"type": "SYMBOL",
"name": "singleton_method"
},
{
"type": "SYMBOL",
"name": "class"
},
{
"type": "SYMBOL",
"name": "singleton_class"
},
{
"type": "SYMBOL",
"name": "module"
},
{
"type": "SYMBOL",
"name": "begin"
},
{
"type": "SYMBOL",
"name": "while"
},
{
"type": "SYMBOL",
"name": "until"
},
{
"type": "SYMBOL",
"name": "if"
},
{
"type": "SYMBOL",
"name": "unless"
},
{
"type": "SYMBOL",
"name": "for"
},
{
"type": "SYMBOL",
"name": "case"
},
{
"type": "SYMBOL",
"name": "case_match"
},
{
"type": "SYMBOL",
"name": "return"
},
{
"type": "SYMBOL",
"name": "yield"
},
{
"type": "SYMBOL",
"name": "break"
},
{
"type": "SYMBOL",
"name": "next"
},
{
"type": "SYMBOL",
"name": "redo"
},
{
"type": "SYMBOL",
"name": "retry"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "parenthesized_unary"
},
"named": true,
"value": "unary"
},
{
"type": "SYMBOL",
"name": "heredoc_beginning"
}
]
},
"parenthesized_statements": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ")"
}
]
},
"element_reference": {
"type": "PREC_LEFT",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "object",
"content": {
"type": "SYMBOL",
"name": "_primary"
}
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_element_reference_bracket"
},
"named": false,
"value": "["
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_argument_list_with_trailing_comma"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "]"
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "block",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "block"
},
{
"type": "SYMBOL",
"name": "do_block"
}
]
}
},
{
"type": "BLANK"
}
]
}
]
}
},
"scope_resolution": {
"type": "PREC_LEFT",
"value": 57,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "::"
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "scope",
"content": {
"type": "SYMBOL",
"name": "_primary"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "::"
}
}
]
}
]
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "constant"
}
}
]
}
},
"_call_operator": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "."
},
{
"type": "STRING",
"value": "&."
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "::"
}
}
]
},
"_call": {
"type": "PREC_LEFT",
"value": 56,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "receiver",
"content": {
"type": "SYMBOL",
"name": "_primary"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "SYMBOL",
"name": "_call_operator"
}
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "SYMBOL",
"name": "operator"
},
{
"type": "SYMBOL",
"name": "constant"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
}
]
}
}
]
}
},
"command_call": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_call"
},
{
"type": "SYMBOL",
"name": "_chained_command_call"
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_variable"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
}
]
}
}
]
},
{
"type": "FIELD",
"name": "arguments",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_argument_list"
},
"named": true,
"value": "argument_list"
}
}
]
},
"command_call_with_block": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_call"
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_variable"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
}
]
}
}
]
},
{
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "arguments",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_argument_list"
},
"named": true,
"value": "argument_list"
}
},
{
"type": "FIELD",
"name": "block",
"content": {
"type": "SYMBOL",
"name": "block"
}
}
]
}
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_call"
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_variable"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
}
]
}
}
]
},
{
"type": "PREC",
"value": -1,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "arguments",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_argument_list"
},
"named": true,
"value": "argument_list"
}
},
{
"type": "FIELD",
"name": "block",
"content": {
"type": "SYMBOL",
"name": "do_block"
}
}
]
}
}
]
}
]
},
"_chained_command_call": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "receiver",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "command_call_with_block"
},
"named": true,
"value": "call"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "SYMBOL",
"name": "_call_operator"
}
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
},
{
"type": "SYMBOL",
"name": "operator"
},
{
"type": "SYMBOL",
"name": "constant"
}
]
}
}
]
},
"call": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_call"
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_variable"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
}
]
}
}
]
},
{
"type": "PREC_LEFT",
"value": 56,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "receiver",
"content": {
"type": "SYMBOL",
"name": "_primary"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "SYMBOL",
"name": "_call_operator"
}
}
]
}
}
]
},
{
"type": "FIELD",
"name": "arguments",
"content": {
"type": "SYMBOL",
"name": "argument_list"
}
}
]
},
{
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_call"
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_variable"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
}
]
}
}
]
},
{
"type": "PREC_LEFT",
"value": 56,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "receiver",
"content": {
"type": "SYMBOL",
"name": "_primary"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "SYMBOL",
"name": "_call_operator"
}
}
]
}
}
]
},
{
"type": "FIELD",
"name": "arguments",
"content": {
"type": "SYMBOL",
"name": "argument_list"
}
}
]
},
{
"type": "FIELD",
"name": "block",
"content": {
"type": "SYMBOL",
"name": "block"
}
}
]
}
},
{
"type": "PREC",
"value": -1,
"content": {
"type": "SEQ",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_call"
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_variable"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
}
]
}
}
]
},
{
"type": "PREC_LEFT",
"value": 56,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "receiver",
"content": {
"type": "SYMBOL",
"name": "_primary"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "SYMBOL",
"name": "_call_operator"
}
}
]
}
}
]
},
{
"type": "FIELD",
"name": "arguments",
"content": {
"type": "SYMBOL",
"name": "argument_list"
}
}
]
},
{
"type": "FIELD",
"name": "block",
"content": {
"type": "SYMBOL",
"name": "do_block"
}
}
]
}
},
{
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_call"
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_variable"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
}
]
}
}
]
},
{
"type": "FIELD",
"name": "block",
"content": {
"type": "SYMBOL",
"name": "block"
}
}
]
}
},
{
"type": "PREC",
"value": -1,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_call"
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_variable"
},
{
"type": "SYMBOL",
"name": "_function_identifier"
}
]
}
}
]
},
{
"type": "FIELD",
"name": "block",
"content": {
"type": "SYMBOL",
"name": "do_block"
}
}
]
}
}
]
},
"command_argument_list": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_argument"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_argument"
}
]
}
}
]
}
},
"argument_list": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "("
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_argument_list_with_trailing_comma"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ")"
}
]
}
},
"_argument_list_with_trailing_comma": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_argument"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_argument"
}
]
}
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
},
"_argument": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "SYMBOL",
"name": "splat_argument"
},
{
"type": "SYMBOL",
"name": "hash_splat_argument"
},
{
"type": "SYMBOL",
"name": "forward_argument"
},
{
"type": "SYMBOL",
"name": "block_argument"
},
{
"type": "SYMBOL",
"name": "pair"
}
]
}
},
"forward_argument": {
"type": "STRING",
"value": "..."
},
"splat_argument": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_splat_star"
},
"named": false,
"value": "*"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_arg"
},
{
"type": "BLANK"
}
]
}
]
}
},
"hash_splat_argument": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_hash_splat_star_star"
},
"named": false,
"value": "**"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_arg"
},
{
"type": "BLANK"
}
]
}
]
}
},
"block_argument": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_block_ampersand"
},
"named": false,
"value": "&"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_arg"
},
{
"type": "BLANK"
}
]
}
]
}
},
"do_block": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "do"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "parameters",
"content": {
"type": "SYMBOL",
"name": "block_parameters"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "body_statement"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "end"
}
]
},
"block": {
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "{"
gitextract_arlgabw0/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── config.yml │ │ └── feature_request.yml │ └── workflows/ │ ├── ci.yml │ ├── fuzz.yml │ ├── lint.yml │ └── publish.yml ├── .gitignore ├── CMakeLists.txt ├── Cargo.toml ├── LICENSE ├── Makefile ├── Package.resolved ├── Package.swift ├── README.md ├── binding.gyp ├── bindings/ │ ├── c/ │ │ ├── tree-sitter-ruby.h │ │ └── tree-sitter-ruby.pc.in │ ├── go/ │ │ ├── binding.go │ │ └── binding_test.go │ ├── node/ │ │ ├── binding.cc │ │ ├── binding_test.js │ │ ├── index.d.ts │ │ └── index.js │ ├── python/ │ │ ├── tests/ │ │ │ └── test_binding.py │ │ └── tree_sitter_ruby/ │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── py.typed │ ├── rust/ │ │ ├── build.rs │ │ └── lib.rs │ └── swift/ │ ├── TreeSitterRuby/ │ │ └── ruby.h │ └── TreeSitterRubyTests/ │ └── TreeSitterRubyTests.swift ├── eslint.config.mjs ├── go.mod ├── go.sum ├── grammar.js ├── package.json ├── pyproject.toml ├── queries/ │ ├── highlights.scm │ ├── locals.scm │ └── tags.scm ├── setup.py ├── src/ │ ├── grammar.json │ ├── node-types.json │ ├── parser.c │ ├── scanner.c │ └── tree_sitter/ │ ├── alloc.h │ ├── array.h │ └── parser.h ├── test/ │ ├── corpus/ │ │ ├── comments.txt │ │ ├── control-flow.txt │ │ ├── declarations.txt │ │ ├── expressions.txt │ │ ├── line-endings.txt │ │ ├── literals.txt │ │ ├── patterns.txt │ │ ├── single-cr-as-whitespace.txt │ │ └── statements.txt │ └── highlight/ │ ├── classes.rb │ ├── constants.rb │ ├── literals.rb │ ├── patterns.rb │ └── variables.rb └── tree-sitter.json
SYMBOL INDEX (93 symbols across 20 files)
FILE: bindings/c/tree-sitter-ruby.h
type TSLanguage (line 4) | typedef struct TSLanguage TSLanguage;
FILE: bindings/go/binding.go
function Language (line 11) | func Language() unsafe.Pointer {
FILE: bindings/go/binding_test.go
function TestCanLoadGrammar (line 10) | func TestCanLoadGrammar(t *testing.T) {
FILE: bindings/node/binding.cc
type TSLanguage (line 3) | struct TSLanguage
function Init (line 12) | Napi::Object Init(Napi::Env env, Napi::Object exports) {
FILE: bindings/node/index.d.ts
type BaseNode (line 1) | type BaseNode = {
type ChildNode (line 6) | type ChildNode = {
type NodeInfo (line 12) | type NodeInfo =
type Language (line 21) | type Language = {
FILE: bindings/python/tests/test_binding.py
class TestLanguage (line 6) | class TestLanguage(TestCase):
method test_can_load_grammar (line 7) | def test_can_load_grammar(self):
FILE: bindings/python/tree_sitter_ruby/__init__.py
function _get_query (line 8) | def _get_query(name, file):
function __getattr__ (line 14) | def __getattr__(name):
function __dir__ (line 33) | def __dir__():
FILE: bindings/python/tree_sitter_ruby/__init__.pyi
function language (line 7) | def language() -> object: ...
FILE: bindings/python/tree_sitter_ruby/binding.c
type TSLanguage (line 3) | typedef struct TSLanguage TSLanguage;
function PyObject (line 7) | static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *...
type PyModuleDef (line 17) | struct PyModuleDef
function PyMODINIT_FUNC (line 25) | PyMODINIT_FUNC PyInit__binding(void) {
FILE: bindings/rust/build.rs
function main (line 1) | fn main() {
FILE: bindings/rust/lib.rs
function tree_sitter_ruby (line 29) | fn tree_sitter_ruby() -> *const ();
constant LANGUAGE (line 35) | pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitt...
constant NODE_TYPES (line 40) | pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
constant HIGHLIGHTS_QUERY (line 43) | pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlight...
constant LOCALS_QUERY (line 46) | pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm");
constant TAGS_QUERY (line 49) | pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");
function test_can_load_grammar (line 54) | fn test_can_load_grammar() {
FILE: bindings/swift/TreeSitterRuby/ruby.h
type TSLanguage (line 4) | typedef struct TSLanguage TSLanguage;
FILE: grammar.js
constant PREC (line 4) | const PREC = {
constant IDENTIFIER_CHARS (line 33) | const IDENTIFIER_CHARS = /[^\x00-\x1F\s:;`"'@$#.,|^&<=>+\-*/\\%?!~()\[\]...
constant LOWER_ALPHA_CHAR (line 34) | const LOWER_ALPHA_CHAR = /[^\x00-\x1F\sA-Z0-9:;`"'@$#.,|^&<=>+\-*/\\%?!~...
constant ALPHA_CHAR (line 35) | const ALPHA_CHAR = /[^\x00-\x1F\s0-9:;`"'@$#.,|^&<=>+\-*/\\%?!~()\[\]{}]/;
function sep (line 1244) | function sep(rule, separator) {
function sep1 (line 1257) | function sep1(rule, separator) {
function commaSep1 (line 1268) | function commaSep1(rule) {
function commaSep (line 1279) | function commaSep(rule) {
FILE: setup.py
class Build (line 9) | class Build(build):
method run (line 10) | def run(self):
class BdistWheel (line 17) | class BdistWheel(bdist_wheel):
method get_tag (line 18) | def get_tag(self):
FILE: src/scanner.c
type TokenType (line 8) | typedef enum {
type String (line 47) | typedef Array(char) String;
type Literal (line 49) | typedef struct {
type Heredoc (line 57) | typedef struct {
type Scanner (line 64) | typedef struct {
function skip (line 75) | static inline void skip(Scanner *scanner, TSLexer *lexer) {
function advance (line 80) | static inline void advance(TSLexer *lexer) { lexer->advance(lexer, false...
function reset (line 82) | static inline void reset(Scanner *scanner) {
function serialize (line 90) | static inline unsigned serialize(Scanner *scanner, char *buffer) {
function deserialize (line 125) | static inline void deserialize(Scanner *scanner, const char *buffer, uns...
function scan_whitespace (line 166) | static inline bool scan_whitespace(Scanner *scanner, TSLexer *lexer, con...
function scan_operator (line 237) | static inline bool scan_operator(TSLexer *lexer) {
function is_iden_char (line 339) | static inline bool is_iden_char(char c) {
function scan_symbol_identifier (line 343) | static inline bool scan_symbol_identifier(TSLexer *lexer) {
function scan_open_delimiter (line 378) | static inline bool scan_open_delimiter(Scanner *scanner, TSLexer *lexer,...
function scan_heredoc_word (line 600) | static inline void scan_heredoc_word(TSLexer *lexer, Heredoc *heredoc) {
function scan_short_interpolation (line 633) | static inline bool scan_short_interpolation(TSLexer *lexer, const bool h...
function scan_heredoc_content (line 670) | static inline bool scan_heredoc_content(Scanner *scanner, TSLexer *lexer) {
function scan_literal_content (line 765) | static inline bool scan_literal_content(Scanner *scanner, TSLexer *lexer) {
function scan (line 840) | static inline bool scan(Scanner *scanner, TSLexer *lexer, const bool *va...
function tree_sitter_ruby_external_scanner_scan (line 1087) | bool tree_sitter_ruby_external_scanner_scan(void *payload, TSLexer *lexe...
function tree_sitter_ruby_external_scanner_serialize (line 1092) | unsigned tree_sitter_ruby_external_scanner_serialize(void *payload, char...
function tree_sitter_ruby_external_scanner_deserialize (line 1097) | void tree_sitter_ruby_external_scanner_deserialize(void *payload, const ...
function tree_sitter_ruby_external_scanner_destroy (line 1102) | void tree_sitter_ruby_external_scanner_destroy(void *payload) {
FILE: src/tree_sitter/array.h
type Array (line 159) | typedef Array(void) Array;
function _array__delete (line 162) | static inline void _array__delete(Array *self) {
function _array__erase (line 172) | static inline void _array__erase(Array *self, size_t element_size,
function _array__reserve (line 182) | static inline void _array__reserve(Array *self, size_t element_size, uin...
function _array__assign (line 194) | static inline void _array__assign(Array *self, const Array *other, size_...
function _array__swap (line 201) | static inline void _array__swap(Array *self, Array *other) {
function _array__grow (line 208) | static inline void _array__grow(Array *self, uint32_t count, size_t elem...
function _array__splice (line 219) | static inline void _array__splice(Array *self, size_t element_size,
FILE: src/tree_sitter/parser.h
type TSStateId (line 17) | typedef uint16_t TSStateId;
type TSSymbol (line 18) | typedef uint16_t TSSymbol;
type TSFieldId (line 19) | typedef uint16_t TSFieldId;
type TSLanguage (line 20) | typedef struct TSLanguage TSLanguage;
type TSFieldMapEntry (line 23) | typedef struct {
type TSFieldMapSlice (line 29) | typedef struct {
type TSSymbolMetadata (line 34) | typedef struct {
type TSLexer (line 40) | typedef struct TSLexer TSLexer;
type TSLexer (line 42) | struct TSLexer {
type TSParseActionType (line 53) | typedef enum {
type TSParseAction (line 60) | typedef union {
type TSLexMode (line 77) | typedef struct {
type TSParseActionEntry (line 82) | typedef union {
type TSCharacterRange (line 90) | typedef struct {
type TSLanguage (line 95) | struct TSLanguage {
function set_contains (line 134) | static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, ...
FILE: test/highlight/classes.rb
class Car (line 4) | class Car < Vehicle
method init (line 8) | def init(id)
FILE: test/highlight/constants.rb
class MyClass (line 1) | class MyClass
method OtherClass (line 10) | def OtherClass
FILE: test/highlight/variables.rb
function two (line 4) | def two()
Condensed preview — 67 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (565K chars).
[
{
"path": ".editorconfig",
"chars": 541,
"preview": "root = true\n\n[*]\ncharset = utf-8\n\n[*.{json,toml,yml,gyp}]\nindent_style = space\nindent_size = 2\n\n[*.js]\nindent_style = sp"
},
{
"path": ".gitattributes",
"chars": 862,
"preview": "* text=auto eol=lf\n\n# Generated source files\nsrc/*.json linguist-generated\nsrc/parser.c linguist-generated\nsrc/tree_sitt"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 2729,
"preview": "name: Bug Report\ndescription: File a bug or issue\ntitle: \"bug: \"\nlabels: [bug]\nbody:\n - type: markdown\n attributes:\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 28,
"preview": "blank_issues_enabled: false\n"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.yml",
"chars": 1601,
"preview": "name: Feature Request\ndescription: Suggest a new feature\ntitle: \"feature: \"\nlabels: [enhancement]\nbody:\n - type: checkb"
},
{
"path": ".github/workflows/ci.yml",
"chars": 1808,
"preview": "name: CI\n\non:\n push:\n branches: [master]\n paths:\n - grammar.js\n - src/**\n - test/**\n - bindin"
},
{
"path": ".github/workflows/fuzz.yml",
"chars": 323,
"preview": "name: Fuzz Parser\n\non:\n push:\n branches: [master]\n paths:\n - src/scanner.c\n pull_request:\n paths:\n "
},
{
"path": ".github/workflows/lint.yml",
"chars": 511,
"preview": "name: Lint\n\non:\n push:\n branches: [master]\n paths:\n - grammar.js\n pull_request:\n paths:\n - grammar."
},
{
"path": ".github/workflows/publish.yml",
"chars": 796,
"preview": "name: Publish packages\n\non:\n push:\n tags: [\"*\"]\n\npermissions:\n contents: write\n id-token: write\n attestations: wr"
},
{
"path": ".gitignore",
"chars": 324,
"preview": "# Rust artifacts\ntarget/\n\n# Node artifacts\nbuild/\nprebuilds/\nnode_modules/\n\n# Swift artifacts\n.build/\n\n# Go artifacts\n_o"
},
{
"path": "CMakeLists.txt",
"chars": 2422,
"preview": "cmake_minimum_required(VERSION 3.13)\n\nproject(tree-sitter-ruby\n VERSION \"0.23.1\"\n DESCRIPTION \"Ruby gramma"
},
{
"path": "Cargo.toml",
"chars": 725,
"preview": "[package]\nname = \"tree-sitter-ruby\"\ndescription = \"Ruby grammar for tree-sitter\"\nversion = \"0.23.1\"\nauthors = [\n \"Max B"
},
{
"path": "LICENSE",
"chars": 1075,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2016 Rob Rix\n\nPermission is hereby granted, free of charge, to any person obtaining"
},
{
"path": "Makefile",
"chars": 3179,
"preview": "ifeq ($(OS),Windows_NT)\n$(error Windows is not supported)\nendif\n\nLANGUAGE_NAME := tree-sitter-ruby\nHOMEPAGE_URL := https"
},
{
"path": "Package.resolved",
"chars": 333,
"preview": "{\n \"object\": {\n \"pins\": [\n {\n \"package\": \"SwiftTreeSitter\",\n \"repositoryURL\": \"https://github.com"
},
{
"path": "Package.swift",
"chars": 993,
"preview": "// swift-tools-version:5.3\nimport PackageDescription\n\nlet package = Package(\n name: \"TreeSitterRuby\",\n products: ["
},
{
"path": "README.md",
"chars": 1131,
"preview": "# tree-sitter-ruby\n\n[![CI][ci]](https://github.com/tree-sitter/tree-sitter-ruby/actions/workflows/ci.yml)\n[![discord][di"
},
{
"path": "binding.gyp",
"chars": 599,
"preview": "{\n \"targets\": [\n {\n \"target_name\": \"tree_sitter_ruby_binding\",\n \"dependencies\": [\n \"<!(node -p \\\"re"
},
{
"path": "bindings/c/tree-sitter-ruby.h",
"chars": 238,
"preview": "#ifndef TREE_SITTER_RUBY_H_\n#define TREE_SITTER_RUBY_H_\n\ntypedef struct TSLanguage TSLanguage;\n\n#ifdef __cplusplus\nexter"
},
{
"path": "bindings/c/tree-sitter-ruby.pc.in",
"chars": 293,
"preview": "prefix=@CMAKE_INSTALL_PREFIX@\nlibdir=${prefix}/@CMAKE_INSTALL_LIBDIR@\nincludedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@\n\nN"
},
{
"path": "bindings/go/binding.go",
"chars": 283,
"preview": "package tree_sitter_ruby\n\n// #cgo CFLAGS: -std=c11 -fPIC\n// #include \"../../src/parser.c\"\n// #include \"../../src/scanner"
},
{
"path": "bindings/go/binding_test.go",
"chars": 354,
"preview": "package tree_sitter_ruby_test\n\nimport (\n\t\"testing\"\n\n\ttree_sitter \"github.com/tree-sitter/go-tree-sitter\"\n\ttree_sitter_ru"
},
{
"path": "bindings/node/binding.cc",
"chars": 577,
"preview": "#include <napi.h>\n\ntypedef struct TSLanguage TSLanguage;\n\nextern \"C\" TSLanguage *tree_sitter_ruby();\n\n// \"tree-sitter\", "
},
{
"path": "bindings/node/binding_test.js",
"chars": 250,
"preview": "const assert = require(\"node:assert\");\nconst { test } = require(\"node:test\");\n\nconst Parser = require(\"tree-sitter\");\n\nt"
},
{
"path": "bindings/node/index.d.ts",
"chars": 452,
"preview": "type BaseNode = {\n type: string;\n named: boolean;\n};\n\ntype ChildNode = {\n multiple: boolean;\n required: boolean;\n t"
},
{
"path": "bindings/node/index.js",
"chars": 453,
"preview": "const root = require(\"path\").join(__dirname, \"..\", \"..\");\n\nmodule.exports =\n typeof process.versions.bun === \"string\"\n "
},
{
"path": "bindings/python/tests/test_binding.py",
"chars": 290,
"preview": "from unittest import TestCase\n\nimport tree_sitter, tree_sitter_ruby\n\n\nclass TestLanguage(TestCase):\n def test_can_loa"
},
{
"path": "bindings/python/tree_sitter_ruby/__init__.py",
"chars": 926,
"preview": "\"\"\"Ruby grammar for tree-sitter\"\"\"\n\nfrom importlib.resources import files as _files\n\nfrom ._binding import language\n\n\nde"
},
{
"path": "bindings/python/tree_sitter_ruby/__init__.pyi",
"chars": 134,
"preview": "from typing import Final\n\nHIGHLIGHTS_QUERY: Final[str]\nLOCALS_QUERY: Final[str]\nTAGS_QUERY: Final[str]\n\ndef language() -"
},
{
"path": "bindings/python/tree_sitter_ruby/binding.c",
"chars": 679,
"preview": "#include <Python.h>\n\ntypedef struct TSLanguage TSLanguage;\n\nTSLanguage *tree_sitter_ruby(void);\n\nstatic PyObject* _bindi"
},
{
"path": "bindings/python/tree_sitter_ruby/py.typed",
"chars": 0,
"preview": ""
},
{
"path": "bindings/rust/build.rs",
"chars": 1421,
"preview": "fn main() {\n let src_dir = std::path::Path::new(\"src\");\n\n let mut c_config = cc::Build::new();\n c_config\n "
},
{
"path": "bindings/rust/lib.rs",
"chars": 2019,
"preview": "//! This crate provides Ruby language support for the [tree-sitter][] parsing library.\n//!\n//! Typically, you will use t"
},
{
"path": "bindings/swift/TreeSitterRuby/ruby.h",
"chars": 238,
"preview": "#ifndef TREE_SITTER_RUBY_H_\n#define TREE_SITTER_RUBY_H_\n\ntypedef struct TSLanguage TSLanguage;\n\n#ifdef __cplusplus\nexter"
},
{
"path": "bindings/swift/TreeSitterRubyTests/TreeSitterRubyTests.swift",
"chars": 359,
"preview": "import XCTest\nimport SwiftTreeSitter\nimport TreeSitterRuby\n\nfinal class TreeSitterRubyTests: XCTestCase {\n func testC"
},
{
"path": "eslint.config.mjs",
"chars": 89,
"preview": "import treesitter from 'eslint-config-treesitter';\n\nexport default [\n ...treesitter,\n];\n"
},
{
"path": "go.mod",
"chars": 167,
"preview": "module github.com/tree-sitter/tree-sitter-ruby\n\ngo 1.22\n\nrequire github.com/tree-sitter/go-tree-sitter v0.24.0\n\nrequire "
},
{
"path": "go.sum",
"chars": 3917,
"preview": "github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.m"
},
{
"path": "grammar.js",
"chars": 35373,
"preview": "/// <reference types=\"tree-sitter-cli/dsl\" />\n// @ts-check\n\nconst PREC = {\n COMMENT: -2,\n CURLY_BLOCK: 1,\n DO_BLOCK: "
},
{
"path": "package.json",
"chars": 1599,
"preview": "{\n \"name\": \"tree-sitter-ruby\",\n \"version\": \"0.23.1\",\n \"description\": \"Ruby grammar for tree-sitter\",\n \"repository\": "
},
{
"path": "pyproject.toml",
"chars": 876,
"preview": "[build-system]\nrequires = [\"setuptools>=42\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"tree-si"
},
{
"path": "queries/highlights.scm",
"chars": 2377,
"preview": "(identifier) @variable\n\n((identifier) @function.method\n (#is-not? local))\n\n[\n \"alias\"\n \"and\"\n \"begin\"\n \"break\"\n \"ca"
},
{
"path": "queries/locals.scm",
"chars": 895,
"preview": "((method) @local.scope\n (#set! local.scope-inherits false))\n\n[\n (lambda)\n (block)\n (do_block)\n] @local.scope\n\n(block_"
},
{
"path": "queries/tags.scm",
"chars": 1087,
"preview": "; Method definitions\n\n(\n (comment)* @doc\n .\n [\n (method\n name: (_) @name) @definition.method\n (singleton_m"
},
{
"path": "setup.py",
"chars": 1704,
"preview": "from os.path import isdir, join\nfrom platform import system\n\nfrom setuptools import Extension, find_packages, setup\nfrom"
},
{
"path": "src/grammar.json",
"chars": 192934,
"preview": "{\n \"$schema\": \"https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json\",\n \"name\": \"ruby\",\n \"word"
},
{
"path": "src/node-types.json",
"chars": 70025,
"preview": "[\n {\n \"type\": \"_arg\",\n \"named\": true,\n \"subtypes\": [\n {\n \"type\": \"_primary\",\n \"named\": true"
},
{
"path": "src/scanner.c",
"chars": 37383,
"preview": "#include \"tree_sitter/alloc.h\"\n#include \"tree_sitter/array.h\"\n#include \"tree_sitter/parser.h\"\n\n#include <string.h>\n#incl"
},
{
"path": "src/tree_sitter/alloc.h",
"chars": 985,
"preview": "#ifndef TREE_SITTER_ALLOC_H_\n#define TREE_SITTER_ALLOC_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdbool.h>\n"
},
{
"path": "src/tree_sitter/array.h",
"chars": 10420,
"preview": "#ifndef TREE_SITTER_ARRAY_H_\n#define TREE_SITTER_ARRAY_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"./alloc.h\"\n"
},
{
"path": "src/tree_sitter/parser.h",
"chars": 7039,
"preview": "#ifndef TREE_SITTER_PARSER_H_\n#define TREE_SITTER_PARSER_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdbool.h"
},
{
"path": "test/corpus/comments.txt",
"chars": 1279,
"preview": "========\ncomments\n========\n\n# anything else here should be ignored\n\n---\n\n(program (comment))\n\n===================\nempty "
},
{
"path": "test/corpus/control-flow.txt",
"chars": 9449,
"preview": "=====================\nempty while statement\n=====================\n\nwhile foo do\nend\n\n---\n\n(program (while\n condition: ("
},
{
"path": "test/corpus/declarations.txt",
"chars": 12173,
"preview": "============\nempty method\n============\n\ndef foo\nend\n\ndef foo?\nend\n\ndef foo!\nend\n\n---\n\n(program\n (method (identifier))\n "
},
{
"path": "test/corpus/expressions.txt",
"chars": 44937,
"preview": "================\nscope resolution\n================\n\nFoo::Bar\n::Bar\n\nputs ::Foo::Bar\n\n---\n\n(program\n (scope_resolution\n "
},
{
"path": "test/corpus/line-endings.txt",
"chars": 354,
"preview": "=================\r\nCRLF line endings\r\n=================\r\n\r\nputs 'hi'\r\nx = foo()\r\n\r\n---\r\n\r\n(program\r\n (call (identifier)"
},
{
"path": "test/corpus/literals.txt",
"chars": 33533,
"preview": "======\nsymbol\n======\n\n:foo\n:foo!\n:foo?\n:foo=\n:@foo\n:@foo_0123_bar\n:@@foo\n:$foo\n:$0\n:_bar\n:åäö\n:_\n\n---\n\n(program\n (simpl"
},
{
"path": "test/corpus/patterns.txt",
"chars": 10571,
"preview": "================\npattern matching\n================\n\ncase expr\n in 5 then true\n else false\nend\n\ncase expr\n in x unless"
},
{
"path": "test/corpus/single-cr-as-whitespace.txt",
"chars": 207,
"preview": "==================================\nSingle CR characters as whitespace\n==================================\n\nputs\r\r\r\r\r\r\r\r\r\r"
},
{
"path": "test/corpus/statements.txt",
"chars": 1275,
"preview": "====================\nconditional modifier\n====================\n\nfoo if bar\nreturn if false\nreturn true if foo bar\nreturn"
},
{
"path": "test/highlight/classes.rb",
"chars": 398,
"preview": "require \"a\"\n# ^ function.method.builtin\n\nclass Car < Vehicle\n # <- keyword\n # ^ constructor\n\n def init(id)\n # <"
},
{
"path": "test/highlight/constants.rb",
"chars": 430,
"preview": "class MyClass\n # ^ constructor\n\n ELEMENT8 = 8\n # ^ constant\n\n ELEMENT16 = 16\n # ^ constant\n\n def OtherClass\n "
},
{
"path": "test/highlight/literals.rb",
"chars": 459,
"preview": "\"hello\"\n# ^ string\n%(hello)\n# ^ string\n%w(hello goodbye)\n# ^ string\n# ^ string\n\n:hello\n# ^ string.special.symb"
},
{
"path": "test/highlight/patterns.rb",
"chars": 534,
"preview": "expr = [false | __LINE__ | __FILE__ | __ENCODING__]\n# ^ constant.builtin\n# ^ constant.builtin\n# "
},
{
"path": "test/highlight/variables.rb",
"chars": 1222,
"preview": "one = 1\n# <- variable\n\ndef two()\n three = one\n # ^ variable\n # ^ function.method\n\n four = three\n # ^ variabl"
},
{
"path": "tree-sitter.json",
"chars": 911,
"preview": "{\n \"grammars\": [\n {\n \"name\": \"ruby\",\n \"camelcase\": \"Ruby\",\n \"scope\": \"source.ruby\",\n \"path\": \".\""
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the tree-sitter/tree-sitter-ruby GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 67 files (15.1 MB), approximately 122.2k tokens, and a symbol index with 93 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.