Copy disabled (too large)
Download .txt
Showing preview only (10,429K chars total). Download the full file to get everything.
Repository: tree-sitter/tree-sitter-bash
Branch: master
Commit: a06c2e4415e9
Files: 64
Total size: 9.9 MB
Directory structure:
gitextract_j8navkbf/
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ └── workflows/
│ ├── ci.yml
│ ├── fuzz.yml
│ ├── lint.yml
│ └── publish.yml
├── .gitignore
├── CMakeLists.txt
├── Cargo.toml
├── LICENSE
├── Makefile
├── Package.swift
├── README.md
├── binding.gyp
├── bindings/
│ ├── c/
│ │ ├── tree-sitter-bash.pc.in
│ │ └── tree_sitter/
│ │ └── tree-sitter-bash.h
│ ├── go/
│ │ ├── binding.go
│ │ └── binding_test.go
│ ├── node/
│ │ ├── binding.cc
│ │ ├── binding_test.js
│ │ ├── index.d.ts
│ │ └── index.js
│ ├── python/
│ │ ├── tests/
│ │ │ └── test_binding.py
│ │ └── tree_sitter_bash/
│ │ ├── __init__.py
│ │ ├── __init__.pyi
│ │ ├── binding.c
│ │ └── py.typed
│ ├── rust/
│ │ ├── build.rs
│ │ └── lib.rs
│ └── swift/
│ ├── TreeSitterBash/
│ │ └── bash.h
│ └── TreeSitterBashTests/
│ └── TreeSitterBashTests.swift
├── eslint.config.mjs
├── examples/
│ ├── atom.sh
│ ├── clean-old.sh
│ ├── doc-build.sh
│ ├── install.sh
│ ├── release.sh
│ ├── relocate.sh
│ ├── test.sh
│ └── update-authors.sh
├── go.mod
├── go.sum
├── grammar.js
├── package.json
├── pyproject.toml
├── queries/
│ └── highlights.scm
├── script/
│ ├── known-failures.txt
│ └── parse-examples
├── setup.py
├── src/
│ ├── grammar.json
│ ├── node-types.json
│ ├── parser.c
│ ├── scanner.c
│ └── tree_sitter/
│ ├── alloc.h
│ ├── array.h
│ └── parser.h
├── test/
│ └── corpus/
│ ├── commands.txt
│ ├── crlf.txt
│ ├── literals.txt
│ ├── programs.txt
│ └── statements.txt
└── 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
# Zig bindings
build.zig linguist-generated
build.zig.zon linguist-generated
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: tree-sitter
patreon: # Replace with a single Patreon username
open_collective: tree-sitter # Replace with a single Open Collective username
ko_fi: amaanq
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"
================================================
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@v5
- name: Set up tree-sitter
uses: tree-sitter/setup-action/cli@v2
- name: Set up examples
shell: bash
run: |-
git clone https://github.com/Bash-it/bash-it examples/bash-it -q --single-branch --depth=1
git clone https://git.savannah.gnu.org/git/bash.git examples/bash -q --single-branch --depth=1
git clone https://anongit.gentoo.org/git/repo/gentoo.git examples/gentoo -q --single-branch --depth=1
if [[ $RUNNER_OS != Windows ]]; then
git clone https://github.com/oilshell/wild-corpus examples/wild-corpus -q --single-branch --depth=1
fi
- name: Run tests
uses: tree-sitter/parser-test-action@v3
with:
generate: false
test-rust: true
test-node: false
test-python: true
test-go: true
test-swift: false
- name: Parse examples
uses: tree-sitter/parse-action@v4
with:
files: |-
examples/*.sh
examples/bash-it/**/*.sh
examples/bash-it/**/*.bash
examples/bash/**/*.sh
examples/bash/**/*.tests
examples/gentoo/**/*.sh
examples/gentoo/**/*.eclass
examples/wild-corpus/**/*.sh
# examples/gentoo/**/*.ebuild
!examples/gentoo/app-antivirus/fangfrisch/files/fangfrisch-has-news.sh
!examples/gentoo/eclass/ruby-fakegem.eclass
invalid-files-list: script/known-failures.txt
================================================
FILE: .github/workflows/fuzz.yml
================================================
name: Fuzz
on:
push:
paths:
- src/scanner.c
pull_request:
paths:
- src/scanner.c
workflow_dispatch:
concurrency:
group: ${{github.workflow}}-${{github.ref}}
cancel-in-progress: true
jobs:
test:
name: Fuzz scanner
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Run fuzzer
uses: tree-sitter/fuzz-action@v4
with:
corpus: examples
================================================
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@v5
- name: Set up Node.js
uses: actions/setup-node@v5
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/
Package.resolved
# Go artifacts
_obj/
# Python artifacts
.venv/
dist/
*.egg-info
*.whl
# C artifacts
*.a
*.so
*.so.*
*.dylib
*.dll
*.pc
*.exp
*.lib
# Zig artifacts
.zig-cache/
zig-cache/
zig-out/
# 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-bash
VERSION "0.25.1"
DESCRIPTION "Bash grammar for tree-sitter"
HOMEPAGE_URL "https://github.com/tree-sitter/tree-sitter-bash"
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-bash src/parser.c)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c)
target_sources(tree-sitter-bash PRIVATE src/scanner.c)
endif()
target_include_directories(tree-sitter-bash
PRIVATE src
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/bindings/c>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_compile_definitions(tree-sitter-bash PRIVATE
$<$<BOOL:${TREE_SITTER_REUSE_ALLOCATOR}>:TREE_SITTER_REUSE_ALLOCATOR>
$<$<CONFIG:Debug>:TREE_SITTER_DEBUG>)
set_target_properties(tree-sitter-bash
PROPERTIES
C_STANDARD 11
POSITION_INDEPENDENT_CODE ON
SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}"
DEFINE_SYMBOL "")
configure_file(bindings/c/tree-sitter-bash.pc.in
"${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-bash.pc" @ONLY)
include(GNUInstallDirs)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bindings/c/tree_sitter"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
FILES_MATCHING PATTERN "*.h")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-bash.pc"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig")
install(TARGETS tree-sitter-bash
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-bash"
description = "Bash grammar for tree-sitter"
version = "0.25.1"
authors = [
"Max Brunsfeld <maxbrunsfeld@gmail.com>",
"Amaan Qureshi <amaanq12@gmail.com>",
]
license = "MIT"
readme = "README.md"
keywords = ["incremental", "parsing", "tree-sitter", "bash"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/tree-sitter/tree-sitter-bash"
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.25"
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2017 Max Brunsfeld
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-bash
HOMEPAGE_URL := https://github.com/tree-sitter/tree-sitter-bash
VERSION := 0.25.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/tree_sitter/$(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.swift
================================================
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "TreeSitterBash",
products: [
.library(name: "TreeSitterBash", targets: ["TreeSitterBash"])
],
dependencies: [
.package(
name: "SwiftTreeSitter",
url: "https://github.com/tree-sitter/swift-tree-sitter",
from: "0.25.0"
)
],
targets: [
.target(
name: "TreeSitterBash",
dependencies: [],
path: ".",
sources: [
"src/parser.c",
"src/scanner.c",
],
resources: [
.copy("queries")
],
publicHeadersPath: "bindings/swift",
cSettings: [.headerSearchPath("src")]
),
.testTarget(
name: "TreeSitterBashTests",
dependencies: [
"SwiftTreeSitter",
"TreeSitterBash",
],
path: "bindings/swift/TreeSitterBashTests"
),
],
cLanguageStandard: .c11
)
================================================
FILE: README.md
================================================
# tree-sitter-bash
[![CI][ci]](https://github.com/tree-sitter/tree-sitter-bash/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-bash)
[![npm][npm]](https://www.npmjs.com/package/tree-sitter-bash)
[![pypi][pypi]](https://pypi.org/project/tree-sitter-bash)
Bash grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).
## Development
Install the dependencies:
```sh
npm install
```
Build and run the tests:
```sh
npm run build
npm run test
```
Run the build and tests in watch mode:
```sh
npm run test:watch
```
### References
- [Bash man page](http://man7.org/linux/man-pages/man1/bash.1.html#SHELL_GRAMMAR)
- [Shell command language specification](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html)
- [mvdnan/sh - a shell parser in go](https://github.com/mvdan/sh)
[ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter/tree-sitter-bash/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-bash?logo=npm
[crates]: https://img.shields.io/crates/v/tree-sitter-bash?logo=rust
[pypi]: https://img.shields.io/pypi/v/tree-sitter-bash?logo=pypi&logoColor=ffd242
================================================
FILE: binding.gyp
================================================
{
"targets": [
{
"target_name": "tree_sitter_bash_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-bash.pc.in
================================================
prefix=@CMAKE_INSTALL_PREFIX@
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: tree-sitter-bash
Description: @PROJECT_DESCRIPTION@
URL: @PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
Libs: -L${libdir} -ltree-sitter-bash
Cflags: -I${includedir}
================================================
FILE: bindings/c/tree_sitter/tree-sitter-bash.h
================================================
#ifndef TREE_SITTER_BASH_H_
#define TREE_SITTER_BASH_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
const TSLanguage *tree_sitter_bash(void);
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_BASH_H_
================================================
FILE: bindings/go/binding.go
================================================
package tree_sitter_bash
// #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_bash())
}
================================================
FILE: bindings/go/binding_test.go
================================================
package tree_sitter_bash_test
import (
"testing"
tree_sitter "github.com/tree-sitter/go-tree-sitter"
tree_sitter_bash "github.com/tree-sitter/tree-sitter-bash/bindings/go"
)
func TestCanLoadGrammar(t *testing.T) {
language := tree_sitter.NewLanguage(tree_sitter_bash.Language())
if language == nil {
t.Errorf("Error loading Bash grammar")
}
}
================================================
FILE: bindings/node/binding.cc
================================================
#include <napi.h>
typedef struct TSLanguage TSLanguage;
extern "C" TSLanguage *tree_sitter_bash();
// "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, "bash");
auto language = Napi::External<TSLanguage>::New(env, tree_sitter_bash());
language.TypeTag(&LANGUAGE_TYPE_TAG);
exports["language"] = language;
return exports;
}
NODE_API_MODULE(tree_sitter_bash_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-bash.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_bash
class TestLanguage(TestCase):
def test_can_load_grammar(self):
try:
tree_sitter.Language(tree_sitter_bash.language())
except Exception:
self.fail("Error loading Bash grammar")
================================================
FILE: bindings/python/tree_sitter_bash/__init__.py
================================================
"""Bash 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")
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
__all__ = [
"language",
"HIGHLIGHTS_QUERY",
]
def __dir__():
return sorted(__all__ + [
"__all__", "__builtins__", "__cached__", "__doc__", "__file__",
"__loader__", "__name__", "__package__", "__path__", "__spec__",
])
================================================
FILE: bindings/python/tree_sitter_bash/__init__.pyi
================================================
from typing import Final
HIGHLIGHTS_QUERY: Final[str]
def language() -> object: ...
================================================
FILE: bindings/python/tree_sitter_bash/binding.c
================================================
#include <Python.h>
typedef struct TSLanguage TSLanguage;
TSLanguage *tree_sitter_bash(void);
static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) {
return PyCapsule_New(tree_sitter_bash(), "tree_sitter.Language", NULL);
}
static struct PyModuleDef_Slot slots[] = {
#ifdef Py_GIL_DISABLED
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
#endif
{0, 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 = 0,
.m_methods = methods,
.m_slots = slots,
};
PyMODINIT_FUNC PyInit__binding(void) {
return PyModuleDef_Init(&module);
}
================================================
FILE: bindings/python/tree_sitter_bash/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");
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-bash");
}
================================================
FILE: bindings/rust/lib.rs
================================================
//! This crate provides Bash 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#"
//! echo "hello world!"
//! "#;
//! let mut parser = Parser::new();
//! let language = tree_sitter_bash::LANGUAGE;
//! parser
//! .set_language(&language.into())
//! .expect("Error loading Bash 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_bash() -> *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_bash) };
/// 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 grammar.
pub const HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights.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 Bash parser");
}
}
================================================
FILE: bindings/swift/TreeSitterBash/bash.h
================================================
#ifndef TREE_SITTER_BASH_H_
#define TREE_SITTER_BASH_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
const TSLanguage *tree_sitter_bash(void);
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_BASH_H_
================================================
FILE: bindings/swift/TreeSitterBashTests/TreeSitterBashTests.swift
================================================
import XCTest
import SwiftTreeSitter
import TreeSitterBash
final class TreeSitterBashTests: XCTestCase {
func testCanLoadGrammar() throws {
let parser = Parser()
let language = Language(language: tree_sitter_bash())
XCTAssertNoThrow(try parser.setLanguage(language),
"Error loading Bash grammar")
}
}
================================================
FILE: eslint.config.mjs
================================================
import treesitter from 'eslint-config-treesitter';
export default [
...treesitter,
];
================================================
FILE: examples/atom.sh
================================================
#!/bin/bash
if [ "$(uname)" == 'Darwin' ]; then
OS='Mac'
elif [ "$(expr substr $(uname -s) 1 5)" == 'Linux' ]; then
OS='Linux'
else
echo "Your platform ($(uname -a)) is not supported."
exit 1
fi
if [ "$(basename $0)" == 'atom-beta' ]; then
BETA_VERSION=true
else
BETA_VERSION=
fi
export ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT=true
while getopts ":wtfvh-:" opt; do
case "$opt" in
-)
case "${OPTARG}" in
wait)
WAIT=1
;;
help|version)
REDIRECT_STDERR=1
EXPECT_OUTPUT=1
;;
foreground|benchmark|benchmark-test|test)
EXPECT_OUTPUT=1
;;
esac
;;
w)
WAIT=1
;;
h|v)
REDIRECT_STDERR=1
EXPECT_OUTPUT=1
;;
f|t)
EXPECT_OUTPUT=1
;;
esac
done
if [ $REDIRECT_STDERR ]; then
exec 2> /dev/null
fi
if [ $EXPECT_OUTPUT ]; then
export ELECTRON_ENABLE_LOGGING=1
fi
if [ $OS == 'Mac' ]; then
if [ -L "$0" ]; then
SCRIPT="$(readlink "$0")"
else
SCRIPT="$0"
fi
ATOM_APP="$(dirname "$(dirname "$(dirname "$(dirname "$SCRIPT")")")")"
if [ "$ATOM_APP" == . ]; then
unset ATOM_APP
else
ATOM_PATH="$(dirname "$ATOM_APP")"
ATOM_APP_NAME="$(basename "$ATOM_APP")"
fi
if [ -n "$BETA_VERSION" ]; then
ATOM_EXECUTABLE_NAME="Atom Beta"
else
ATOM_EXECUTABLE_NAME="Atom"
fi
if [ -z "${ATOM_PATH}" ]; then
# If ATOM_PATH isn't set, check /Applications and then ~/Applications for Atom.app
if [ -x "/Applications/$ATOM_APP_NAME" ]; then
ATOM_PATH="/Applications"
elif [ -x "$HOME/Applications/$ATOM_APP_NAME" ]; then
ATOM_PATH="$HOME/Applications"
else
# We haven't found an Atom.app, use spotlight to search for Atom
ATOM_PATH="$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | grep -v ShipIt | head -1 | xargs -0 dirname)"
# Exit if Atom can't be found
if [ ! -x "$ATOM_PATH/$ATOM_APP_NAME" ]; then
echo "Cannot locate ${ATOM_APP_NAME}, it is usually located in /Applications. Set the ATOM_PATH environment variable to the directory containing ${ATOM_APP_NAME}."
exit 1
fi
fi
fi
if [ $EXPECT_OUTPUT ]; then
"$ATOM_PATH/$ATOM_APP_NAME/Contents/MacOS/$ATOM_EXECUTABLE_NAME" --executed-from="$(pwd)" --pid=$$ "$@"
exit $?
else
open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ --path-environment="$PATH" "$@"
fi
elif [ $OS == 'Linux' ]; then
SCRIPT=$(readlink -f "$0")
USR_DIRECTORY=$(readlink -f $(dirname $SCRIPT)/..)
if [ -n "$BETA_VERSION" ]; then
ATOM_PATH="$USR_DIRECTORY/share/atom-beta/atom"
else
ATOM_PATH="$USR_DIRECTORY/share/atom/atom"
fi
ATOM_HOME="${ATOM_HOME:-$HOME/.atom}"
mkdir -p "$ATOM_HOME"
: ${TMPDIR:=/tmp}
[ -x "$ATOM_PATH" ] || ATOM_PATH="$TMPDIR/atom-build/Atom/atom"
if [ $EXPECT_OUTPUT ]; then
"$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@"
exit $?
else
(
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$ATOM_HOME/nohup.out" 2>&1
if [ $? -ne 0 ]; then
cat "$ATOM_HOME/nohup.out"
exit $?
fi
) &
fi
fi
# Exits this process when Atom is used as $EDITOR
on_die() {
exit 0
}
trap 'on_die' SIGQUIT SIGTERM
# If the wait flag is set, don't exit this process until Atom tells it to.
if [ $WAIT ]; then
while true; do
sleep 1
done
fi
================================================
FILE: examples/clean-old.sh
================================================
#!/bin/bash
# look for old 0.x cruft, and get rid of it.
# Should already be sitting in the npm folder.
# This doesn't have to be quite as cross-platform as install.sh.
# There are some bash-isms, because maintaining *two*
# fully-portable posix/bourne sh scripts is too much for
# one project with a sane maintainer.
# If readlink isn't available, then this is just too tricky.
# However, greadlink is fine, so Solaris can join the party, too.
readlink="readlink"
which $readlink >/dev/null 2>/dev/null
if [ $? -ne 0 ]; then
readlink="greadlink"
which $readlink >/dev/null 2>/dev/null
if [ $? -ne 0 ]; then
echo "Can't find the readlink or greadlink command. Aborting."
exit 1
fi
fi
if [ "x$npm_config_prefix" != "x" ]; then
PREFIXES=$npm_config_prefix
else
node="$NODE"
if [ "x$node" = "x" ]; then
node=`which node`
fi
if [ "x$node" = "x" ]; then
echo "Can't find node to determine prefix. Aborting."
exit 1
fi
PREFIX=`dirname $node`
PREFIX=`dirname $PREFIX`
echo "cleanup prefix=$PREFIX"
PREFIXES=$PREFIX
altprefix=`"$node" -e process.installPrefix`
if [ "x$altprefix" != "x" ] && [ "x$altprefix" != "x$PREFIX" ]; then
echo "altprefix=$altprefix"
PREFIXES="$PREFIX $altprefix"
fi
fi
# now prefix is where npm would be rooted by default
# go hunting.
packages=
for prefix in $PREFIXES; do
packages="$packages
"`ls "$prefix"/lib/node/.npm 2>/dev/null | grep -v .cache`
done
packages=`echo $packages`
filelist=()
fid=0
for prefix in $PREFIXES; do
# remove any links into the .npm dir, or links to
# version-named shims/symlinks.
for folder in share/man bin lib/node; do
find $prefix/$folder -type l | while read file; do
target=`$readlink $file | grep '/\.npm/'`
if [ "x$target" != "x" ]; then
# found one!
filelist[$fid]="$file"
let 'fid++'
# also remove any symlinks to this file.
base=`basename "$file"`
base=`echo "$base" | awk -F@ '{print $1}'`
if [ "x$base" != "x" ]; then
find "`dirname $file`" -type l -name "$base"'*' \
| while read l; do
target=`$readlink "$l" | grep "$base"`
if [ "x$target" != "x" ]; then
filelist[$fid]="$1"
let 'fid++'
fi
done
fi
fi
done
# Scour for shim files. These are relics of 0.2 npm installs.
# note: grep -r is not portable.
find $prefix/$folder -type f \
| xargs grep -sl '// generated by npm' \
| while read file; do
filelist[$fid]="$file"
let 'fid++'
done
done
# now remove the package modules, and the .npm folder itself.
if [ "x$packages" != "x" ]; then
for pkg in $packages; do
filelist[$fid]="$prefix/lib/node/$pkg"
let 'fid++'
for i in $prefix/lib/node/$pkg\@*; do
filelist[$fid]="$i"
let 'fid++'
done
done
fi
for folder in lib/node/.npm lib/npm share/npm; do
if [ -d $prefix/$folder ]; then
filelist[$fid]="$prefix/$folder"
let 'fid++'
fi
done
done
# now actually clean, but only if there's anything TO clean
if [ "${#filelist[@]}" -gt 0 ]; then
echo ""
echo "This script will find and eliminate any shims, symbolic"
echo "links, and other cruft that was installed by npm 0.x."
echo ""
if [ "x$packages" != "x" ]; then
echo "The following packages appear to have been installed with"
echo "an old version of npm, and will be removed forcibly:"
for pkg in $packages; do
echo " $pkg"
done
echo "Make a note of these. You may want to install them"
echo "with npm 1.0 when this process is completed."
echo ""
fi
OK=
if [ "x$1" = "x-y" ]; then
OK="yes"
fi
while [ "$OK" != "y" ] && [ "$OK" != "yes" ] && [ "$OK" != "no" ]; do
echo "Is this OK?"
echo " enter 'yes' or 'no'"
echo " or 'show' to see a list of files "
read OK
if [ "x$OK" = "xshow" ] || [ "x$OK" = "xs" ]; then
for i in "${filelist[@]}"; do
echo "$i"
done
fi
done
if [ "$OK" = "no" ]; then
echo "Aborting"
exit 1
fi
for i in "${filelist[@]}"; do
rm -rf "$i"
done
fi
echo ""
echo 'All clean!'
exit 0
================================================
FILE: examples/doc-build.sh
================================================
#!/usr/bin/env bash
if [[ $DEBUG != "" ]]; then
set -x
fi
set -o errexit
set -o pipefail
if ! [ -x node_modules/.bin/marked-man ]; then
ps=0
if [ -f .building_marked-man ]; then
pid=$(cat .building_marked-man)
ps=$(ps -p $pid | grep $pid | wc -l) || true
fi
if [ -f .building_marked-man ] && [ $ps != 0 ]; then
while [ -f .building_marked-man ]; do
sleep 1
done
else
# a race to see which make process will be the one to install marked-man
echo $$ > .building_marked-man
sleep 1
if [ $(cat .building_marked-man) == $$ ]; then
make node_modules/.bin/marked-man
rm .building_marked-man
else
while [ -f .building_marked-man ]; do
sleep 1
done
fi
fi
fi
if ! [ -x node_modules/.bin/marked ]; then
ps=0
if [ -f .building_marked ]; then
pid=$(cat .building_marked)
ps=$(ps -p $pid | grep $pid | wc -l) || true
fi
if [ -f .building_marked ] && [ $ps != 0 ]; then
while [ -f .building_marked ]; do
sleep 1
done
else
# a race to see which make process will be the one to install marked
echo $$ > .building_marked
sleep 1
if [ $(cat .building_marked) == $$ ]; then
make node_modules/.bin/marked
rm .building_marked
else
while [ -f .building_marked ]; do
sleep 1
done
fi
fi
fi
src=$1
dest=$2
name=$(basename ${src%.*})
date=$(date -u +'%Y-%m-%d %H:%M:%S')
version=$(node cli.js -v)
mkdir -p $(dirname $dest)
html_replace_tokens () {
local url=$1
sed "s|@NAME@|$name|g" \
| sed "s|@DATE@|$date|g" \
| sed "s|@URL@|$url|g" \
| sed "s|@VERSION@|$version|g" \
| perl -p -e 's/<h1([^>]*)>([^\(]*\([0-9]\)) -- (.*?)<\/h1>/<h1>\2<\/h1> <p>\3<\/p>/g' \
| perl -p -e 's/npm-npm/npm/g' \
| perl -p -e 's/([^"-])(npm-)?README(?!\.html)(\(1\))?/\1<a href="..\/..\/doc\/README.html">README<\/a>/g' \
| perl -p -e 's/<title><a href="[^"]+README.html">README<\/a><\/title>/<title>README<\/title>/g' \
| perl -p -e 's/([^"-])([^\(> ]+)(\(1\))/\1<a href="..\/cli\/\2.html">\2\3<\/a>/g' \
| perl -p -e 's/([^"-])([^\(> ]+)(\(3\))/\1<a href="..\/api\/\2.html">\2\3<\/a>/g' \
| perl -p -e 's/([^"-])([^\(> ]+)(\(5\))/\1<a href="..\/files\/\2.html">\2\3<\/a>/g' \
| perl -p -e 's/([^"-])([^\(> ]+)(\(7\))/\1<a href="..\/misc\/\2.html">\2\3<\/a>/g' \
| perl -p -e 's/\([1357]\)<\/a><\/h1>/<\/a><\/h1>/g' \
| (if [ $(basename $(dirname $dest)) == "doc" ]; then
perl -p -e 's/ href="\.\.\// href="/g'
else
cat
fi)
}
man_replace_tokens () {
sed "s|@VERSION@|$version|g" \
| perl -p -e 's/(npm\\-)?([a-zA-Z\\\.\-]*)\(1\)/npm help \2/g' \
| perl -p -e 's/(npm\\-)?([a-zA-Z\\\.\-]*)\(([57])\)/npm help \3 \2/g' \
| perl -p -e 's/(npm\\-)?([a-zA-Z\\\.\-]*)\(3\)/npm apihelp \2/g' \
| perl -p -e 's/npm\(1\)/npm help npm/g' \
| perl -p -e 's/npm\(3\)/npm apihelp npm/g'
}
case $dest in
*.[1357])
./node_modules/.bin/marked-man --roff $src \
| man_replace_tokens > $dest
exit $?
;;
*.html)
url=${dest/html\//}
(cat html/dochead.html && \
cat $src | ./node_modules/.bin/marked &&
cat html/docfoot.html)\
| html_replace_tokens $url \
> $dest
exit $?
;;
*)
echo "Invalid destination type: $dest" >&2
exit 1
;;
esac
================================================
FILE: examples/install.sh
================================================
#!/bin/sh
# A word about this shell script:
#
# It must work everywhere, including on systems that lack
# a /bin/bash, map 'sh' to ksh, ksh97, bash, ash, or zsh,
# and potentially have either a posix shell or bourne
# shell living at /bin/sh.
#
# See this helpful document on writing portable shell scripts:
# http://www.gnu.org/s/hello/manual/autoconf/Portable-Shell.html
#
# The only shell it won't ever work on is cmd.exe.
if [ "x$0" = "xsh" ]; then
# run as curl | sh
# on some systems, you can just do cat>npm-install.sh
# which is a bit cuter. But on others, &1 is already closed,
# so catting to another script file won't do anything.
# Follow Location: headers, and fail on errors
curl -f -L -s https://www.npmjs.org/install.sh > npm-install-$$.sh
ret=$?
if [ $ret -eq 0 ]; then
(exit 0)
else
rm npm-install-$$.sh
echo "Failed to download script" >&2
exit $ret
fi
sh npm-install-$$.sh
ret=$?
rm npm-install-$$.sh
exit $ret
fi
# See what "npm_config_*" things there are in the env,
# and make them permanent.
# If this fails, it's not such a big deal.
configures="`env | grep 'npm_config_' | sed -e 's|^npm_config_||g'`"
npm_config_loglevel="error"
if [ "x$npm_debug" = "x" ]; then
(exit 0)
else
echo "Running in debug mode."
echo "Note that this requires bash or zsh."
set -o xtrace
set -o pipefail
npm_config_loglevel="verbose"
fi
export npm_config_loglevel
# make sure that node exists
node=`which node 2>&1`
ret=$?
if [ $ret -eq 0 ] && [ -x "$node" ]; then
(exit 0)
else
echo "npm cannot be installed without node.js." >&2
echo "Install node first, and then try again." >&2
echo "" >&2
echo "Maybe node is installed, but not in the PATH?" >&2
echo "Note that running as sudo can change envs." >&2
echo ""
echo "PATH=$PATH" >&2
exit $ret
fi
# set the temp dir
TMP="${TMPDIR}"
if [ "x$TMP" = "x" ]; then
TMP="/tmp"
fi
TMP="${TMP}/npm.$$"
rm -rf "$TMP" || true
mkdir "$TMP"
if [ $? -ne 0 ]; then
echo "failed to mkdir $TMP" >&2
exit 1
fi
BACK="$PWD"
ret=0
tar="${TAR}"
if [ -z "$tar" ]; then
tar="${npm_config_tar}"
fi
if [ -z "$tar" ]; then
tar=`which tar 2>&1`
ret=$?
fi
if [ $ret -eq 0 ] && [ -x "$tar" ]; then
echo "tar=$tar"
echo "version:"
$tar --version
ret=$?
fi
if [ $ret -eq 0 ]; then
(exit 0)
else
echo "No suitable tar program found."
exit 1
fi
# Try to find a suitable make
# If the MAKE environment var is set, use that.
# otherwise, try to find gmake, and then make.
# If no make is found, then just execute the necessary commands.
# XXX For some reason, make is building all the docs every time. This
# is an annoying source of bugs. Figure out why this happens.
MAKE=NOMAKE
if [ "x$MAKE" = "x" ]; then
make=`which gmake 2>&1`
if [ $? -eq 0 ] && [ -x "$make" ]; then
(exit 0)
else
make=`which make 2>&1`
if [ $? -eq 0 ] && [ -x "$make" ]; then
(exit 0)
else
make=NOMAKE
fi
fi
else
make="$MAKE"
fi
if [ -x "$make" ]; then
(exit 0)
else
# echo "Installing without make. This may fail." >&2
make=NOMAKE
fi
# If there's no bash, then don't even try to clean
if [ -x "/bin/bash" ]; then
(exit 0)
else
clean="no"
fi
node_version=`"$node" --version 2>&1`
ret=$?
if [ $ret -ne 0 ]; then
echo "You need node to run this program." >&2
echo "node --version reports: $node_version" >&2
echo "with exit code = $ret" >&2
echo "Please install node before continuing." >&2
exit $ret
fi
t="${npm_install}"
if [ -z "$t" ]; then
# switch based on node version.
# note that we can only use strict sh-compatible patterns here.
case $node_version in
0.[01234567].* | v0.[01234567].*)
echo "You are using an outdated and unsupported version of" >&2
echo "node ($node_version). Please update node and try again." >&2
exit 99
;;
*)
echo "install npm@latest"
t="latest"
;;
esac
fi
# need to echo "" after, because Posix sed doesn't treat EOF
# as an implied end of line.
url=`(curl -SsL https://registry.npmjs.org/npm/$t; echo "") \
| sed -e 's/^.*tarball":"//' \
| sed -e 's/".*$//'`
ret=$?
if [ "x$url" = "x" ]; then
ret=125
# try without the -e arg to sed.
url=`(curl -SsL https://registry.npmjs.org/npm/$t; echo "") \
| sed 's/^.*tarball":"//' \
| sed 's/".*$//'`
ret=$?
if [ "x$url" = "x" ]; then
ret=125
fi
fi
if [ $ret -ne 0 ]; then
echo "Failed to get tarball url for npm/$t" >&2
exit $ret
fi
echo "fetching: $url" >&2
cd "$TMP" \
&& curl -SsL "$url" \
| $tar -xzf - \
&& cd "$TMP"/* \
&& (ver=`"$node" bin/read-package-json.js package.json version`
isnpm10=0
if [ $ret -eq 0 ]; then
if [ -d node_modules ]; then
if "$node" node_modules/semver/bin/semver -v "$ver" -r "1"
then
isnpm10=1
fi
else
if "$node" bin/semver -v "$ver" -r ">=1.0"; then
isnpm10=1
fi
fi
fi
ret=0
if [ $isnpm10 -eq 1 ] && [ -f "scripts/clean-old.sh" ]; then
if [ "x$skipclean" = "x" ]; then
(exit 0)
else
clean=no
fi
if [ "x$clean" = "xno" ] \
|| [ "x$clean" = "xn" ]; then
echo "Skipping 0.x cruft clean" >&2
ret=0
elif [ "x$clean" = "xy" ] || [ "x$clean" = "xyes" ]; then
NODE="$node" /bin/bash "scripts/clean-old.sh" "-y"
ret=$?
else
NODE="$node" /bin/bash "scripts/clean-old.sh" </dev/tty
ret=$?
fi
fi
if [ $ret -ne 0 ]; then
echo "Aborted 0.x cleanup. Exiting." >&2
exit $ret
fi) \
&& (if [ "x$configures" = "x" ]; then
(exit 0)
else
echo "./configure $configures"
echo "$configures" > npmrc
fi) \
&& (if [ "$make" = "NOMAKE" ]; then
(exit 0)
elif "$make" uninstall install; then
(exit 0)
else
make="NOMAKE"
fi
if [ "$make" = "NOMAKE" ]; then
"$node" cli.js rm npm -gf
"$node" cli.js install -gf
fi) \
&& cd "$BACK" \
&& rm -rf "$TMP" \
&& echo "It worked"
ret=$?
if [ $ret -ne 0 ]; then
echo "It failed" >&2
fi
exit $ret
================================================
FILE: examples/release.sh
================================================
#!/bin/bash
# script for creating a zip and tarball for inclusion in node
unset CDPATH
set -e
rm -rf release *.tgz || true
mkdir release
node ./cli.js pack --loglevel error >/dev/null
mv *.tgz release
cd release
tar xzf *.tgz
mkdir node_modules
mv package node_modules/npm
# make the zip for windows users
cp node_modules/npm/bin/*.cmd .
zipname=npm-$(node ../cli.js -v).zip
zip -q -9 -r -X "$zipname" *.cmd node_modules
# make the tar for node's deps
cd node_modules
tarname=npm-$(node ../../cli.js -v).tgz
tar czf "$tarname" npm
cd ..
mv "node_modules/$tarname" .
rm -rf *.cmd
rm -rf node_modules
echo "release/$tarname"
echo "release/$zipname"
================================================
FILE: examples/relocate.sh
================================================
#!/bin/bash
# Change the cli shebang to point at the specified node
# Useful for when the program is moved around after install.
# Also used by the default 'make install' in node to point
# npm at the newly installed node, rather than the first one
# in the PATH, which would be the default otherwise.
# bash /path/to/npm/scripts/relocate.sh $nodepath
# If $nodepath is blank, then it'll use /usr/bin/env
dir="$(dirname "$(dirname "$0")")"
cli="$dir"/bin/npm-cli.js
tmp="$cli".tmp
node="$1"
if [ "x$node" = "x" ]; then
node="/usr/bin/env node"
fi
node="#!$node"
sed -e 1d "$cli" > "$tmp"
echo "$node" > "$cli"
cat "$tmp" >> "$cli"
rm "$tmp"
chmod ogu+x $cli
================================================
FILE: examples/test.sh
================================================
#!/usr/bin/env bash
set -e
function usage {
cat <<-EOF
USAGE
$0 [-dgGhv] [-f focus-string] [-s seed]
OPTIONS
-h print this message
-b run make under scan-build static analyzer
-d run tests in a debugger (either lldb or gdb)
-g run tests with valgrind's memcheck tool
-G run tests with valgrind's memcheck tool, including a full leak check
-v run tests with verbose output
-f run only tests whose description contain the given string
-s set the seed used to control random behavior
-z pipe tests' stderr to \`dot(1)\` to render an SVG log
EOF
}
profile=
leak_check=no
mode=normal
verbose=
args=()
target=tests
export BUILDTYPE=Test
cmd="out/${BUILDTYPE}/${target}"
run_scan_build=
if [ "$(uname -s)" == "Darwin" ]; then
export LINK="clang++ -fsanitize=address"
fi
while getopts "bdf:s:gGhpvS" option; do
case ${option} in
h)
usage
exit
;;
d)
mode=debug
;;
g)
mode=valgrind
;;
G)
mode=valgrind
leak_check=full
;;
p)
profile=true
;;
f)
args+=("--only=${OPTARG}")
;;
v)
verbose=true
;;
s)
export TREE_SITTER_SEED=${OPTARG}
;;
S)
mode=SVG
;;
b)
run_scan_build=true
;;
esac
done
if [[ -n $verbose ]]; then
args+=("--reporter=spec")
else
args+=("--reporter=singleline")
fi
if [[ -n "$run_scan_build" ]]; then
. script/util/scan-build.sh
scan_build make -j2 $target
else
make -j2 $target
fi
args=${args:-""}
if [[ -n $profile ]]; then
export CPUPROFILE=/tmp/${target}-$(date '+%s').prof
fi
case ${mode} in
valgrind)
valgrind \
--suppressions=./script/util/valgrind.supp \
--dsymutil=yes \
--leak-check=${leak_check} \
$cmd "${args[@]}" 2>&1 | \
grep --color -E '\w+_tests?.cc:\d+|$'
;;
debug)
if which -s lldb; then
lldb $cmd -- "${args[@]}"
elif which -s gdb; then
gdb $cmd -- "${args[@]}"
else
echo "No debugger found"
exit 1
fi
;;
SVG)
echo "<!DOCTYPE html><style>svg { width: 100%; margin-bottom: 20px; }</style>" > index.html
$cmd "${args[@]}" 2> >(grep -v 'Assertion failed' | dot -Tsvg >> index.html)
echo "Wrote index.html"
;;
normal)
time $cmd "${args[@]}"
;;
esac
if [[ -n $profile ]]; then
pprof $cmd $CPUPROFILE
fi
================================================
FILE: examples/update-authors.sh
================================================
#!/bin/sh
git log --reverse --format='%aN <%aE>' | perl -wnE '
BEGIN {
say "# Authors sorted by whether or not they\x27re me";
}
print $seen{$_} = $_ unless $seen{$_}
' > AUTHORS
================================================
FILE: go.mod
================================================
module github.com/tree-sitter/tree-sitter-bash
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-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d h1:fcYCvoXdcP1uRQYXqJHRy6Hec+uKScQdKVtMwK9JeCI=
github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d/go.mod h1:T1nShQ4v5AJtozZ8YyAS4uzUtDAJj/iv4YfwXSbUHzg=
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
================================================
/**
* @file Bash grammar for tree-sitter
* @author Max Brunsfeld <maxbrunsfeld@gmail.com>
* @author Amaan Qureshi <amaanq12@gmail.com>
* @license MIT
*/
/// <reference types="tree-sitter-cli/dsl" />
// @ts-check
const SPECIAL_CHARACTERS = [
'\'', '"',
'<', '>',
'{', '}',
'\\[', '\\]',
'(', ')',
'`', '$',
'|', '&', ';',
'\\',
'\\s',
];
const PREC = {
UPDATE: 0,
ASSIGN: 1,
TERNARY: 2,
LOGICAL_OR: 3,
LOGICAL_AND: 4,
BITWISE_OR: 5,
BITWISE_XOR: 6,
BITWISE_AND: 7,
EQUALITY: 8,
COMPARE: 9,
TEST: 10,
UNARY: 11,
SHIFT: 12,
ADD: 13,
MULTIPLY: 14,
EXPONENT: 15,
NEGATE: 16,
PREFIX: 17,
POSTFIX: 18,
};
module.exports = grammar({
name: 'bash',
conflicts: $ => [
[$._expression, $.command_name],
[$.command, $.variable_assignments],
[$.redirected_statement, $.command],
[$.redirected_statement, $.command_substitution],
[$.function_definition, $.command_name],
[$.pipeline],
],
inline: $ => [
$._statement,
$._terminator,
$._literal,
$._terminated_statement,
$._primary_expression,
$._simple_variable_name,
$._multiline_variable_name,
$._special_variable_name,
$._c_word,
$._statement_not_subshell,
$._redirect,
],
externals: $ => [
$.heredoc_start,
$.simple_heredoc_body,
$._heredoc_body_beginning,
$.heredoc_content,
$.heredoc_end,
$.file_descriptor,
$._empty_value,
$._concat,
$.variable_name, // Variable name followed by an operator like '=' or '+='
$.test_operator,
$.regex,
$._regex_no_slash,
$._regex_no_space,
$._expansion_word,
$.extglob_pattern,
$._bare_dollar,
$._brace_start,
$._immediate_double_hash,
$._external_expansion_sym_hash,
$._external_expansion_sym_bang,
$._external_expansion_sym_equal,
'}',
']',
'<<',
'<<-',
/\n/,
'(',
'esac',
$.__error_recovery,
],
extras: $ => [
$.comment,
/\s/,
/\\\r?\n/,
/\\( |\t|\v|\f)/,
],
supertypes: $ => [
$._statement,
$._expression,
$._primary_expression,
],
word: $ => $.word,
rules: {
program: $ => optional($._statements),
_statements: $ => prec(1, seq(
repeat(seq(
$._statement,
$._terminator,
)),
$._statement,
optional($._terminator),
)),
_terminated_statement: $ => repeat1(seq(
$._statement,
$._terminator,
)),
// Statements
_statement: $ => choice(
$._statement_not_subshell,
$.subshell,
),
_statement_not_subshell: $ => choice(
$.redirected_statement,
$.variable_assignment,
$.variable_assignments,
$.command,
$.declaration_command,
$.unset_command,
$.test_command,
$.negated_command,
$.for_statement,
$.c_style_for_statement,
$.while_statement,
$.if_statement,
$.case_statement,
$.pipeline,
$.list,
$.compound_statement,
$.function_definition,
),
_statement_not_pipeline: $ => prec(1, choice(
$.redirected_statement,
$.variable_assignment,
$.variable_assignments,
$.command,
$.declaration_command,
$.unset_command,
$.test_command,
$.negated_command,
$.for_statement,
$.c_style_for_statement,
$.while_statement,
$.if_statement,
$.case_statement,
$.list,
$.compound_statement,
$.function_definition,
$.subshell,
)),
redirected_statement: $ => prec.dynamic(-1, prec.right(-1, choice(
seq(
field('body', $._statement),
field('redirect', choice(
repeat1(choice(
$.file_redirect,
$.heredoc_redirect,
)),
)),
),
seq(
field('body', choice($.if_statement, $.while_statement)),
$.herestring_redirect,
),
field('redirect', repeat1($._redirect)),
$.herestring_redirect,
))),
for_statement: $ => seq(
choice('for', 'select'),
field('variable', $._simple_variable_name),
optional(seq(
'in',
field('value', repeat1($._literal)),
)),
$._terminator,
field('body', $.do_group),
),
c_style_for_statement: $ => seq(
'for',
'((',
choice($._for_body),
'))',
optional(';'),
field('body', choice(
$.do_group,
$.compound_statement,
)),
),
_for_body: $ => seq(
field('initializer', commaSep($._c_expression)),
$._c_terminator,
field('condition', commaSep($._c_expression)),
$._c_terminator,
field('update', commaSep($._c_expression)),
),
_c_expression: $ => choice(
$._c_expression_not_assignment,
alias($._c_variable_assignment, $.variable_assignment),
),
_c_expression_not_assignment: $ => choice(
$._c_word,
$.simple_expansion,
$.expansion,
$.number,
$.string,
alias($._c_unary_expression, $.unary_expression),
alias($._c_binary_expression, $.binary_expression),
alias($._c_postfix_expression, $.postfix_expression),
alias($._c_parenthesized_expression, $.parenthesized_expression),
$.command_substitution,
),
_c_variable_assignment: $ => seq(
field('name', alias($._c_word, $.variable_name)),
'=',
field('value', $._c_expression),
),
_c_unary_expression: $ => prec(PREC.PREFIX, seq(
field('operator', choice('++', '--')),
$._c_expression_not_assignment,
)),
_c_binary_expression: $ => {
const table = [
[choice('+=', '-=', '*=', '/=', '%=', '**=', '<<=', '>>=', '&=', '^=', '|='), PREC.UPDATE],
[choice('||', '-o'), PREC.LOGICAL_OR],
[choice('&&', '-a'), PREC.LOGICAL_AND],
['|', PREC.BITWISE_OR],
['^', PREC.BITWISE_XOR],
['&', PREC.BITWISE_AND],
[choice('==', '!='), PREC.EQUALITY],
[choice('<', '>', '<=', '>='), PREC.COMPARE],
[choice('<<', '>>'), PREC.SHIFT],
[choice('+', '-'), PREC.ADD],
[choice('*', '/', '%'), PREC.MULTIPLY],
['**', PREC.EXPONENT],
];
return choice(...table.map(([operator, precedence]) => {
// @ts-ignore
return prec[operator === '**' ? 'right' : 'left'](precedence, seq(
field('left', $._c_expression_not_assignment),
// @ts-ignore
field('operator', operator),
field('right', $._c_expression_not_assignment),
));
}));
},
_c_postfix_expression: $ => prec(PREC.POSTFIX, seq(
$._c_expression_not_assignment,
field('operator', choice('++', '--')),
)),
_c_parenthesized_expression: $ => seq(
'(',
commaSep1($._c_expression),
')',
),
_c_word: $ => alias(/[a-zA-Z_][a-zA-Z0-9_]*/, $.word),
while_statement: $ => seq(
choice('while', 'until'),
field('condition', $._terminated_statement),
field('body', $.do_group),
),
do_group: $ => seq(
'do',
optional($._terminated_statement),
'done',
),
if_statement: $ => seq(
'if',
field('condition', $._terminated_statement),
'then',
optional($._terminated_statement),
repeat($.elif_clause),
optional($.else_clause),
'fi',
),
elif_clause: $ => seq(
'elif',
$._terminated_statement,
'then',
optional($._terminated_statement),
),
else_clause: $ => seq(
'else',
optional($._terminated_statement),
),
case_statement: $ => seq(
'case',
field('value', $._literal),
optional($._terminator),
'in',
optional($._terminator),
optional(seq(
repeat($.case_item),
alias($.last_case_item, $.case_item),
)),
'esac',
),
case_item: $ => seq(
choice(
seq(
optional('('),
field('value', choice($._literal, $._extglob_blob)),
repeat(seq('|', field('value', choice($._literal, $._extglob_blob)))),
')',
),
),
optional($._statements),
prec(1, choice(
field('termination', ';;'),
field('fallthrough', choice(';&', ';;&')),
)),
),
last_case_item: $ => seq(
optional('('),
field('value', choice($._literal, $._extglob_blob)),
repeat(seq('|', field('value', choice($._literal, $._extglob_blob)))),
')',
optional($._statements),
optional(prec(1, ';;')),
),
function_definition: $ => prec.right(seq(
choice(
seq(
'function',
field('name', $.word),
optional(seq('(', ')')),
),
seq(
field('name', $.word),
'(', ')',
),
),
field(
'body',
choice(
$.compound_statement,
$.subshell,
$.test_command,
$.if_statement,
),
),
field('redirect', optional($._redirect)),
)),
compound_statement: $ => choice(
seq(
'{',
optional($._terminated_statement),
token(prec(-1, '}')),
),
seq(
'((',
repeat(
seq(
$._arithmetic_expression,
',',
),
),
$._arithmetic_expression,
'))'),
),
subshell: $ => seq(
'(',
$._statements,
')',
),
pipeline: $ => prec.right(seq(
$._statement_not_pipeline,
repeat1(seq(
choice('|', '|&'),
$._statement_not_pipeline,
)),
)),
list: $ => prec.left(-1, seq(
$._statement,
choice('&&', '||'),
$._statement,
)),
// Commands
negated_command: $ => seq(
'!',
choice(
prec(2, $.command),
prec(1, $.variable_assignment),
$.test_command,
$.subshell,
),
),
test_command: $ => seq(
choice(
seq('[', optional(choice($._expression, $.redirected_statement)), ']'),
seq(
'[[',
choice(
$._expression,
alias($._test_command_binary_expression, $.binary_expression),
),
']]',
),
),
),
_test_command_binary_expression: $ => prec(PREC.ASSIGN,
seq(
field('left', $._expression),
field('operator', '='),
field('right', alias($._regex_no_space, $.regex)),
),
),
declaration_command: $ => prec.left(seq(
choice('declare', 'typeset', 'export', 'readonly', 'local'),
repeat(choice(
$._literal,
$._simple_variable_name,
$.variable_assignment,
)),
)),
unset_command: $ => prec.left(seq(
choice('unset', 'unsetenv'),
repeat(choice(
$._literal,
$._simple_variable_name,
)),
)),
command: $ => prec.left(seq(
repeat(choice(
$.variable_assignment,
field('redirect', $._redirect),
)),
field('name', $.command_name),
choice(
repeat(choice(
field('argument', $._literal),
field('argument', alias($._bare_dollar, '$')),
field('argument', seq(
choice('=~', '=='),
choice($._literal, $.regex),
)),
field('redirect', $.herestring_redirect),
)),
$.subshell,
),
)),
command_name: $ => $._literal,
variable_assignment: $ => seq(
field('name', choice(
$.variable_name,
$.subscript,
)),
choice(
'=',
'+=',
),
field('value', choice(
$._literal,
$.array,
$._empty_value,
alias($._comment_word, $.word),
)),
),
variable_assignments: $ => seq($.variable_assignment, repeat1($.variable_assignment)),
subscript: $ => seq(
field('name', $.variable_name),
'[',
field('index', choice($._literal, $.binary_expression, $.unary_expression, $.compound_statement, $.subshell)),
optional($._concat),
']',
optional($._concat),
),
file_redirect: $ => prec.left(seq(
field('descriptor', optional($.file_descriptor)),
choice(
seq(
choice('<', '>', '>>', '&>', '&>>', '<&', '>&', '>|'),
field('destination', repeat1($._literal)),
),
seq(
choice('<&-', '>&-'), // close file descriptor
optional(field('destination', $._literal)),
),
),
)),
heredoc_redirect: $ => seq(
field('descriptor', optional($.file_descriptor)),
choice('<<', '<<-'),
$.heredoc_start,
optional(choice(
alias($._heredoc_pipeline, $.pipeline),
seq(
field('redirect', repeat1($._redirect)),
optional($._heredoc_expression),
),
$._heredoc_expression,
$._heredoc_command,
)),
/\n/,
choice($._heredoc_body, $._simple_heredoc_body),
),
_heredoc_pipeline: $ => seq(
choice('|', '|&'),
$._statement,
),
_heredoc_expression: $ => seq(
field('operator', choice('||', '&&')),
field('right', $._statement),
),
_heredoc_command: $ => repeat1(field('argument', $._literal)),
_heredoc_body: $ => seq(
$.heredoc_body,
$.heredoc_end,
),
heredoc_body: $ => seq(
$._heredoc_body_beginning,
repeat(choice(
$.expansion,
$.simple_expansion,
$.command_substitution,
$.heredoc_content,
)),
),
_simple_heredoc_body: $ => seq(
alias($.simple_heredoc_body, $.heredoc_body),
$.heredoc_end,
),
herestring_redirect: $ => prec.left(seq(
field('descriptor', optional($.file_descriptor)),
'<<<',
$._literal,
)),
_redirect: $ => choice($.file_redirect, $.herestring_redirect),
// Expressions
_expression: $ => choice(
$._literal,
$.unary_expression,
$.ternary_expression,
$.binary_expression,
$.postfix_expression,
$.parenthesized_expression,
),
// https://tldp.org/LDP/abs/html/opprecedence.html
binary_expression: $ => {
const table = [
[choice('+=', '-=', '*=', '/=', '%=', '**=', '<<=', '>>=', '&=', '^=', '|='), PREC.UPDATE],
[choice('=', '=~'), PREC.ASSIGN],
['||', PREC.LOGICAL_OR],
['&&', PREC.LOGICAL_AND],
['|', PREC.BITWISE_OR],
['^', PREC.BITWISE_XOR],
['&', PREC.BITWISE_AND],
[choice('==', '!='), PREC.EQUALITY],
[choice('<', '>', '<=', '>='), PREC.COMPARE],
[$.test_operator, PREC.TEST],
[choice('<<', '>>'), PREC.SHIFT],
[choice('+', '-'), PREC.ADD],
[choice('*', '/', '%'), PREC.MULTIPLY],
['**', PREC.EXPONENT],
];
return choice(
choice(...table.map(([operator, precedence]) => {
// @ts-ignore
return prec[operator === '**' ? 'right' : 'left'](precedence, seq(
field('left', $._expression),
// @ts-ignore
field('operator', operator),
field('right', $._expression),
));
})),
prec(PREC.ASSIGN, seq(
field('left', $._expression),
field('operator', '=~'),
field('right', alias($._regex_no_space, $.regex)),
)),
prec(PREC.EQUALITY, seq(
field('left', $._expression),
field('operator', choice('==', '!=')),
field('right', $._extglob_blob),
)),
);
},
ternary_expression: $ => prec.left(PREC.TERNARY, seq(
field('condition', $._expression),
'?',
field('consequence', $._expression),
':',
field('alternative', $._expression),
)),
unary_expression: $ => choice(
prec(PREC.PREFIX, seq(
field('operator', tokenLiterals(1, '++', '--')),
$._expression,
)),
prec(PREC.UNARY, seq(
field('operator', tokenLiterals(1, '-', '+', '~')),
$._expression,
)),
prec.right(PREC.UNARY, seq(
field('operator', '!'),
$._expression,
)),
prec.right(PREC.TEST, seq(
field('operator', $.test_operator),
$._expression,
)),
),
postfix_expression: $ => prec(PREC.POSTFIX, seq(
$._expression,
field('operator', choice('++', '--')),
)),
parenthesized_expression: $ => seq(
'(',
$._expression,
')',
),
// Literals
_literal: $ => choice(
$.concatenation,
$._primary_expression,
alias(prec(-2, repeat1($._special_character)), $.word),
),
_primary_expression: $ => choice(
$.word,
alias($.test_operator, $.word),
$.string,
$.raw_string,
$.translated_string,
$.ansi_c_string,
$.number,
$.expansion,
$.simple_expansion,
$.command_substitution,
$.process_substitution,
$.arithmetic_expansion,
$.brace_expression,
),
arithmetic_expansion: $ => choice(
seq('$((', commaSep1($._arithmetic_expression), '))'),
seq('$[', $._arithmetic_expression, ']'),
),
brace_expression: $ => seq(
alias($._brace_start, '{'),
alias(token.immediate(/\d+/), $.number),
token.immediate('..'),
alias(token.immediate(/\d+/), $.number),
token.immediate('}'),
),
_arithmetic_expression: $ => prec(1, choice(
$._arithmetic_literal,
alias($._arithmetic_unary_expression, $.unary_expression),
alias($._arithmetic_ternary_expression, $.ternary_expression),
alias($._arithmetic_binary_expression, $.binary_expression),
alias($._arithmetic_postfix_expression, $.postfix_expression),
alias($._arithmetic_parenthesized_expression, $.parenthesized_expression),
$.command_substitution,
)),
_arithmetic_literal: $ => prec(1, choice(
$.number,
$.subscript,
$.simple_expansion,
$.expansion,
$._simple_variable_name,
$.variable_name,
$.string,
$.raw_string,
)),
_arithmetic_binary_expression: $ => {
const table = [
[choice('+=', '-=', '*=', '/=', '%=', '**=', '<<=', '>>=', '&=', '^=', '|='), PREC.UPDATE],
[choice('=', '=~'), PREC.ASSIGN],
['||', PREC.LOGICAL_OR],
['&&', PREC.LOGICAL_AND],
['|', PREC.BITWISE_OR],
['^', PREC.BITWISE_XOR],
['&', PREC.BITWISE_AND],
[choice('==', '!='), PREC.EQUALITY],
[choice('<', '>', '<=', '>='), PREC.COMPARE],
[choice('<<', '>>'), PREC.SHIFT],
[choice('+', '-'), PREC.ADD],
[choice('*', '/', '%'), PREC.MULTIPLY],
['**', PREC.EXPONENT],
];
return choice(...table.map(([operator, precedence]) => {
// @ts-ignore
return prec.left(precedence, seq(
field('left', $._arithmetic_expression),
// @ts-ignore
field('operator', operator),
field('right', $._arithmetic_expression),
));
}));
},
_arithmetic_ternary_expression: $ => prec.left(PREC.TERNARY, seq(
field('condition', $._arithmetic_expression),
'?',
field('consequence', $._arithmetic_expression),
':',
field('alternative', $._arithmetic_expression),
)),
_arithmetic_unary_expression: $ => choice(
prec(PREC.PREFIX, seq(
field('operator', tokenLiterals(1, '++', '--')),
$._arithmetic_expression,
)),
prec(PREC.UNARY, seq(
field('operator', tokenLiterals(1, '-', '+', '~')),
$._arithmetic_expression,
)),
prec.right(PREC.UNARY, seq(
field('operator', '!'),
$._arithmetic_expression,
)),
),
_arithmetic_postfix_expression: $ => prec(PREC.POSTFIX, seq(
$._arithmetic_expression,
field('operator', choice('++', '--')),
)),
_arithmetic_parenthesized_expression: $ => seq(
'(',
$._arithmetic_expression,
')',
),
concatenation: $ => prec(-1, seq(
choice(
$._primary_expression,
alias($._special_character, $.word),
),
repeat1(seq(
choice($._concat, alias(/`\s*`/, '``')),
choice(
$._primary_expression,
alias($._special_character, $.word),
alias($._comment_word, $.word),
alias($._bare_dollar, '$'),
),
)),
optional(seq($._concat, '$')),
)),
_special_character: _ => token(prec(-1, choice('{', '}', '[', ']'))),
string: $ => seq(
'"',
repeat(seq(
choice(
seq(optional('$'), $.string_content),
$.expansion,
$.simple_expansion,
$.command_substitution,
$.arithmetic_expansion,
),
optional($._concat),
)),
optional('$'),
'"',
),
string_content: _ => token(prec(-1, /([^"`$\\\r\n]|\\(.|\r?\n))+/)),
translated_string: $ => seq('$', $.string),
array: $ => seq(
'(',
repeat($._literal),
')',
),
raw_string: _ => /'[^']*'/,
ansi_c_string: _ => /\$'([^']|\\')*'/,
number: $ => choice(
/-?(0x)?[0-9]+(#[0-9A-Za-z@_]+)?/,
// the base can be an expansion or command substitution
seq(/-?(0x)?[0-9]+#/, choice($.expansion, $.command_substitution)),
),
simple_expansion: $ => seq(
'$',
choice(
$._simple_variable_name,
$._multiline_variable_name,
$._special_variable_name,
$.variable_name,
alias('!', $.special_variable_name),
alias('#', $.special_variable_name),
),
),
string_expansion: $ => seq('$', $.string),
expansion: $ => seq(
'${',
optional($._expansion_body),
'}',
),
_expansion_body: $ => choice(
// ${!##} ${!#}
repeat1(field(
'operator',
choice(
alias($._external_expansion_sym_hash, '#'),
alias($._external_expansion_sym_bang, '!'),
alias($._external_expansion_sym_equal, '='),
),
)),
seq(
optional(field('operator', token.immediate('!'))),
choice($.variable_name, $._simple_variable_name, $._special_variable_name, $.subscript),
choice(
$._expansion_expression,
$._expansion_regex,
$._expansion_regex_replacement,
$._expansion_regex_removal,
$._expansion_max_length,
$._expansion_operator,
),
),
seq(
field('operator', token.immediate('!')),
choice($._simple_variable_name, $.variable_name),
optional(field('operator', choice(
token.immediate('@'),
token.immediate('*'),
))),
),
seq(
optional(field('operator', immediateLiterals('#', '!', '='))),
choice(
$.subscript,
$._simple_variable_name,
$._special_variable_name,
$.command_substitution,
),
repeat(field(
'operator',
choice(
alias($._external_expansion_sym_hash, '#'),
alias($._external_expansion_sym_bang, '!'),
alias($._external_expansion_sym_equal, '='),
),
)),
),
),
_expansion_expression: $ => prec(1, seq(
field('operator', immediateLiterals('=', ':=', '-', ':-', '+', ':+', '?', ':?')),
optional(seq(
choice(
alias($._concatenation_in_expansion, $.concatenation),
$.command_substitution,
$.word,
$.expansion,
$.simple_expansion,
$.array,
$.string,
$.raw_string,
$.ansi_c_string,
alias($._expansion_word, $.word),
),
)),
)),
_expansion_regex: $ => seq(
field('operator', choice('#', alias($._immediate_double_hash, '##'), '%', '%%')),
repeat(choice(
$.regex,
alias(')', $.regex),
$.string,
$.raw_string,
alias(/\s+/, $.regex),
)),
),
_expansion_regex_replacement: $ => seq(
field('operator', choice('/', '//', '/#', '/%')),
optional(choice(
alias($._regex_no_slash, $.regex),
$.string,
$.command_substitution,
seq($.string, alias($._regex_no_slash, $.regex)),
)),
// This can be elided
optional(seq(
field('operator', '/'),
optional(seq(
choice(
$._primary_expression,
alias(prec(-2, repeat1($._special_character)), $.word),
seq($.command_substitution, alias($._expansion_word, $.word)),
alias($._expansion_word, $.word),
alias($._concatenation_in_expansion, $.concatenation),
$.array,
),
field('operator', optional('/')),
)),
)),
),
_expansion_regex_removal: $ => seq(
field('operator', choice(',', ',,', '^', '^^')),
optional($.regex),
),
_expansion_max_length: $ => seq(
field('operator', ':'),
optional(choice(
$._simple_variable_name,
$.number,
$.arithmetic_expansion,
$.expansion,
$.parenthesized_expression,
$.command_substitution,
alias($._expansion_max_length_binary_expression, $.binary_expression),
/\n/,
)),
optional(seq(
field('operator', ':'),
optional($.simple_expansion),
optional(choice(
$._simple_variable_name,
$.number,
$.arithmetic_expansion,
$.expansion,
$.parenthesized_expression,
$.command_substitution,
alias($._expansion_max_length_binary_expression, $.binary_expression),
/\n/,
)),
)),
),
_expansion_max_length_expression: $ => choice(
$._simple_variable_name,
$.number,
$.expansion,
alias($._expansion_max_length_binary_expression, $.binary_expression),
),
_expansion_max_length_binary_expression: $ => {
const table = [
[choice('+', '-'), PREC.ADD],
[choice('*', '/', '%'), PREC.MULTIPLY],
];
return choice(...table.map(([operator, precedence]) => {
// @ts-ignore
return prec.left(precedence, seq(
$._expansion_max_length_expression,
// @ts-ignore
field('operator', operator),
$._expansion_max_length_expression,
));
}));
},
_expansion_operator: _ => seq(
field('operator', token.immediate('@')),
field('operator', immediateLiterals('U', 'u', 'L', 'Q', 'E', 'P', 'A', 'K', 'a', 'k')),
),
_concatenation_in_expansion: $ => prec(-2, seq(
choice(
$.word,
$.variable_name,
$.simple_expansion,
$.expansion,
$.string,
$.raw_string,
$.ansi_c_string,
$.command_substitution,
alias($._expansion_word, $.word),
$.array,
$.process_substitution,
),
repeat1(seq(
choice($._concat, alias(/`\s*`/, '``')),
choice(
$.word,
$.variable_name,
$.simple_expansion,
$.expansion,
$.string,
$.raw_string,
$.ansi_c_string,
$.command_substitution,
alias($._expansion_word, $.word),
$.array,
$.process_substitution,
),
)),
)),
command_substitution: $ => choice(
seq('$(', $._statements, ')'),
seq('$(', field('redirect', $.file_redirect), ')'),
prec(1, seq('`', $._statements, '`')),
seq('$`', $._statements, '`'),
),
process_substitution: $ => seq(
choice('<(', '>('),
$._statements,
')',
),
_extglob_blob: $ => choice(
$.extglob_pattern,
seq(
$.extglob_pattern,
choice($.string, $.expansion, $.command_substitution),
optional($.extglob_pattern),
),
),
comment: _ => token(prec(-10, /#.*/)),
_comment_word: _ => token(prec(-8, seq(
choice(
noneOf(...SPECIAL_CHARACTERS),
seq('\\', noneOf('\\s')),
),
repeat(choice(
noneOf(...SPECIAL_CHARACTERS),
seq('\\', noneOf('\\s')),
'\\ ',
)),
))),
_simple_variable_name: $ => alias(/\w+/, $.variable_name),
_multiline_variable_name: $ => alias(
token(prec(-1, /(\w|\\\r?\n)+/)),
$.variable_name,
),
_special_variable_name: $ => alias(choice('*', '@', '?', '!', '#', '-', '$', '_'), $.special_variable_name),
word: _ => token(seq(
choice(
noneOf('#', ...SPECIAL_CHARACTERS),
seq('\\', noneOf('\\s')),
),
repeat(choice(
noneOf(...SPECIAL_CHARACTERS),
seq('\\', noneOf('\\s')),
'\\ ',
)),
)),
_c_terminator: _ => choice(';', /\n/, '&'),
_terminator: _ => choice(';', ';;', /\n/, '&'),
},
});
/**
* Returns a regular expression that matches any character except the ones
* provided.
*
* @param {...string} characters
*
* @returns {RegExp}
*/
function noneOf(...characters) {
const negatedString = characters.map(c => c == '\\' ? '\\\\' : c).join('');
return new RegExp('[^' + negatedString + ']');
}
/**
* 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));
}
/**
* Creates a rule to match one or more of the rules separated by a comma
*
* @param {RuleOrLiteral} rule
*
* @returns {SeqRule}
*/
function commaSep1(rule) {
return seq(rule, repeat(seq(',', rule)));
}
/**
*
* Turns a list of rules into a choice of immediate rule
*
* @param {(RegExp | string)[]} literals
*
* @returns {ChoiceRule}
*/
function immediateLiterals(...literals) {
return choice(...literals.map(l => token.immediate(l)));
}
/**
*
* Turns a list of rules into a choice of aliased token rules
*
* @param {number} precedence
*
* @param {(RegExp | string)[]} literals
*
* @returns {ChoiceRule}
*/
function tokenLiterals(precedence, ...literals) {
return choice(...literals.map(l => token(prec(precedence, l))));
}
================================================
FILE: package.json
================================================
{
"name": "tree-sitter-bash",
"version": "0.25.1",
"description": "Bash grammar for tree-sitter",
"repository": "https://github.com/tree-sitter/tree-sitter-bash",
"license": "MIT",
"author": {
"name": "Max Brunsfeld",
"email": "maxbrunsfeld@gmail.com"
},
"maintainers": [
{
"name": "Amaan Qureshi",
"email": "amaanq12@gmail.com"
}
],
"main": "bindings/node",
"types": "bindings/node",
"keywords": [
"incremental",
"parsing",
"tree-sitter",
"bash"
],
"files": [
"grammar.js",
"tree-sitter.json",
"binding.gyp",
"prebuilds/**",
"bindings/node/*",
"queries/*",
"src/**",
"*.wasm"
],
"dependencies": {
"node-addon-api": "^8.2.1",
"node-gyp-build": "^4.8.2"
},
"devDependencies": {
"eslint": "^9.12.0",
"eslint-config-treesitter": "^1.0.2",
"tree-sitter-cli": "^0.25.6",
"prebuildify": "^6.0.1"
},
"peerDependencies": {
"tree-sitter": "^0.25.0"
},
"peerDependenciesMeta": {
"tree-sitter": {
"optional": true
}
},
"scripts": {
"install": "node-gyp-build",
"lint": "eslint grammar.js",
"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-bash"
description = "Bash grammar for tree-sitter"
version = "0.25.1"
keywords = ["incremental", "parsing", "tree-sitter", "bash"]
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.10"
license.text = "MIT"
readme = "README.md"
[project.urls]
Homepage = "https://github.com/tree-sitter/tree-sitter-bash"
[project.optional-dependencies]
core = ["tree-sitter~=0.24"]
[tool.cibuildwheel]
build = "cp310-*"
build-frontend = "build"
================================================
FILE: queries/highlights.scm
================================================
[
(string)
(raw_string)
(heredoc_body)
(heredoc_start)
] @string
(command_name) @function
(variable_name) @property
[
"case"
"do"
"done"
"elif"
"else"
"esac"
"export"
"fi"
"for"
"function"
"if"
"in"
"select"
"then"
"unset"
"until"
"while"
] @keyword
(comment) @comment
(function_definition name: (word) @function)
(file_descriptor) @number
[
(command_substitution)
(process_substitution)
(expansion)
]@embedded
[
"$"
"&&"
">"
">>"
"<"
"|"
] @operator
(
(command (_) @constant)
(#match? @constant "^-")
)
================================================
FILE: script/known-failures.txt
================================================
examples/bash-it/completion/available/bundler.completion.bash
examples/bash-it/completion/available/sqlmap.completion.bash
examples/bash-it/plugins/available/colors.plugin.bash
examples/bash-it/plugins/available/history-eternal.plugin.bash
examples/bash-it/themes/hawaii50/hawaii50.theme.bash
examples/bash/examples/functions/notify.bash
examples/bash/examples/shellmath/shellmath.sh
examples/bash/tests/arith-for.tests
examples/bash/tests/arith.tests
examples/bash/tests/array.tests
examples/bash/tests/assoc.tests
examples/bash/tests/braces.tests
examples/bash/tests/case.tests
examples/bash/tests/casemod.tests
examples/bash/tests/comsub-posix.tests
examples/bash/tests/comsub.tests
examples/bash/tests/comsub2.tests
examples/bash/tests/cond.tests
examples/bash/tests/errors.tests
examples/bash/tests/extglob.tests
examples/bash/tests/glob.tests
examples/bash/tests/heredoc.tests
examples/bash/tests/histexp.tests
examples/bash/tests/misc/dev-tcp.tests
examples/bash/tests/more-exp.tests
examples/bash/tests/new-exp.tests
examples/bash/tests/parser.tests
examples/bash/tests/posixexp.tests
examples/bash/tests/posixexp2.tests
examples/bash/tests/printf.tests
examples/bash/tests/quote.tests
examples/bash/tests/quotearray.tests
examples/bash/tests/redir.tests
examples/bash/tests/test.tests
examples/gentoo/app-misc/editor-wrapper/files/editor-wrapper-4.sh
examples/gentoo/dev-lang/rust/rust-1.74.1-r101.ebuild
examples/gentoo/dev-libs/libffi/libffi-3.5.1.ebuild
examples/gentoo/dev-libs/libffi/libffi-3.5.2.ebuild
examples/gentoo/dev-libs/libffi/libffi-9999.ebuild
examples/gentoo/eclass/rust.eclass
examples/gentoo/eclass/tests/toolchain-funcs.sh
examples/gentoo/eclass/texlive-common.eclass
examples/gentoo/eclass/toolchain-funcs.eclass
examples/gentoo/mail-client/thunderbird-bin/files/thunderbird-bin-r1.sh
examples/gentoo/mail-client/thunderbird/files/thunderbird-r1.sh
examples/gentoo/net-misc/asterisk/asterisk-18.26.2.ebuild
examples/gentoo/net-misc/asterisk/asterisk-18.26.4.ebuild
examples/gentoo/net-misc/asterisk/asterisk-20.15.2.ebuild
examples/gentoo/net-misc/asterisk/asterisk-21.10.2.ebuild
examples/gentoo/net-misc/asterisk/asterisk-22.5.2.ebuild
examples/gentoo/sys-apps/dcfldd/dcfldd-1.9.2-r1.ebuild
examples/gentoo/sys-apps/dcfldd/dcfldd-1.9.3.ebuild
examples/gentoo/sys-apps/less/files/lesspipe-r3.sh
examples/gentoo/sys-apps/less/files/lesspipe-r4.sh
examples/gentoo/sys-apps/locale-gen/locale-gen-3.8.ebuild
examples/gentoo/sys-apps/locale-gen/locale-gen-3.9-r1.ebuild
examples/gentoo/sys-apps/locale-gen/locale-gen-9999.ebuild
examples/gentoo/sys-fs/bcachefs-tools/bcachefs-tools-1.25.3.ebuild
examples/gentoo/sys-fs/bcachefs-tools/bcachefs-tools-1.31.5.ebuild
examples/gentoo/www-client/firefox-bin/files/firefox-bin-r1.sh
examples/gentoo/www-client/firefox/files/firefox-r1.sh
examples/wild-corpus/cloud/chef-bcpc/legacy_scripts/make_databag.sh
examples/wild-corpus/cloud/docker/hack/make.sh
examples/wild-corpus/cloud/kubernetes/build/common.sh
examples/wild-corpus/cloud/kubernetes/cluster/gce/config-default.sh
examples/wild-corpus/cloud/kubernetes/cluster/gce/config-test.sh
examples/wild-corpus/cloud/kubernetes/hack/benchmark-go.sh
examples/wild-corpus/cloud/kubernetes/hack/generate-bindata.sh
examples/wild-corpus/cloud/kubernetes/hack/lib/golang.sh
examples/wild-corpus/cloud/kubernetes/hack/lib/test.sh
examples/wild-corpus/cloud/kubernetes/hack/make-rules/test-integration.sh
examples/wild-corpus/cloud/kubernetes/hack/make-rules/test.sh
examples/wild-corpus/cloud/kubernetes/hack/make-rules/verify.sh
examples/wild-corpus/cloud/kubernetes/hack/update-api-reference-docs.sh
examples/wild-corpus/cloud/kubernetes/hack/update-codegen.sh
examples/wild-corpus/cloud/kubernetes/hack/update-federation-api-reference-docs.sh
examples/wild-corpus/cloud/kubernetes/hack/update-federation-swagger-spec.sh
examples/wild-corpus/cloud/kubernetes/hack/update-swagger-spec.sh
examples/wild-corpus/cloud/kubernetes/test/e2e_node/gubernator.sh
examples/wild-corpus/cloud/kubernetes/vendor/github.com/ugorji/go/codec/prebuild.sh
examples/wild-corpus/cloud/sandstorm/install.sh
examples/wild-corpus/cloud/sandstorm/make-bundle.sh
examples/wild-corpus/cloud/sandstorm/shell/run-dev.sh
examples/wild-corpus/distro/DietPi/PREP_SYSTEM_FOR_DIETPI.sh
examples/wild-corpus/distro/portage/bin/misc-functions.sh
examples/wild-corpus/distro/portage/bin/phase-helpers.sh
examples/wild-corpus/distro/woof-CE/initrd-progs/build.sh
examples/wild-corpus/distro/woof-CE/woof-code/rootfs-packages/network_wizard/usr/sbin/wag-profiles.sh
examples/wild-corpus/distro/woof-CE/woof-code/rootfs-skeleton/usr/local/petget/installpkg.sh
examples/wild-corpus/distro/woof-CE/woof-code/rootfs-skeleton/usr/local/petget/pkg_chooser.sh
examples/wild-corpus/esoteric/CmdlineGL/share/examples/FlightSim.sh
examples/wild-corpus/esoteric/CmdlineGL/share/examples/Robot.sh
examples/wild-corpus/esoteric/make-a-lisp-bash/core.sh
examples/wild-corpus/esoteric/shasm/shasm.sh
examples/wild-corpus/exp/shootout/timing.sh
examples/wild-corpus/freebsd-11.1/contrib/binutils/ld/emulparams/elf64bmip.sh
examples/wild-corpus/freebsd-11.1/contrib/binutils/ld/genscripts.sh
examples/wild-corpus/freebsd-11.1/contrib/gcc/scan-types.sh
examples/wild-corpus/freebsd-11.1/contrib/groff/src/preproc/eqn/neqn.sh
examples/wild-corpus/freebsd-11.1/contrib/groff/src/roff/nroff/nroff.sh
examples/wild-corpus/freebsd-11.1/contrib/netbsd-tests/bin/sh/t_arith.sh
examples/wild-corpus/freebsd-11.1/contrib/netbsd-tests/bin/sh/t_here.sh
examples/wild-corpus/freebsd-11.1/contrib/ntp/scripts/stats/summary.sh
examples/wild-corpus/freebsd-11.1/contrib/ntp/scripts/update-leap/update-leap.sh
examples/wild-corpus/freebsd-11.1/crypto/openssl/util/bat.sh
examples/wild-corpus/freebsd-11.1/gnu/usr.bin/binutils/ld/genscripts.sh
examples/wild-corpus/freebsd-11.1/share/examples/drivers/make_device_driver.sh
examples/wild-corpus/freebsd-11.1/share/examples/drivers/make_pseudo_driver.sh
examples/wild-corpus/freebsd-11.1/tools/tools/mctest/mctest_run.sh
examples/wild-corpus/freebsd-11.1/tools/tools/nanobsd/fill_pkg.sh
examples/wild-corpus/freebsd-11.1/tools/tools/shlib-compat/test/regress.sh
examples/wild-corpus/freebsd-11.1/tools/tools/sysbuild/sysbuild.sh
examples/wild-corpus/freebsd-11.1/tools/tools/sysdoc/sysdoc.sh
examples/wild-corpus/freebsd-11.1/usr.bin/apply/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/calendar/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/comm/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/file2c/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/join/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/jot/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/m4/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/man/man.sh
examples/wild-corpus/freebsd-11.1/usr.bin/ncal/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/printf/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/sed/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/shar/shar.sh
examples/wild-corpus/freebsd-11.1/usr.bin/tr/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/uudecode/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/uuencode/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.bin/xargs/tests/regress.sh
examples/wild-corpus/freebsd-11.1/usr.sbin/adduser/adduser.sh
examples/wild-corpus/freebsd-11.1/usr.sbin/freebsd-update/freebsd-update.sh
examples/wild-corpus/freebsd-11.1/usr.sbin/manctl/manctl.sh
examples/wild-corpus/freebsd-11.1/usr.sbin/portsnap/portsnap/portsnap.sh
examples/wild-corpus/git/contrib/examples/git-ls-remote.sh
examples/wild-corpus/git/contrib/examples/git-merge.sh
examples/wild-corpus/git/contrib/examples/git-pull.sh
examples/wild-corpus/git/git-filter-branch.sh
examples/wild-corpus/git/git-merge-octopus.sh
examples/wild-corpus/git/git-merge-resolve.sh
examples/wild-corpus/git/git-rebase--interactive.sh
examples/wild-corpus/git/git-submodule.sh
examples/wild-corpus/git/t/lib-pack.sh
examples/wild-corpus/git/t/t9500-gitweb-standalone-no-errors.sh
examples/wild-corpus/gnu/binutils-2.26/ld/emulparams/elf64bmip.sh
examples/wild-corpus/gnu/binutils-2.26/ld/genscripts.sh
examples/wild-corpus/gnu/coreutils-8.22/gnulib-tests/init.sh
examples/wild-corpus/gnu/coreutils-8.22/tests/init.sh
examples/wild-corpus/gnu/coreutils-8.22/tests/ln/hard-to-sym.sh
examples/wild-corpus/gnu/glibc-2.23/posix/globtest.sh
examples/wild-corpus/gnu/glibc-2.23/posix/tst-getconf.sh
examples/wild-corpus/gnu/glibc-2.23/sysdeps/unix/make-syscalls.sh
examples/wild-corpus/gnu/grep-2.24/gnulib-tests/init.sh
examples/wild-corpus/gnu/grep-2.24/tests/init.sh
examples/wild-corpus/google/bazel/src/test/shell/bazel/remote_helpers.sh
examples/wild-corpus/google/kythe/.jenkins/nightly-release.sh
examples/wild-corpus/google/kythe/kythe/extractors/openjdk/extract.sh
examples/wild-corpus/hg-other/eigen/bench/perf_monitoring/gemm/run.sh
examples/wild-corpus/hg-other/pygments-main/tests/examplefiles/example.sh
examples/wild-corpus/hg-other/pygments-main/tests/examplefiles/ltmain.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/acct/prctmp.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/acct/prtacct.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/allocate/disk_clean.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/ast/msgcc/msgcc.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/avs/dscfg/dscfgadm.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/diff3/diff3.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/initpkg/umountall.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/ipf/examples/mkfilters.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/krb5/kadmin/kclient/kclient.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/ldap/ns_ldap/idsconfig.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/svc/configd/restore_repository.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/svc/shell/ipf_include.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/tail/tests/sun_solaris_tail.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/tsol/misc/txzonemgr.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/ypcmd/multi.awk.sh
examples/wild-corpus/illumos-gate/usr/src/cmd/ypcmd/ypinit.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libast/common/comp/conf.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/data/bash_pre_rc.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/cpvprint.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/crawlsrccomments.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/filemutexdemo1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/filetree1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/gnaw.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/mandelbrotset1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/multifollow.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/numtree1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/primenumbers1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/rssread.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/shcalc.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/shircbot.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/shlint.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/shman.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/shnote.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/shpiano.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/shtinyurl.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/shtwitter.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/simplefileattributetree1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/simplefiletree1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/svcproptree1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/termclock.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/test_net_sctp.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/scripts/xmldocumenttree1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/append.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/arith.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/arrays.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/arrays2.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/attributes.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/basic.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/bracket.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/builtins.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/comvar.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/coprocess.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/cubetype.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/enum.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/expand.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/functions.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/io.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/nameref.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/options.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/path.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/pointtype.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/quoting.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/quoting2.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/recttype.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sigchld.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/signal.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/statics.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/subshell.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/substring.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_array_default_datatype.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_builtin_poll.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_builtin_tail.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_command_substitution.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_compound_misc.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_compound_nameref.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_compoundvario.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6722134_background_CHLD_trap.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6763594_command_failure_execs_twice.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6789247_printf_hexfloat_rounding.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6800929_large_command_substitution_hang.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6805792_varmovetest1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6805795_negative_zero.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6835835_builtin_cat_n_broken.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6855875_typeset_hexfloat_has_too_few_digits.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6881017_background_process_in_subshell_hangs_caller.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6904557_wc_no_longer_counts_number_of_bytes_correctly.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6904575_cut_-d_with_multibyte_character_no_longer_works.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6904878_join_-t_no_longer_works_with_multibyte_char_separator.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_cr_6907460_EXIT_trap_handlers_are_sometimes_executed_twice.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_locale_misc.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_staticvariables.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_vartree001.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_vartree002.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/sun_solaris_vartree003.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/tilde.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/timetype.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/treemove.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/types.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/variables.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/vartree1.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/common/tests/vartree2.sh
examples/wild-corpus/illumos-gate/usr/src/lib/libshell/misc/buildksh93.sh
examples/wild-corpus/illumos-gate/usr/src/test/os-tests/tests/pf_key/acquire-spray.sh
examples/wild-corpus/illumos-gate/usr/src/tools/env/illumos.sh
examples/wild-corpus/illumos-gate/usr/src/tools/gk/cshrc.sh
examples/wild-corpus/illumos-gate/usr/src/tools/gk/gen_make.machines.sh
examples/wild-corpus/illumos-gate/usr/src/tools/gk/login.sh
examples/wild-corpus/illumos-gate/usr/src/tools/scripts/bldenv.sh
examples/wild-corpus/illumos-gate/usr/src/tools/scripts/nightly.sh
examples/wild-corpus/illumos-gate/usr/src/tools/scripts/webrev.sh
examples/wild-corpus/liballocs/tools/debug-funcs.sh
examples/wild-corpus/linux-4.8.7/scripts/decode_stacktrace.sh
examples/wild-corpus/linux-4.8.7/scripts/tags.sh
examples/wild-corpus/linux-4.8.7/tools/perf/perf-completion.sh
examples/wild-corpus/linux-4.8.7/tools/perf/perf-with-kcore.sh
examples/wild-corpus/linux-4.8.7/tools/vm/slabinfo-gnuplot.sh
examples/wild-corpus/minix/commands/scripts/DESCRIBE.sh
examples/wild-corpus/minix/commands/scripts/mkdist.sh
examples/wild-corpus/minix/lib/generate.sh
examples/wild-corpus/oil/test/gold.sh
examples/wild-corpus/oil/test/osh2oil.sh
examples/wild-corpus/oil/test/oshc-deps.sh
examples/wild-corpus/oil/test/smoke.sh
examples/wild-corpus/sdk/tools/clang/scripts/update.sh
examples/wild-corpus/shell/ast/src/cmd/3d/3d.sh
examples/wild-corpus/shell/ast/src/cmd/3d/features/syscall.sh
examples/wild-corpus/shell/ast/src/cmd/INIT/ditto.sh
examples/wild-corpus/shell/ast/src/cmd/INIT/hurl.sh
examples/wild-corpus/shell/ast/src/cmd/INIT/iffe.sh
examples/wild-corpus/shell/ast/src/cmd/INIT/mktest.sh
examples/wild-corpus/shell/ast/src/cmd/INIT/package.sh
examples/wild-corpus/shell/ast/src/cmd/INIT/regress.sh
examples/wild-corpus/shell/ast/src/cmd/INIT/rt.sh
examples/wild-corpus/shell/ast/src/cmd/html/mm2bb.sh
examples/wild-corpus/shell/ast/src/cmd/html/mm2html.sh
examples/wild-corpus/shell/ast/src/cmd/html/mm2twiki.sh
examples/wild-corpus/shell/ast/src/cmd/ie/ie.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/data/bash_pre_rc.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/append.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/arith.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/arrays.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/arrays2.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/attributes.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/basic.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/bracket.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/builtins.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/comvar.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/comvario.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/coprocess.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/cubetype.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/enum.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/expand.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/functions.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/heredoc.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/io.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/leaks.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/locale.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/math.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/nameref.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/namespace.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/options.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/path.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/pointtype.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/quoting.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/quoting2.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/recttype.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/sigchld.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/signal.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/statics.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/subshell.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/substring.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/tilde.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/timetype.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/treemove.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/types.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/variables.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/vartree1.sh
examples/wild-corpus/shell/ast/src/cmd/ksh93/tests/vartree2.sh
examples/wild-corpus/shell/ast/src/cmd/mam/mamold.sh
examples/wild-corpus/shell/ast/src/cmd/msgcc/msgadmin.sh
examples/wild-corpus/shell/ast/src/cmd/msgcc/msgcc.sh
examples/wild-corpus/shell/ast/src/cmd/pax/tar.sh
examples/wild-corpus/shell/ast/src/cmd/proto/changes.sh
examples/wild-corpus/shell/ast/src/cmd/std/seq.sh
examples/wild-corpus/shell/ast/src/cmd/warp/warp.sh
examples/wild-corpus/shell/ast/src/lib/libast/comp/conf.sh
examples/wild-corpus/shell/bashdb/command/backtrace.sh
examples/wild-corpus/shell/bashdb/command/set_sub/autoeval.sh
examples/wild-corpus/shell/bashdb/command/set_sub/autolist.sh
examples/wild-corpus/shell/bashdb/command/set_sub/basename.sh
examples/wild-corpus/shell/bashdb/command/set_sub/debug.sh
examples/wild-corpus/shell/bashdb/command/set_sub/debugging.sh
examples/wild-corpus/shell/bashdb/command/set_sub/editing.sh
examples/wild-corpus/shell/bashdb/command/set_sub/highlight.sh
examples/wild-corpus/shell/bashdb/command/set_sub/history.sh
examples/wild-corpus/shell/bashdb/command/set_sub/showcommand.sh
examples/wild-corpus/shell/bashdb/getopts_long.sh
examples/wild-corpus/shell/bashdb/lib/processor.sh
examples/wild-corpus/shell/bashdb/test/unit/test-file.sh
examples/wild-corpus/shell/mksh/Build.sh
examples/wild-corpus/shell/mksh/test.sh
examples/wild-corpus/shell/modernish/install.sh
examples/wild-corpus/shell/mwc-sh/shql.sh
examples/wild-corpus/shell/posixcube/test.sh
================================================
FILE: script/parse-examples
================================================
#!/usr/bin/env bash
set -euo pipefail
files=(
examples/*.sh
examples/bash-it/**/*.sh
examples/bash-it/**/*.bash
examples/bash/**/*.sh
examples/bash/**/*.tests
examples/gentoo/**/*.sh
examples/gentoo/**/*.eclass
examples/gentoo/**/*.ebuild
examples/wild-corpus/**/*.sh
)
clone() {
if [[ -d examples/$1 ]]; then
git -C "examples/$1" fetch origin "$3:$3" -f -u --depth=1
else
git clone "$2" "examples/$1" -b "$3" --single-branch --depth=1
fi
}
cd "${0%/script/parse-examples}"
clone bash-it https://github.com/Bash-it/bash-it master
clone bash https://git.savannah.gnu.org/git/bash.git master
clone gentoo https://anongit.gentoo.org/git/repo/gentoo.git master
clone wild-corpus https://github.com/oilshell/wild-corpus main
find examples \( -name '*.sh' -or -name '*.bash' -or -name '*.tests' -or \
-name '*.eclass' -or -name '*.ebuild' \) -and -type f -print > script/example-files.txt
tree-sitter parse --scope source.bash -q -s --paths script/example-files.txt | \
tee >(awk '/ERROR|MISSING/{print $1}' | sort > script/known-failures.txt)
================================================
FILE: setup.py
================================================
from os import path
from platform import system
from sysconfig import get_config_var
from setuptools import Extension, find_packages, setup
from setuptools.command.build import build
from setuptools.command.egg_info import egg_info
from wheel.bdist_wheel import bdist_wheel
sources = [
"bindings/python/tree_sitter_bash/binding.c",
"src/parser.c",
]
if path.exists("src/scanner.c"):
sources.append("src/scanner.c")
macros: list[tuple[str, str | None]] = [
("PY_SSIZE_T_CLEAN", None),
("TREE_SITTER_HIDE_SYMBOLS", None),
]
if limited_api := not get_config_var("Py_GIL_DISABLED"):
macros.append(("Py_LIMITED_API", "0x030A0000"))
if system() != "Windows":
cflags = ["-std=c11", "-fvisibility=hidden"]
else:
cflags = ["/std:c11", "/utf-8"]
class Build(build):
def run(self):
if path.isdir("queries"):
dest = path.join(self.build_lib, "tree_sitter_bash", "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 = "cp310", "abi3"
return python, abi, platform
class EggInfo(egg_info):
def find_sources(self):
super().find_sources()
self.filelist.recursive_include("queries", "*.scm")
self.filelist.include("src/tree_sitter/*.h")
setup(
packages=find_packages("bindings/python"),
package_dir={"": "bindings/python"},
package_data={
"tree_sitter_bash": ["*.pyi", "py.typed"],
"tree_sitter_bash.queries": ["*.scm"],
},
ext_package="tree_sitter_bash",
ext_modules=[
Extension(
name="_binding",
sources=sources,
extra_compile_args=cflags,
define_macros=macros,
include_dirs=["src"],
py_limited_api=limited_api,
)
],
cmdclass={
"build": Build,
"bdist_wheel": BdistWheel,
"egg_info": EggInfo,
},
zip_safe=False
)
================================================
FILE: src/grammar.json
================================================
{
"$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json",
"name": "bash",
"word": "word",
"rules": {
"program": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
},
"_statements": {
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_statement"
},
{
"type": "SYMBOL",
"name": "_terminator"
}
]
}
},
{
"type": "SYMBOL",
"name": "_statement"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
}
]
}
},
"_terminated_statement": {
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_statement"
},
{
"type": "SYMBOL",
"name": "_terminator"
}
]
}
},
"_statement": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statement_not_subshell"
},
{
"type": "SYMBOL",
"name": "subshell"
}
]
},
"_statement_not_subshell": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "redirected_statement"
},
{
"type": "SYMBOL",
"name": "variable_assignment"
},
{
"type": "SYMBOL",
"name": "variable_assignments"
},
{
"type": "SYMBOL",
"name": "command"
},
{
"type": "SYMBOL",
"name": "declaration_command"
},
{
"type": "SYMBOL",
"name": "unset_command"
},
{
"type": "SYMBOL",
"name": "test_command"
},
{
"type": "SYMBOL",
"name": "negated_command"
},
{
"type": "SYMBOL",
"name": "for_statement"
},
{
"type": "SYMBOL",
"name": "c_style_for_statement"
},
{
"type": "SYMBOL",
"name": "while_statement"
},
{
"type": "SYMBOL",
"name": "if_statement"
},
{
"type": "SYMBOL",
"name": "case_statement"
},
{
"type": "SYMBOL",
"name": "pipeline"
},
{
"type": "SYMBOL",
"name": "list"
},
{
"type": "SYMBOL",
"name": "compound_statement"
},
{
"type": "SYMBOL",
"name": "function_definition"
}
]
},
"_statement_not_pipeline": {
"type": "PREC",
"value": 1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "redirected_statement"
},
{
"type": "SYMBOL",
"name": "variable_assignment"
},
{
"type": "SYMBOL",
"name": "variable_assignments"
},
{
"type": "SYMBOL",
"name": "command"
},
{
"type": "SYMBOL",
"name": "declaration_command"
},
{
"type": "SYMBOL",
"name": "unset_command"
},
{
"type": "SYMBOL",
"name": "test_command"
},
{
"type": "SYMBOL",
"name": "negated_command"
},
{
"type": "SYMBOL",
"name": "for_statement"
},
{
"type": "SYMBOL",
"name": "c_style_for_statement"
},
{
"type": "SYMBOL",
"name": "while_statement"
},
{
"type": "SYMBOL",
"name": "if_statement"
},
{
"type": "SYMBOL",
"name": "case_statement"
},
{
"type": "SYMBOL",
"name": "list"
},
{
"type": "SYMBOL",
"name": "compound_statement"
},
{
"type": "SYMBOL",
"name": "function_definition"
},
{
"type": "SYMBOL",
"name": "subshell"
}
]
}
},
"redirected_statement": {
"type": "PREC_DYNAMIC",
"value": -1,
"content": {
"type": "PREC_RIGHT",
"value": -1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
},
{
"type": "FIELD",
"name": "redirect",
"content": {
"type": "CHOICE",
"members": [
{
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "file_redirect"
},
{
"type": "SYMBOL",
"name": "heredoc_redirect"
}
]
}
}
]
}
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "body",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "if_statement"
},
{
"type": "SYMBOL",
"name": "while_statement"
}
]
}
},
{
"type": "SYMBOL",
"name": "herestring_redirect"
}
]
},
{
"type": "FIELD",
"name": "redirect",
"content": {
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "_redirect"
}
}
},
{
"type": "SYMBOL",
"name": "herestring_redirect"
}
]
}
}
},
"for_statement": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "for"
},
{
"type": "STRING",
"value": "select"
}
]
},
{
"type": "FIELD",
"name": "variable",
"content": {
"type": "SYMBOL",
"name": "_simple_variable_name"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "in"
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "_literal"
}
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "do_group"
}
}
]
},
"c_style_for_statement": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "for"
},
{
"type": "STRING",
"value": "(("
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_for_body"
}
]
},
{
"type": "STRING",
"value": "))"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ";"
},
{
"type": "BLANK"
}
]
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "do_group"
},
{
"type": "SYMBOL",
"name": "compound_statement"
}
]
}
}
]
},
"_for_body": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "initializer",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_c_expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_c_expression"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
}
},
{
"type": "SYMBOL",
"name": "_c_terminator"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_c_expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_c_expression"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
}
},
{
"type": "SYMBOL",
"name": "_c_terminator"
},
{
"type": "FIELD",
"name": "update",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_c_expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_c_expression"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
}
}
]
},
"_c_expression": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_c_variable_assignment"
},
"named": true,
"value": "variable_assignment"
}
]
},
"_c_expression_not_assignment": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_c_word"
},
{
"type": "SYMBOL",
"name": "simple_expansion"
},
{
"type": "SYMBOL",
"name": "expansion"
},
{
"type": "SYMBOL",
"name": "number"
},
{
"type": "SYMBOL",
"name": "string"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_c_unary_expression"
},
"named": true,
"value": "unary_expression"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_c_binary_expression"
},
"named": true,
"value": "binary_expression"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_c_postfix_expression"
},
"named": true,
"value": "postfix_expression"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_c_parenthesized_expression"
},
"named": true,
"value": "parenthesized_expression"
},
{
"type": "SYMBOL",
"name": "command_substitution"
}
]
},
"_c_variable_assignment": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_c_word"
},
"named": true,
"value": "variable_name"
}
},
{
"type": "STRING",
"value": "="
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_c_expression"
}
}
]
},
"_c_unary_expression": {
"type": "PREC",
"value": 17,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "++"
},
{
"type": "STRING",
"value": "--"
}
]
}
},
{
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
]
}
},
"_c_binary_expression": {
"type": "CHOICE",
"members": [
{
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "+="
},
{
"type": "STRING",
"value": "-="
},
{
"type": "STRING",
"value": "*="
},
{
"type": "STRING",
"value": "/="
},
{
"type": "STRING",
"value": "%="
},
{
"type": "STRING",
"value": "**="
},
{
"type": "STRING",
"value": "<<="
},
{
"type": "STRING",
"value": ">>="
},
{
"type": "STRING",
"value": "&="
},
{
"type": "STRING",
"value": "^="
},
{
"type": "STRING",
"value": "|="
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 3,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "||"
},
{
"type": "STRING",
"value": "-o"
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 4,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "&&"
},
{
"type": "STRING",
"value": "-a"
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 5,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "|"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 6,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "^"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 7,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "&"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 8,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "=="
},
{
"type": "STRING",
"value": "!="
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 9,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "<"
},
{
"type": "STRING",
"value": ">"
},
{
"type": "STRING",
"value": "<="
},
{
"type": "STRING",
"value": ">="
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 12,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "<<"
},
{
"type": "STRING",
"value": ">>"
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 13,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "+"
},
{
"type": "STRING",
"value": "-"
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 14,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "*"
},
{
"type": "STRING",
"value": "/"
},
{
"type": "STRING",
"value": "%"
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
},
{
"type": "PREC_RIGHT",
"value": 15,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "**"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
}
}
]
}
}
]
},
"_c_postfix_expression": {
"type": "PREC",
"value": 18,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_c_expression_not_assignment"
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "++"
},
{
"type": "STRING",
"value": "--"
}
]
}
}
]
}
},
"_c_parenthesized_expression": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_c_expression"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_c_expression"
}
]
}
}
]
},
{
"type": "STRING",
"value": ")"
}
]
},
"_c_word": {
"type": "ALIAS",
"content": {
"type": "PATTERN",
"value": "[a-zA-Z_][a-zA-Z0-9_]*"
},
"named": true,
"value": "word"
},
"while_statement": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "while"
},
{
"type": "STRING",
"value": "until"
}
]
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_terminated_statement"
}
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "do_group"
}
}
]
},
"do_group": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "do"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminated_statement"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "done"
}
]
},
"if_statement": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "if"
},
{
"type": "FIELD",
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_terminated_statement"
}
},
{
"type": "STRING",
"value": "then"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminated_statement"
},
{
"type": "BLANK"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "elif_clause"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "else_clause"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "fi"
}
]
},
"elif_clause": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "elif"
},
{
"type": "SYMBOL",
"name": "_terminated_statement"
},
{
"type": "STRING",
"value": "then"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminated_statement"
},
{
"type": "BLANK"
}
]
}
]
},
"else_clause": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminated_statement"
},
{
"type": "BLANK"
}
]
}
]
},
"case_statement": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "case"
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_literal"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "in"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminator"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "case_item"
}
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "last_case_item"
},
"named": true,
"value": "case_item"
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "esac"
}
]
},
"case_item": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "BLANK"
}
]
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "_extglob_blob"
}
]
}
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "_extglob_blob"
}
]
}
}
]
}
},
{
"type": "STRING",
"value": ")"
}
]
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
},
{
"type": "PREC",
"value": 1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "termination",
"content": {
"type": "STRING",
"value": ";;"
}
},
{
"type": "FIELD",
"name": "fallthrough",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ";&"
},
{
"type": "STRING",
"value": ";;&"
}
]
}
}
]
}
}
]
},
"last_case_item": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "BLANK"
}
]
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "_extglob_blob"
}
]
}
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "_extglob_blob"
}
]
}
}
]
}
},
{
"type": "STRING",
"value": ")"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "PREC",
"value": 1,
"content": {
"type": "STRING",
"value": ";;"
}
},
{
"type": "BLANK"
}
]
}
]
},
"function_definition": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "function"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "word"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "STRING",
"value": ")"
}
]
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "word"
}
},
{
"type": "STRING",
"value": "("
},
{
"type": "STRING",
"value": ")"
}
]
}
]
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "compound_statement"
},
{
"type": "SYMBOL",
"name": "subshell"
},
{
"type": "SYMBOL",
"name": "test_command"
},
{
"type": "SYMBOL",
"name": "if_statement"
}
]
}
},
{
"type": "FIELD",
"name": "redirect",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_redirect"
},
{
"type": "BLANK"
}
]
}
}
]
}
},
"compound_statement": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "{"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_terminated_statement"
},
{
"type": "BLANK"
}
]
},
{
"type": "TOKEN",
"content": {
"type": "PREC",
"value": -1,
"content": {
"type": "STRING",
"value": "}"
}
}
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "(("
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_arithmetic_expression"
},
{
"type": "STRING",
"value": ","
}
]
}
},
{
"type": "SYMBOL",
"name": "_arithmetic_expression"
},
{
"type": "STRING",
"value": "))"
}
]
}
]
},
"subshell": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "_statements"
},
{
"type": "STRING",
"value": ")"
}
]
},
"pipeline": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_statement_not_pipeline"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "STRING",
"value": "|&"
}
]
},
{
"type": "SYMBOL",
"name": "_statement_not_pipeline"
}
]
}
}
]
}
},
"list": {
"type": "PREC_LEFT",
"value": -1,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_statement"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "&&"
},
{
"type": "STRING",
"value": "||"
}
]
},
{
"type": "SYMBOL",
"name": "_statement"
}
]
}
},
"negated_command": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "!"
},
{
"type": "CHOICE",
"members": [
{
"type": "PREC",
"value": 2,
"content": {
"type": "SYMBOL",
"name": "command"
}
},
{
"type": "PREC",
"value": 1,
"content": {
"type": "SYMBOL",
"name": "variable_assignment"
}
},
{
"type": "SYMBOL",
"name": "test_command"
},
{
"type": "SYMBOL",
"name": "subshell"
}
]
}
]
},
"test_command": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "SYMBOL",
"name": "redirected_statement"
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "]"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "[["
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_expression"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_test_command_binary_expression"
},
"named": true,
"value": "binary_expression"
}
]
},
{
"type": "STRING",
"value": "]]"
}
]
}
]
}
]
},
"_test_command_binary_expression": {
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "="
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_regex_no_space"
},
"named": true,
"value": "regex"
}
}
]
}
},
"declaration_command": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "declare"
},
{
"type": "STRING",
"value": "typeset"
},
{
"type": "STRING",
"value": "export"
},
{
"type": "STRING",
"value": "readonly"
},
{
"type": "STRING",
"value": "local"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "_simple_variable_name"
},
{
"type": "SYMBOL",
"name": "variable_assignment"
}
]
}
}
]
}
},
"unset_command": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "unset"
},
{
"type": "STRING",
"value": "unsetenv"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "_simple_variable_name"
}
]
}
}
]
}
},
"command": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "variable_assignment"
},
{
"type": "FIELD",
"name": "redirect",
"content": {
"type": "SYMBOL",
"name": "_redirect"
}
}
]
}
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "command_name"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "argument",
"content": {
"type": "SYMBOL",
"name": "_literal"
}
},
{
"type": "FIELD",
"name": "argument",
"content": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_bare_dollar"
},
"named": false,
"value": "$"
}
},
{
"type": "FIELD",
"name": "argument",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "=~"
},
{
"type": "STRING",
"value": "=="
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "regex"
}
]
}
]
}
},
{
"type": "FIELD",
"name": "redirect",
"content": {
"type": "SYMBOL",
"name": "herestring_redirect"
}
}
]
}
},
{
"type": "SYMBOL",
"name": "subshell"
}
]
}
]
}
},
"command_name": {
"type": "SYMBOL",
"name": "_literal"
},
"variable_assignment": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "variable_name"
},
{
"type": "SYMBOL",
"name": "subscript"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "="
},
{
"type": "STRING",
"value": "+="
}
]
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "array"
},
{
"type": "SYMBOL",
"name": "_empty_value"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_comment_word"
},
"named": true,
"value": "word"
}
]
}
}
]
},
"variable_assignments": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "variable_assignment"
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "variable_assignment"
}
}
]
},
"subscript": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "variable_name"
}
},
{
"type": "STRING",
"value": "["
},
{
"type": "FIELD",
"name": "index",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "binary_expression"
},
{
"type": "SYMBOL",
"name": "unary_expression"
},
{
"type": "SYMBOL",
"name": "compound_statement"
},
{
"type": "SYMBOL",
"name": "subshell"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_concat"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "]"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_concat"
},
{
"type": "BLANK"
}
]
}
]
},
"file_redirect": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "descriptor",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "file_descriptor"
},
{
"type": "BLANK"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "<"
},
{
"type": "STRING",
"value": ">"
},
{
"type": "STRING",
"value": ">>"
},
{
"type": "STRING",
"value": "&>"
},
{
"type": "STRING",
"value": "&>>"
},
{
"type": "STRING",
"value": "<&"
},
{
"type": "STRING",
"value": ">&"
},
{
"type": "STRING",
"value": ">|"
}
]
},
{
"type": "FIELD",
"name": "destination",
"content": {
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "_literal"
}
}
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "<&-"
},
{
"type": "STRING",
"value": ">&-"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "destination",
"content": {
"type": "SYMBOL",
"name": "_literal"
}
},
{
"type": "BLANK"
}
]
}
]
}
]
}
]
}
},
"heredoc_redirect": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "descriptor",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "file_descriptor"
},
{
"type": "BLANK"
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "<<"
},
{
"type": "STRING",
"value": "<<-"
}
]
},
{
"type": "SYMBOL",
"name": "heredoc_start"
},
{
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_heredoc_pipeline"
},
"named": true,
"value": "pipeline"
},
{
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "redirect",
"content": {
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "_redirect"
}
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_heredoc_expression"
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "SYMBOL",
"name": "_heredoc_expression"
},
{
"type": "SYMBOL",
"name": "_heredoc_command"
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "PATTERN",
"value": "\\n"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_heredoc_body"
},
{
"type": "SYMBOL",
"name": "_simple_heredoc_body"
}
]
}
]
},
"_heredoc_pipeline": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "STRING",
"value": "|&"
}
]
},
{
"type": "SYMBOL",
"name": "_statement"
}
]
},
"_heredoc_expression": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "||"
},
{
"type": "STRING",
"value": "&&"
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_statement"
}
}
]
},
"_heredoc_command": {
"type": "REPEAT1",
"content": {
"type": "FIELD",
"name": "argument",
"content": {
"type": "SYMBOL",
"name": "_literal"
}
}
},
"_heredoc_body": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "heredoc_body"
},
{
"type": "SYMBOL",
"name": "heredoc_end"
}
]
},
"heredoc_body": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_heredoc_body_beginning"
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "expansion"
},
{
"type": "SYMBOL",
"name": "simple_expansion"
},
{
"type": "SYMBOL",
"name": "command_substitution"
},
{
"type": "SYMBOL",
"name": "heredoc_content"
}
]
}
}
]
},
"_simple_heredoc_body": {
"type": "SEQ",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "simple_heredoc_body"
},
"named": true,
"value": "heredoc_body"
},
{
"type": "SYMBOL",
"name": "heredoc_end"
}
]
},
"herestring_redirect": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "descriptor",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "file_descriptor"
},
{
"type": "BLANK"
}
]
}
},
{
"type": "STRING",
"value": "<<<"
},
{
"type": "SYMBOL",
"name": "_literal"
}
]
}
},
"_redirect": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "file_redirect"
},
{
"type": "SYMBOL",
"name": "herestring_redirect"
}
]
},
"_expression": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_literal"
},
{
"type": "SYMBOL",
"name": "unary_expression"
},
{
"type": "SYMBOL",
"name": "ternary_expression"
},
{
"type": "SYMBOL",
"name": "binary_expression"
},
{
"type": "SYMBOL",
"name": "postfix_expression"
},
{
"type": "SYMBOL",
"name": "parenthesized_expression"
}
]
},
"binary_expression": {
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "+="
},
{
"type": "STRING",
"value": "-="
},
{
"type": "STRING",
"value": "*="
},
{
"type": "STRING",
"value": "/="
},
{
"type": "STRING",
"value": "%="
},
{
"type": "STRING",
"value": "**="
},
{
"type": "STRING",
"value": "<<="
},
{
"type": "STRING",
"value": ">>="
},
{
"type": "STRING",
"value": "&="
},
{
"type": "STRING",
"value": "^="
},
{
"type": "STRING",
"value": "|="
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "="
},
{
"type": "STRING",
"value": "=~"
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 3,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "||"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 4,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "&&"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 5,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "|"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 6,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "^"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 7,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "STRING",
"value": "&"
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 8,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
},
{
"type": "FIELD",
"name": "operator",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "=="
},
{
"type": "STRING",
"value": "!="
}
]
}
},
{
"type": "FIELD",
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
}
},
{
"type": "PREC_LEFT",
"value": 9,
"content": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
gitextract_j8navkbf/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── dependabot.yml │ └── workflows/ │ ├── ci.yml │ ├── fuzz.yml │ ├── lint.yml │ └── publish.yml ├── .gitignore ├── CMakeLists.txt ├── Cargo.toml ├── LICENSE ├── Makefile ├── Package.swift ├── README.md ├── binding.gyp ├── bindings/ │ ├── c/ │ │ ├── tree-sitter-bash.pc.in │ │ └── tree_sitter/ │ │ └── tree-sitter-bash.h │ ├── go/ │ │ ├── binding.go │ │ └── binding_test.go │ ├── node/ │ │ ├── binding.cc │ │ ├── binding_test.js │ │ ├── index.d.ts │ │ └── index.js │ ├── python/ │ │ ├── tests/ │ │ │ └── test_binding.py │ │ └── tree_sitter_bash/ │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── py.typed │ ├── rust/ │ │ ├── build.rs │ │ └── lib.rs │ └── swift/ │ ├── TreeSitterBash/ │ │ └── bash.h │ └── TreeSitterBashTests/ │ └── TreeSitterBashTests.swift ├── eslint.config.mjs ├── examples/ │ ├── atom.sh │ ├── clean-old.sh │ ├── doc-build.sh │ ├── install.sh │ ├── release.sh │ ├── relocate.sh │ ├── test.sh │ └── update-authors.sh ├── go.mod ├── go.sum ├── grammar.js ├── package.json ├── pyproject.toml ├── queries/ │ └── highlights.scm ├── script/ │ ├── known-failures.txt │ └── parse-examples ├── setup.py ├── src/ │ ├── grammar.json │ ├── node-types.json │ ├── parser.c │ ├── scanner.c │ └── tree_sitter/ │ ├── alloc.h │ ├── array.h │ └── parser.h ├── test/ │ └── corpus/ │ ├── commands.txt │ ├── crlf.txt │ ├── literals.txt │ ├── programs.txt │ └── statements.txt └── tree-sitter.json
SYMBOL INDEX (94 symbols across 18 files)
FILE: bindings/c/tree_sitter/tree-sitter-bash.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_bash/__init__.py
function _get_query (line 8) | def _get_query(name, file):
function __getattr__ (line 14) | def __getattr__(name):
function __dir__ (line 27) | def __dir__():
FILE: bindings/python/tree_sitter_bash/__init__.pyi
function language (line 5) | def language() -> object: ...
FILE: bindings/python/tree_sitter_bash/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_Slot (line 11) | struct PyModuleDef_Slot
type PyModuleDef (line 24) | struct PyModuleDef
function PyMODINIT_FUNC (line 33) | PyMODINIT_FUNC PyInit__binding(void) {
FILE: bindings/rust/build.rs
function main (line 1) | fn main() {
FILE: bindings/rust/lib.rs
function tree_sitter_bash (line 27) | fn tree_sitter_bash() -> *const ();
constant LANGUAGE (line 33) | pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitt...
constant NODE_TYPES (line 38) | pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
constant HIGHLIGHT_QUERY (line 41) | pub const HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights...
function test_can_load_grammar (line 46) | fn test_can_load_grammar() {
FILE: bindings/swift/TreeSitterBash/bash.h
type TSLanguage (line 4) | typedef struct TSLanguage TSLanguage;
FILE: grammar.js
constant SPECIAL_CHARACTERS (line 11) | const SPECIAL_CHARACTERS = [
constant PREC (line 23) | const PREC = {
function noneOf (line 1150) | function noneOf(...characters) {
function commaSep (line 1162) | function commaSep(rule) {
function commaSep1 (line 1173) | function commaSep1(rule) {
function immediateLiterals (line 1185) | function immediateLiterals(...literals) {
function tokenLiterals (line 1199) | function tokenLiterals(precedence, ...literals) {
FILE: setup.py
class Build (line 30) | class Build(build):
method run (line 31) | def run(self):
class BdistWheel (line 38) | class BdistWheel(bdist_wheel):
method get_tag (line 39) | def get_tag(self):
class EggInfo (line 46) | class EggInfo(egg_info):
method find_sources (line 47) | def find_sources(self):
FILE: src/parser.c
type ts_symbol_identifiers (line 30) | enum ts_symbol_identifiers {
type ts_field_identifiers (line 2002) | enum ts_field_identifiers {
function ts_lex (line 10359) | static bool ts_lex(TSLexer *lexer, TSStateId state) {
function ts_lex_keywords (line 20765) | static bool ts_lex_keywords(TSLexer *lexer, TSStateId state) {
type ts_external_scanner_symbol_identifiers (line 349604) | enum ts_external_scanner_symbol_identifiers {
function TS_PUBLIC (line 350577) | TS_PUBLIC const TSLanguage *tree_sitter_bash(void) {
FILE: src/scanner.c
type TokenType (line 9) | enum TokenType {
type String (line 41) | typedef Array(char) String;
type Heredoc (line 43) | typedef struct {
type Scanner (line 60) | typedef struct {
function advance (line 67) | static inline void advance(TSLexer *lexer) { lexer->advance(lexer, false...
function skip (line 69) | static inline void skip(TSLexer *lexer) { lexer->advance(lexer, true); }
function in_error_recovery (line 71) | static inline bool in_error_recovery(const bool *valid_symbols) { return...
function reset_string (line 73) | static inline void reset_string(String *string) {
function reset_heredoc (line 80) | static inline void reset_heredoc(Heredoc *heredoc) {
function reset (line 87) | static inline void reset(Scanner *scanner) {
function serialize (line 93) | static unsigned serialize(Scanner *scanner, char *buffer) {
function deserialize (line 121) | static void deserialize(Scanner *scanner, const char *buffer, unsigned l...
function advance_word (line 164) | static bool advance_word(TSLexer *lexer, String *unquoted_word) {
function scan_bare_dollar (line 195) | static inline bool scan_bare_dollar(TSLexer *lexer) {
function scan_heredoc_start (line 210) | static bool scan_heredoc_start(Heredoc *heredoc, TSLexer *lexer) {
function scan_heredoc_end_identifier (line 226) | static bool scan_heredoc_end_identifier(Heredoc *heredoc, TSLexer *lexer) {
function scan_heredoc_content (line 246) | static bool scan_heredoc_content(Scanner *scanner, TSLexer *lexer, enum ...
function scan (line 349) | static bool scan(Scanner *scanner, TSLexer *lexer, const bool *valid_sym...
function tree_sitter_bash_external_scanner_scan (line 1193) | bool tree_sitter_bash_external_scanner_scan(void *payload, TSLexer *lexe...
function tree_sitter_bash_external_scanner_serialize (line 1198) | unsigned tree_sitter_bash_external_scanner_serialize(void *payload, char...
function tree_sitter_bash_external_scanner_deserialize (line 1203) | void tree_sitter_bash_external_scanner_deserialize(void *payload, const ...
function tree_sitter_bash_external_scanner_destroy (line 1208) | void tree_sitter_bash_external_scanner_destroy(void *payload) {
FILE: src/tree_sitter/array.h
type Array (line 160) | typedef Array(void) Array;
function _array__delete (line 163) | static inline void _array__delete(Array *self) {
function _array__erase (line 173) | static inline void _array__erase(Array *self, size_t element_size,
function _array__reserve (line 183) | static inline void _array__reserve(Array *self, size_t element_size, uin...
function _array__assign (line 195) | static inline void _array__assign(Array *self, const Array *other, size_...
function _array__swap (line 202) | static inline void _array__swap(Array *self, Array *other) {
function _array__grow (line 209) | static inline void _array__grow(Array *self, uint32_t count, size_t elem...
function _array__splice (line 220) | 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 TSLanguageMetadata (line 21) | typedef struct TSLanguageMetadata {
type TSFieldMapEntry (line 28) | typedef struct {
type TSMapSlice (line 35) | typedef struct {
type TSSymbolMetadata (line 40) | typedef struct {
type TSLexer (line 46) | typedef struct TSLexer TSLexer;
type TSLexer (line 48) | struct TSLexer {
type TSParseActionType (line 59) | typedef enum {
type TSParseAction (line 66) | typedef union {
type TSLexMode (line 83) | typedef struct {
type TSLexerMode (line 88) | typedef struct {
type TSParseActionEntry (line 94) | typedef union {
type TSCharacterRange (line 102) | typedef struct {
type TSLanguage (line 107) | struct TSLanguage {
function set_contains (line 154) | static inline bool set_contains(const TSCharacterRange *ranges, uint32_t...
Copy disabled (too large)
Download .json
Condensed preview — 64 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (10,816K 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": 941,
"preview": "* text=auto eol=lf\n\n# Generated source files\nsrc/*.json linguist-generated\nsrc/parser.c linguist-generated\nsrc/tree_sitt"
},
{
"path": ".github/FUNDING.yml",
"chars": 835,
"preview": "# These are supported funding model platforms\n\ngithub: tree-sitter\npatreon: # Replace with a single Patreon username\nope"
},
{
"path": ".github/dependabot.yml",
"chars": 157,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"github-actions\"\n directory: \"/\"\n schedule:\n interval: \"weekly\"\n "
},
{
"path": ".github/workflows/ci.yml",
"chars": 2111,
"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": 465,
"preview": "name: Fuzz\n\non:\n push:\n paths:\n - src/scanner.c\n pull_request:\n paths:\n - src/scanner.c\n workflow_dis"
},
{
"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": 402,
"preview": "# Rust artifacts\ntarget/\n\n# Node artifacts\nbuild/\nprebuilds/\nnode_modules/\n\n# Swift artifacts\n.build/\nPackage.resolved\n\n"
},
{
"path": "CMakeLists.txt",
"chars": 2683,
"preview": "cmake_minimum_required(VERSION 3.13)\n\nproject(tree-sitter-bash\n VERSION \"0.25.1\"\n DESCRIPTION \"Bash gramma"
},
{
"path": "Cargo.toml",
"chars": 725,
"preview": "[package]\nname = \"tree-sitter-bash\"\ndescription = \"Bash grammar for tree-sitter\"\nversion = \"0.25.1\"\nauthors = [\n \"Max B"
},
{
"path": "LICENSE",
"chars": 1080,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2017 Max Brunsfeld\n\nPermission is hereby granted, free of charge, to any person obt"
},
{
"path": "Makefile",
"chars": 3191,
"preview": "ifeq ($(OS),Windows_NT)\n$(error Windows is not supported)\nendif\n\nLANGUAGE_NAME := tree-sitter-bash\nHOMEPAGE_URL := https"
},
{
"path": "Package.swift",
"chars": 1070,
"preview": "// swift-tools-version:5.3\nimport PackageDescription\n\nlet package = Package(\n name: \"TreeSitterBash\",\n products: ["
},
{
"path": "README.md",
"chars": 1485,
"preview": "# tree-sitter-bash\n\n[![CI][ci]](https://github.com/tree-sitter/tree-sitter-bash/actions/workflows/ci.yml)\n[![discord][di"
},
{
"path": "binding.gyp",
"chars": 599,
"preview": "{\n \"targets\": [\n {\n \"target_name\": \"tree_sitter_bash_binding\",\n \"dependencies\": [\n \"<!(node -p \\\"re"
},
{
"path": "bindings/c/tree-sitter-bash.pc.in",
"chars": 293,
"preview": "prefix=@CMAKE_INSTALL_PREFIX@\nlibdir=${prefix}/@CMAKE_INSTALL_LIBDIR@\nincludedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@\n\nN"
},
{
"path": "bindings/c/tree_sitter/tree-sitter-bash.h",
"chars": 238,
"preview": "#ifndef TREE_SITTER_BASH_H_\n#define TREE_SITTER_BASH_H_\n\ntypedef struct TSLanguage TSLanguage;\n\n#ifdef __cplusplus\nexter"
},
{
"path": "bindings/go/binding.go",
"chars": 283,
"preview": "package tree_sitter_bash\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_bash_test\n\nimport (\n\t\"testing\"\n\n\ttree_sitter \"github.com/tree-sitter/go-tree-sitter\"\n\ttree_sitter_ba"
},
{
"path": "bindings/node/binding.cc",
"chars": 577,
"preview": "#include <napi.h>\n\ntypedef struct TSLanguage TSLanguage;\n\nextern \"C\" TSLanguage *tree_sitter_bash();\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_bash\n\n\nclass TestLanguage(TestCase):\n def test_can_loa"
},
{
"path": "bindings/python/tree_sitter_bash/__init__.py",
"chars": 720,
"preview": "\"\"\"Bash 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_bash/__init__.pyi",
"chars": 86,
"preview": "from typing import Final\n\nHIGHLIGHTS_QUERY: Final[str]\n\ndef language() -> object: ...\n"
},
{
"path": "bindings/python/tree_sitter_bash/binding.c",
"chars": 832,
"preview": "#include <Python.h>\n\ntypedef struct TSLanguage TSLanguage;\n\nTSLanguage *tree_sitter_bash(void);\n\nstatic PyObject* _bindi"
},
{
"path": "bindings/python/tree_sitter_bash/py.typed",
"chars": 0,
"preview": ""
},
{
"path": "bindings/rust/build.rs",
"chars": 632,
"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": 1725,
"preview": "//! This crate provides Bash language support for the [tree-sitter][] parsing library.\n//!\n//! Typically, you will use t"
},
{
"path": "bindings/swift/TreeSitterBash/bash.h",
"chars": 238,
"preview": "#ifndef TREE_SITTER_BASH_H_\n#define TREE_SITTER_BASH_H_\n\ntypedef struct TSLanguage TSLanguage;\n\n#ifdef __cplusplus\nexter"
},
{
"path": "bindings/swift/TreeSitterBashTests/TreeSitterBashTests.swift",
"chars": 359,
"preview": "import XCTest\nimport SwiftTreeSitter\nimport TreeSitterBash\n\nfinal class TreeSitterBashTests: 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": "examples/atom.sh",
"chars": 3410,
"preview": "#!/bin/bash\n\nif [ \"$(uname)\" == 'Darwin' ]; then\n OS='Mac'\nelif [ \"$(expr substr $(uname -s) 1 5)\" == 'Linux' ]; then\n "
},
{
"path": "examples/clean-old.sh",
"chars": 4258,
"preview": "#!/bin/bash\n\n# look for old 0.x cruft, and get rid of it.\n# Should already be sitting in the npm folder.\n\n# This doesn't"
},
{
"path": "examples/doc-build.sh",
"chars": 3260,
"preview": "#!/usr/bin/env bash\n\nif [[ $DEBUG != \"\" ]]; then\n set -x\nfi\nset -o errexit\nset -o pipefail\n\nif ! [ -x node_modules/.bin"
},
{
"path": "examples/install.sh",
"chars": 6239,
"preview": "#!/bin/sh\n\n# A word about this shell script:\n#\n# It must work everywhere, including on systems that lack\n# a /bin/bash, "
},
{
"path": "examples/release.sh",
"chars": 657,
"preview": "#!/bin/bash\n\n# script for creating a zip and tarball for inclusion in node\n\nunset CDPATH\n\nset -e\n\nrm -rf release *.tgz |"
},
{
"path": "examples/relocate.sh",
"chars": 665,
"preview": "#!/bin/bash\n\n# Change the cli shebang to point at the specified node\n# Useful for when the program is moved around after"
},
{
"path": "examples/test.sh",
"chars": 2481,
"preview": "#!/usr/bin/env bash\n\nset -e\n\nfunction usage {\n cat <<-EOF\nUSAGE\n\n $0 [-dgGhv] [-f focus-string] [-s seed]\n\nOPTIONS\n\n "
},
{
"path": "examples/update-authors.sh",
"chars": 183,
"preview": "#!/bin/sh\n\ngit log --reverse --format='%aN <%aE>' | perl -wnE '\nBEGIN {\n say \"# Authors sorted by whether or not they\\x"
},
{
"path": "go.mod",
"chars": 167,
"preview": "module github.com/tree-sitter/tree-sitter-bash\n\ngo 1.22\n\nrequire github.com/tree-sitter/go-tree-sitter v0.24.0\n\nrequire "
},
{
"path": "go.sum",
"chars": 4176,
"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": 30142,
"preview": "/**\n * @file Bash grammar for tree-sitter\n * @author Max Brunsfeld <maxbrunsfeld@gmail.com>\n * @author Amaan Qureshi <am"
},
{
"path": "package.json",
"chars": 1292,
"preview": "{\n \"name\": \"tree-sitter-bash\",\n \"version\": \"0.25.1\",\n \"description\": \"Bash grammar for tree-sitter\",\n \"repository\": "
},
{
"path": "pyproject.toml",
"chars": 878,
"preview": "[build-system]\nrequires = [\"setuptools>=42\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"tree-si"
},
{
"path": "queries/highlights.scm",
"chars": 577,
"preview": "[\n (string)\n (raw_string)\n (heredoc_body)\n (heredoc_start)\n] @string\n\n(command_name) @function\n\n(variable_name) @pro"
},
{
"path": "script/known-failures.txt",
"chars": 23847,
"preview": "examples/bash-it/completion/available/bundler.completion.bash\nexamples/bash-it/completion/available/sqlmap.completion.ba"
},
{
"path": "script/parse-examples",
"chars": 1081,
"preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nfiles=(\n examples/*.sh\n examples/bash-it/**/*.sh\n examples/bash-it/**/*.bash\n"
},
{
"path": "setup.py",
"chars": 2056,
"preview": "from os import path\nfrom platform import system\nfrom sysconfig import get_config_var\n\nfrom setuptools import Extension, "
},
{
"path": "src/grammar.json",
"chars": 179629,
"preview": "{\n \"$schema\": \"https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json\",\n \"name\": \"bash\",\n \"word"
},
{
"path": "src/node-types.json",
"chars": 51167,
"preview": "[\n {\n \"type\": \"_expression\",\n \"named\": true,\n \"subtypes\": [\n {\n \"type\": \"_primary_expression\",\n "
},
{
"path": "src/parser.c",
"chars": 9912254,
"preview": "/* Automatically @generated by tree-sitter v0.25.10 */\n\n#include \"tree_sitter/parser.h\"\n\n#if defined(__GNUC__) || define"
},
{
"path": "src/scanner.c",
"chars": 45602,
"preview": "#include \"tree_sitter/array.h\"\n#include \"tree_sitter/parser.h\"\n\n#include <assert.h>\n#include <ctype.h>\n#include <string."
},
{
"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": 10431,
"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": 7624,
"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/commands.txt",
"chars": 17200,
"preview": "===============================\nCommands\n===============================\n\nwhoami\n\n---\n\n(program\n (command\n (command_"
},
{
"path": "test/corpus/crlf.txt",
"chars": 239,
"preview": "================================\nVariables with CRLF line endings\n================================\n\nA=one\n\nB=two\n\n---\n\n("
},
{
"path": "test/corpus/literals.txt",
"chars": 37509,
"preview": "================================================================================\nLiteral words\n========================="
},
{
"path": "test/corpus/programs.txt",
"chars": 1311,
"preview": "===============================\nComments\n===============================\n\n#!/bin/bash\n# hi\n\n---\n\n(program\n (comment)\n "
},
{
"path": "test/corpus/statements.txt",
"chars": 42290,
"preview": "================================================================================\nPipelines\n============================="
},
{
"path": "tree-sitter.json",
"chars": 916,
"preview": "{\n \"grammars\": [\n {\n \"name\": \"bash\",\n \"camelcase\": \"Bash\",\n \"scope\": \"source.bash\",\n \"path\": \".\""
}
]
About this extraction
This page contains the full source code of the tree-sitter/tree-sitter-bash GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 64 files (9.9 MB), approximately 2.6M tokens, and a symbol index with 94 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.