Full Code of tree-sitter/tree-sitter-ruby for AI

master ad907a69da0c cached
67 files
15.1 MB
122.2k tokens
93 symbols
1 requests
Download .txt
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": "{"
         
Download .txt
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
Download .txt
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.

Copied to clipboard!