├── bindings ├── python │ ├── tree_sitter_yaml │ │ ├── py.typed │ │ ├── __init__.pyi │ │ ├── __init__.py │ │ └── binding.c │ └── tests │ │ └── test_binding.py ├── node │ ├── binding_test.js │ ├── index.d.ts │ ├── index.js │ └── binding.cc ├── swift │ ├── TreeSitterYAML │ │ └── yaml.h │ └── TreeSitterYAMLTests │ │ └── TreeSitterYAMLTests.swift ├── c │ ├── tree_sitter │ │ └── tree-sitter-yaml.h │ └── tree-sitter-yaml.pc.in ├── go │ ├── binding.go │ └── binding_test.go └── rust │ ├── build.rs │ └── lib.rs ├── eslint.config.mjs ├── .gitmodules ├── schema ├── core │ ├── package.json │ ├── src │ │ ├── node-types.json │ │ ├── tree_sitter │ │ │ ├── alloc.h │ │ │ ├── parser.h │ │ │ └── array.h │ │ ├── grammar.json │ │ └── parser.c │ └── grammar.js ├── json │ ├── package.json │ ├── grammar.js │ └── src │ │ ├── node-types.json │ │ ├── tree_sitter │ │ ├── alloc.h │ │ ├── parser.h │ │ └── array.h │ │ ├── grammar.json │ │ └── parser.c ├── legacy │ ├── package.json │ ├── src │ │ ├── node-types.json │ │ ├── tree_sitter │ │ │ ├── alloc.h │ │ │ ├── parser.h │ │ │ └── array.h │ │ └── grammar.json │ └── grammar.js └── update-schema.js ├── .github ├── dependabot.yml └── workflows │ ├── fuzz.yml │ ├── lint.yml │ ├── publish.yml │ └── ci.yml ├── go.mod ├── examples ├── log-file.yaml └── invoice.yaml ├── .gitignore ├── Package.resolved ├── .editorconfig ├── Cargo.toml ├── binding.gyp ├── pyproject.toml ├── tree-sitter.json ├── .gitattributes ├── README.md ├── LICENSE ├── test ├── highlight │ └── core.yaml └── corpus │ ├── 09_streams.txt │ └── 05_characters.txt ├── src ├── tree_sitter │ ├── alloc.h │ ├── parser.h │ └── array.h ├── schema.json.c ├── schema.core.c └── node-types.json ├── Package.swift ├── queries └── highlights.scm ├── package.json ├── setup.py ├── CMakeLists.txt ├── Makefile ├── go.sum └── Cargo.lock /bindings/python/tree_sitter_yaml/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import treesitter from 'eslint-config-treesitter'; 2 | 3 | export default [ 4 | ...treesitter, 5 | ]; 6 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_yaml/__init__.pyi: -------------------------------------------------------------------------------- 1 | from typing import Final 2 | 3 | HIGHLIGHTS_QUERY: Final[str] 4 | 5 | def language() -> object: ... 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "yaml-test-suite"] 2 | path = examples/yaml-test-suite 3 | url = https://github.com/yaml/yaml-test-suite 4 | branch = data 5 | shallow = true 6 | -------------------------------------------------------------------------------- /schema/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "build": "tree-sitter generate --abi=14", 5 | "postbuild": "node ../update-schema.js core" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /schema/json/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "build": "tree-sitter generate --abi=14", 5 | "postbuild": "node ../update-schema.js json" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /schema/legacy/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "build": "tree-sitter generate --abi=14", 5 | "postbuild": "node ../update-schema.js legacy" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | commit-message: 8 | prefix: "ci" 9 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tree-sitter-grammars/tree-sitter-yaml 2 | 3 | go 1.22 4 | 5 | require github.com/tree-sitter/go-tree-sitter v0.24.0 6 | 7 | require github.com/mattn/go-pointer v0.0.1 // indirect 8 | -------------------------------------------------------------------------------- /bindings/node/binding_test.js: -------------------------------------------------------------------------------- 1 | const assert = require("node:assert"); 2 | const { test } = require("node:test"); 3 | 4 | const Parser = require("tree-sitter"); 5 | 6 | test("can load grammar", () => { 7 | const parser = new Parser(); 8 | assert.doesNotThrow(() => parser.setLanguage(require("."))); 9 | }); 10 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterYAML/yaml.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_YAML_H_ 2 | #define TREE_SITTER_YAML_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_yaml(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_YAML_H_ 17 | -------------------------------------------------------------------------------- /bindings/c/tree_sitter/tree-sitter-yaml.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_YAML_H_ 2 | #define TREE_SITTER_YAML_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_yaml(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_YAML_H_ 17 | -------------------------------------------------------------------------------- /bindings/c/tree-sitter-yaml.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 3 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ 4 | 5 | Name: tree-sitter-yaml 6 | Description: @PROJECT_DESCRIPTION@ 7 | URL: @PROJECT_HOMEPAGE_URL@ 8 | Version: @PROJECT_VERSION@ 9 | Libs: -L${libdir} -ltree-sitter-yaml 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /bindings/python/tests/test_binding.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | from tree_sitter import Language, Parser 4 | import tree_sitter_yaml 5 | 6 | 7 | class TestLanguage(TestCase): 8 | def test_can_load_grammar(self): 9 | try: 10 | Parser(Language(tree_sitter_yaml.language())) 11 | except Exception: 12 | self.fail("Error loading YAML grammar") 13 | -------------------------------------------------------------------------------- /bindings/go/binding.go: -------------------------------------------------------------------------------- 1 | package tree_sitter_yaml 2 | 3 | // #cgo CFLAGS: -std=c11 -fPIC 4 | // #include "../../src/parser.c" 5 | // #if __has_include("../../src/scanner.c") 6 | // #include "../../src/scanner.c" 7 | // #endif 8 | import "C" 9 | 10 | import "unsafe" 11 | 12 | // Get the tree-sitter Language for this grammar. 13 | func Language() unsafe.Pointer { 14 | return unsafe.Pointer(C.tree_sitter_yaml()) 15 | } 16 | -------------------------------------------------------------------------------- /bindings/go/binding_test.go: -------------------------------------------------------------------------------- 1 | package tree_sitter_yaml_test 2 | 3 | import ( 4 | "testing" 5 | 6 | tree_sitter "github.com/tree-sitter/go-tree-sitter" 7 | tree_sitter_yaml "github.com/tree-sitter-grammars/tree-sitter-yaml/bindings/go" 8 | ) 9 | 10 | func TestCanLoadGrammar(t *testing.T) { 11 | language := tree_sitter.NewLanguage(tree_sitter_yaml.Language()) 12 | if language == nil { 13 | t.Errorf("Error loading YAML grammar") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterYAMLTests/TreeSitterYAMLTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftTreeSitter 3 | import TreeSitterYAML 4 | 5 | final class TreeSitterYAMLTests: XCTestCase { 6 | func testCanLoadGrammar() throws { 7 | let parser = Parser() 8 | let language = Language(language: tree_sitter_yaml()) 9 | XCTAssertNoThrow(try parser.setLanguage(language), 10 | "Error loading YAML grammar") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/log-file.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | Time: 2001-11-23 15:01:42 -5 3 | User: ed 4 | Warning: 5 | This is an error message 6 | for the log file 7 | --- 8 | Time: 2001-11-23 15:02:31 -5 9 | User: ed 10 | Warning: 11 | A slightly different error 12 | message. 13 | --- 14 | Date: 2001-11-23 15:03:17 -5 15 | User: ed 16 | Fatal: 17 | Unknown variable "bar" 18 | Stack: 19 | - file: TopClass.py 20 | line: 23 21 | code: | 22 | x = MoreObject("345\n") 23 | - file: MoreClass.py 24 | line: 58 25 | code: |- 26 | foo = bar 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /bindings/node/index.d.ts: -------------------------------------------------------------------------------- 1 | type BaseNode = { 2 | type: string; 3 | named: boolean; 4 | }; 5 | 6 | type ChildNode = { 7 | multiple: boolean; 8 | required: boolean; 9 | types: BaseNode[]; 10 | }; 11 | 12 | type NodeInfo = 13 | | (BaseNode & { 14 | subtypes: BaseNode[]; 15 | }) 16 | | (BaseNode & { 17 | fields: { [name: string]: ChildNode }; 18 | children: ChildNode[]; 19 | }); 20 | 21 | type Language = { 22 | language: unknown; 23 | nodeTypeInfo: NodeInfo[]; 24 | }; 25 | 26 | declare const language: Language; 27 | export = language; 28 | -------------------------------------------------------------------------------- /schema/json/grammar.js: -------------------------------------------------------------------------------- 1 | /** @see {@link JSON Schema|https://yaml.org/spec/1.2.2/#102-json-schema} */ 2 | 3 | /// 4 | 5 | module.exports = grammar({ 6 | name: "json_schema", 7 | 8 | extras: _ => [], 9 | 10 | rules: { 11 | scalar: $ => choice($.null, $.bool, $.int, $.float), 12 | 13 | null: _ => token("null"), 14 | 15 | bool: _ => token(choice("true", "false")), 16 | 17 | int: _ => token(/-?(0|[1-9][0-9]*)/), 18 | 19 | float: _ => token(/-?(0|[1-9][0-9]*)(\.[0-9]*)?([eE][-+]?[0-9]+)?/), 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /bindings/node/index.js: -------------------------------------------------------------------------------- 1 | const root = require('path').join(__dirname, '..', '..'); 2 | 3 | module.exports = 4 | typeof process.versions.bun === 'string' ? 5 | // Support `bun build --compile` by being statically analyzable enough to find the .node file at build-time 6 | require(`../../prebuilds/${process.platform}-${process.arch}/@tree-sitter-grammars+tree-sitter-yaml.node`) : 7 | require('node-gyp-build')(root); 8 | 9 | try { 10 | module.exports.nodeTypeInfo = require('../../src/node-types.json'); 11 | // eslint-disable-next-line no-unused-vars 12 | } catch (_) { } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Rust artifacts 2 | target/ 3 | 4 | # Node artifacts 5 | build/ 6 | prebuilds/ 7 | node_modules/ 8 | 9 | # Swift artifacts 10 | .build/ 11 | 12 | # Go artifacts 13 | _obj/ 14 | 15 | # Python artifacts 16 | .venv/ 17 | dist/ 18 | *.egg-info 19 | *.whl 20 | 21 | # C artifacts 22 | *.a 23 | *.so 24 | *.so.* 25 | *.dylib 26 | *.dll 27 | *.pc 28 | *.exp 29 | *.lib 30 | 31 | # Zig artifacts 32 | .zig-cache/ 33 | zig-cache/ 34 | zig-out/ 35 | 36 | # Example dirs 37 | /examples/*/ 38 | 39 | # Grammar volatiles 40 | *.wasm 41 | *.obj 42 | *.o 43 | 44 | # Archives 45 | *.tar.gz 46 | *.tgz 47 | *.zip 48 | -------------------------------------------------------------------------------- /.github/workflows/fuzz.yml: -------------------------------------------------------------------------------- 1 | name: Fuzz 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - src/schema.core.c 8 | - src/scanner.c 9 | pull_request: 10 | paths: 11 | - src/schema.core.c 12 | - src/scanner.c 13 | 14 | concurrency: 15 | group: ${{github.workflow}}-${{github.ref}} 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | fuzz: 20 | name: Fuzz scanner 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout repository 24 | uses: actions/checkout@v4 25 | - name: Run fuzzer 26 | uses: tree-sitter/fuzz-action@v4 27 | -------------------------------------------------------------------------------- /bindings/node/binding.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | extern "C" TSLanguage *tree_sitter_yaml(); 6 | 7 | // "tree-sitter", "language" hashed with BLAKE2 8 | const napi_type_tag LANGUAGE_TYPE_TAG = { 9 | 0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16 10 | }; 11 | 12 | Napi::Object Init(Napi::Env env, Napi::Object exports) { 13 | auto language = Napi::External::New(env, tree_sitter_yaml()); 14 | language.TypeTag(&LANGUAGE_TYPE_TAG); 15 | exports["language"] = language; 16 | return exports; 17 | } 18 | 19 | NODE_API_MODULE(tree_sitter_yaml_binding, Init) 20 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - grammar.js 8 | pull_request: 9 | paths: 10 | - grammar.js 11 | 12 | jobs: 13 | lint: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v4 18 | - name: Set up Node.js 19 | uses: actions/setup-node@v4 20 | with: 21 | cache: npm 22 | node-version: ${{vars.NODE_VERSION}} 23 | - name: Install modules 24 | run: npm ci --legacy-peer-deps 25 | - name: Run ESLint 26 | run: npm run lint 27 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "SwiftTreeSitter", 6 | "repositoryURL": "https://github.com/tree-sitter/swift-tree-sitter", 7 | "state": { 8 | "branch": null, 9 | "revision": "36aa61d1b531f744f35229f010efba9c6d6cbbdd", 10 | "version": "0.9.0" 11 | } 12 | }, 13 | { 14 | "package": "TreeSitter", 15 | "repositoryURL": "https://github.com/tree-sitter/tree-sitter", 16 | "state": { 17 | "branch": null, 18 | "revision": "d97db6d63507eb62c536bcb2c4ac7d70c8ec665e", 19 | "version": "0.23.2" 20 | } 21 | } 22 | ] 23 | }, 24 | "version": 1 25 | } 26 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | 6 | [*.{json,toml,yml,gyp}] 7 | indent_style = space 8 | indent_size = 2 9 | 10 | [*.js] 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.scm] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | [*.{c,cc,h}] 19 | indent_style = space 20 | indent_size = 4 21 | 22 | [*.rs] 23 | indent_style = space 24 | indent_size = 4 25 | 26 | [*.{py,pyi}] 27 | indent_style = space 28 | indent_size = 4 29 | 30 | [*.swift] 31 | indent_style = space 32 | indent_size = 4 33 | 34 | [*.go] 35 | indent_style = tab 36 | indent_size = 8 37 | 38 | [Makefile] 39 | indent_style = tab 40 | indent_size = 8 41 | 42 | [parser.c] 43 | indent_size = 2 44 | 45 | [{alloc,array,parser}.h] 46 | indent_size = 2 47 | -------------------------------------------------------------------------------- /examples/invoice.yaml: -------------------------------------------------------------------------------- 1 | --- ! 2 | invoice: 34843 3 | date : 2001-01-23 4 | bill-to: &id001 5 | given : Chris 6 | family : Dumars 7 | address: 8 | lines: | 9 | 458 Walkman Dr. 10 | Suite #292 11 | city : Royal Oak 12 | state : MI 13 | postal : 48046 14 | ship-to: *id001 15 | product: 16 | - sku : BL394D 17 | quantity : 4 18 | description : Basketball 19 | price : 450.00 20 | - sku : BL4438H 21 | quantity : 1 22 | description : Super Hoop 23 | price : 2392.00 24 | tax : 251.42 25 | total: 4443.52 26 | comments: 27 | Late afternoon is best. 28 | Backup contact is Nancy 29 | Billsmer @ 338-4338. 30 | -------------------------------------------------------------------------------- /schema/core/src/node-types.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "scalar", 4 | "named": true, 5 | "root": true, 6 | "fields": {}, 7 | "children": { 8 | "multiple": false, 9 | "required": true, 10 | "types": [ 11 | { 12 | "type": "bool", 13 | "named": true 14 | }, 15 | { 16 | "type": "float", 17 | "named": true 18 | }, 19 | { 20 | "type": "int", 21 | "named": true 22 | }, 23 | { 24 | "type": "null", 25 | "named": true 26 | } 27 | ] 28 | } 29 | }, 30 | { 31 | "type": "bool", 32 | "named": true 33 | }, 34 | { 35 | "type": "float", 36 | "named": true 37 | }, 38 | { 39 | "type": "int", 40 | "named": true 41 | }, 42 | { 43 | "type": "null", 44 | "named": true 45 | } 46 | ] -------------------------------------------------------------------------------- /schema/json/src/node-types.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "scalar", 4 | "named": true, 5 | "root": true, 6 | "fields": {}, 7 | "children": { 8 | "multiple": false, 9 | "required": true, 10 | "types": [ 11 | { 12 | "type": "bool", 13 | "named": true 14 | }, 15 | { 16 | "type": "float", 17 | "named": true 18 | }, 19 | { 20 | "type": "int", 21 | "named": true 22 | }, 23 | { 24 | "type": "null", 25 | "named": true 26 | } 27 | ] 28 | } 29 | }, 30 | { 31 | "type": "bool", 32 | "named": true 33 | }, 34 | { 35 | "type": "float", 36 | "named": true 37 | }, 38 | { 39 | "type": "int", 40 | "named": true 41 | }, 42 | { 43 | "type": "null", 44 | "named": true 45 | } 46 | ] -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish package 2 | 3 | on: 4 | push: 5 | tags: ["*"] 6 | 7 | permissions: 8 | contents: write 9 | id-token: write 10 | attestations: write 11 | 12 | jobs: 13 | github: 14 | uses: tree-sitter/workflows/.github/workflows/release.yml@main 15 | with: 16 | attestations: true 17 | npm: 18 | uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main 19 | secrets: 20 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 21 | with: 22 | package-name: "@tree-sitter-grammars/tree-sitter-yaml" 23 | crates: 24 | uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main 25 | secrets: 26 | CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_TOKEN}} 27 | pypi: 28 | uses: tree-sitter/workflows/.github/workflows/package-pypi.yml@main 29 | secrets: 30 | PYPI_API_TOKEN: ${{secrets.PYPI_TOKEN}} 31 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_yaml/__init__.py: -------------------------------------------------------------------------------- 1 | """YAML grammar for tree-sitter""" 2 | 3 | from importlib.resources import files as _files 4 | 5 | from ._binding import language 6 | 7 | 8 | def _get_query(name, file): 9 | query = _files(f"{__package__}.queries") / file 10 | globals()[name] = query.read_text() 11 | return globals()[name] 12 | 13 | 14 | def __getattr__(name): 15 | if name == "HIGHLIGHTS_QUERY": 16 | return _get_query("HIGHLIGHTS_QUERY", "highlights.scm") 17 | 18 | raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 19 | 20 | 21 | __all__ = [ 22 | "language", 23 | "HIGHLIGHTS_QUERY", 24 | ] 25 | 26 | 27 | def __dir__(): 28 | return sorted(__all__ + [ 29 | "__all__", "__builtins__", "__cached__", "__doc__", "__file__", 30 | "__loader__", "__name__", "__package__", "__path__", "__spec__", 31 | ]) 32 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-yaml" 3 | description = "YAML grammar for tree-sitter" 4 | version = "0.7.2" 5 | authors = ["Ika ", "Amaan Qureshi "] 6 | license = "MIT" 7 | readme = "README.md" 8 | keywords = ["incremental", "parsing", "tree-sitter", "yaml"] 9 | categories = ["parser-implementations", "parsing", "text-editors"] 10 | repository = "https://github.com/tree-sitter-grammars/tree-sitter-yaml" 11 | edition = "2021" 12 | autoexamples = false 13 | 14 | build = "bindings/rust/build.rs" 15 | include = [ 16 | "bindings/rust/*", 17 | "grammar.js", 18 | "queries/*", 19 | "src/*", 20 | "tree-sitter.json", 21 | "/LICENSE", 22 | ] 23 | 24 | [lib] 25 | path = "bindings/rust/lib.rs" 26 | 27 | [dependencies] 28 | tree-sitter-language = "0.1" 29 | 30 | [build-dependencies] 31 | cc = "1.2" 32 | 33 | [dev-dependencies] 34 | tree-sitter = "0.25.4" 35 | -------------------------------------------------------------------------------- /bindings/rust/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let src_dir = std::path::Path::new("src"); 3 | 4 | let mut c_config = cc::Build::new(); 5 | c_config.std("c11").include(src_dir); 6 | c_config 7 | .flag_if_supported("-Wno-unused-but-set-variable") 8 | .flag_if_supported("-Wno-unused-value") 9 | .flag_if_supported("-Wno-implicit-fallthrough"); 10 | 11 | #[cfg(target_env = "msvc")] 12 | c_config.flag("-utf-8"); 13 | 14 | let parser_path = src_dir.join("parser.c"); 15 | c_config.file(&parser_path); 16 | println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); 17 | 18 | let scanner_path = src_dir.join("scanner.c"); 19 | if scanner_path.exists() { 20 | c_config.file(&scanner_path); 21 | println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); 22 | } 23 | 24 | c_config.compile("tree-sitter-yaml"); 25 | } 26 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_yaml_binding", 5 | "dependencies": [ 6 | " 4 | 5 | module.exports = grammar({ 6 | name: "core_schema", 7 | 8 | extras: _ => [], 9 | 10 | rules: { 11 | scalar: $ => choice($.null, $.bool, $.int, $.float), 12 | 13 | null: _ => token(choice("~", "null", "Null", "NULL")), 14 | 15 | bool: _ => token(choice("true", "True", "TRUE", "false", "False", "FALSE")), 16 | 17 | int: _ => token(choice( 18 | /[-+]?[0-9]+/, // base 10 19 | /0o[0-7]+/, // base 8 20 | /0x[0-9a-fA-F]+/, // base 12 21 | )), 22 | 23 | float: _ => token(choice( 24 | /[-+]?(\.\d+|\d+(\.\d*)?)([eE][-+]?\d+)?/, // number 25 | seq( 26 | optional(choice("-", "+")), 27 | choice(".inf", ".Inf", ".INF") 28 | ), // infinity 29 | choice(".nan", ".NaN", ".NAN"), // not a number 30 | )), 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "tree-sitter-yaml" 7 | description = "YAML grammar for tree-sitter" 8 | version = "0.7.2" 9 | keywords = ["incremental", "parsing", "tree-sitter", "yaml"] 10 | classifiers = [ 11 | "Intended Audience :: Developers", 12 | "Topic :: Software Development :: Compilers", 13 | "Topic :: Text Processing :: Linguistic", 14 | "Typing :: Typed", 15 | ] 16 | authors = [ 17 | { name = "Ika", email = "ikatyang@gmail.com" }, 18 | { name = "Amaan Qureshi", email = "amaanq12@gmail.com" }, 19 | ] 20 | requires-python = ">=3.10" 21 | license.text = "MIT" 22 | readme = "README.md" 23 | 24 | [project.urls] 25 | Homepage = "https://github.com/tree-sitter-grammars/tree-sitter-yaml" 26 | 27 | [project.optional-dependencies] 28 | core = ["tree-sitter~=0.24"] 29 | 30 | [tool.cibuildwheel] 31 | build = "cp310-*" 32 | build-frontend = "build" 33 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_yaml/binding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | TSLanguage *tree_sitter_yaml(void); 6 | 7 | static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { 8 | return PyCapsule_New(tree_sitter_yaml(), "tree_sitter.Language", NULL); 9 | } 10 | 11 | static struct PyModuleDef_Slot slots[] = { 12 | #ifdef Py_GIL_DISABLED 13 | {Py_mod_gil, Py_MOD_GIL_NOT_USED}, 14 | #endif 15 | {0, NULL} 16 | }; 17 | 18 | static PyMethodDef methods[] = { 19 | {"language", _binding_language, METH_NOARGS, 20 | "Get the tree-sitter language for this grammar."}, 21 | {NULL, NULL, 0, NULL} 22 | }; 23 | 24 | static struct PyModuleDef module = { 25 | .m_base = PyModuleDef_HEAD_INIT, 26 | .m_name = "_binding", 27 | .m_doc = NULL, 28 | .m_size = 0, 29 | .m_methods = methods, 30 | .m_slots = slots, 31 | }; 32 | 33 | PyMODINIT_FUNC PyInit__binding(void) { 34 | return PyModuleDef_Init(&module); 35 | } 36 | -------------------------------------------------------------------------------- /tree-sitter.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/config.schema.json", 3 | "grammars": [ 4 | { 5 | "name": "yaml", 6 | "camelcase": "YAML", 7 | "title": "YAML", 8 | "scope": "source.yaml", 9 | "file-types": [ 10 | "yml", 11 | "yaml" 12 | ], 13 | "highlights": "queries/highlights.scm", 14 | "class-name": "TreeSitterYAML", 15 | "injection-regex": "^yaml$" 16 | } 17 | ], 18 | "metadata": { 19 | "version": "0.7.2", 20 | "license": "MIT", 21 | "description": "YAML grammar for tree-sitter", 22 | "authors": [ 23 | { 24 | "name": "Ika", 25 | "email": "ikatyang@gmail.com", 26 | "url": "https://github.com/ikatyang" 27 | }, 28 | { 29 | "name": "Amaan Qureshi", 30 | "email": "amaanq12@gmail.com" 31 | } 32 | ], 33 | "links": { 34 | "repository": "https://github.com/tree-sitter-grammars/tree-sitter-yaml" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /schema/legacy/src/node-types.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "scalar", 4 | "named": true, 5 | "root": true, 6 | "fields": {}, 7 | "children": { 8 | "multiple": false, 9 | "required": true, 10 | "types": [ 11 | { 12 | "type": "bool", 13 | "named": true 14 | }, 15 | { 16 | "type": "float", 17 | "named": true 18 | }, 19 | { 20 | "type": "int", 21 | "named": true 22 | }, 23 | { 24 | "type": "null", 25 | "named": true 26 | }, 27 | { 28 | "type": "timestamp", 29 | "named": true 30 | } 31 | ] 32 | } 33 | }, 34 | { 35 | "type": "bool", 36 | "named": true 37 | }, 38 | { 39 | "type": "float", 40 | "named": true 41 | }, 42 | { 43 | "type": "int", 44 | "named": true 45 | }, 46 | { 47 | "type": "null", 48 | "named": true 49 | }, 50 | { 51 | "type": "timestamp", 52 | "named": true 53 | } 54 | ] -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | 3 | # Generated source files 4 | src/*.json linguist-generated 5 | src/parser.c linguist-generated 6 | src/tree_sitter/* linguist-generated 7 | 8 | # C bindings 9 | bindings/c/** linguist-generated 10 | CMakeLists.txt linguist-generated 11 | Makefile linguist-generated 12 | 13 | # Rust bindings 14 | bindings/rust/* linguist-generated 15 | Cargo.toml linguist-generated 16 | Cargo.lock linguist-generated 17 | 18 | # Node.js bindings 19 | bindings/node/* linguist-generated 20 | binding.gyp linguist-generated 21 | package.json linguist-generated 22 | package-lock.json linguist-generated 23 | 24 | # Python bindings 25 | bindings/python/** linguist-generated 26 | setup.py linguist-generated 27 | pyproject.toml linguist-generated 28 | 29 | # Go bindings 30 | bindings/go/* linguist-generated 31 | go.mod linguist-generated 32 | go.sum linguist-generated 33 | 34 | # Swift bindings 35 | bindings/swift/** linguist-generated 36 | Package.swift linguist-generated 37 | Package.resolved linguist-generated 38 | 39 | # Zig bindings 40 | build.zig linguist-generated 41 | build.zig.zon linguist-generated 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-yaml 2 | 3 | [![CI][ci]](https://github.com/tree-sitter-grammars/tree-sitter-yaml/actions) 4 | [![discord][discord]](https://discord.gg/w7nTvsVJhm) 5 | [![matrix][matrix]](https://matrix.to/#/#tree-sitter-chat:matrix.org) 6 | [![npm][npm]](https://www.npmjs.com/package/@tree-sitter-grammars/tree-sitter-yaml) 7 | [![crates][crates]](https://crates.io/crates/tree-sitter-yaml) 8 | [![pypi][pypi]](https://pypi.org/project/tree-sitter-yaml/) 9 | 10 | A tree-sitter parser for YAML files. 11 | 12 | ## References 13 | 14 | - [YAML version 1.2](https://yaml.org/spec/1.2.2/) 15 | 16 | [ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter-grammars/tree-sitter-yaml/ci.yml?logo=github&label=CI 17 | [discord]: https://img.shields.io/discord/1063097320771698699?logo=discord&label=discord 18 | [matrix]: https://img.shields.io/matrix/tree-sitter-chat%3Amatrix.org?logo=matrix&label=matrix 19 | [npm]: https://img.shields.io/npm/v/%40tree-sitter-grammars%2Ftree-sitter-yaml?logo=npm 20 | [crates]: https://img.shields.io/crates/v/tree-sitter-yaml?logo=rust 21 | [pypi]: https://img.shields.io/pypi/v/tree-sitter-yaml?logo=pypi&logoColor=ffd242 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 tree-sitter-grammars contributors 2 | Copyright (c) 2019-2021 Ika 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /test/highlight/core.yaml: -------------------------------------------------------------------------------- 1 | A null: null 2 | # <- @property 3 | # ^ @punctuation.delimiter 4 | # ^^^^ @constant.builtin 5 | Also a null: # Empty 6 | # ^^^^^^^ @comment 7 | Not a null: "" 8 | # ^^ @string 9 | Booleans: [ true, True, false, FALSE ] 10 | # ^ @punctuation.bracket 11 | # ^ @punctuation.bracket 12 | # ^ @punctuation.delimiter 13 | # ^^^^ @boolean 14 | # ^^^^ @boolean 15 | # ^^^^^ @boolean 16 | # ^^^^^ @boolean 17 | Integers: [ 0, 0o7, 0x3A, -19 ] 18 | # ^ @number 19 | # ^^^ @number 20 | # ^^^^ @number 21 | # ^^^ @number 22 | Floats: [ 0., -0.0, .5, +12e03, -2E+05 ] 23 | # ^^ @number 24 | # ^^^^ @number 25 | # ^^ @number 26 | # ^^^^^^ @number 27 | # ^^^^^^ @number 28 | Also floats: [ .inf, -.Inf, +.INF, .NAN ] 29 | # ^^^^ @number 30 | # ^^^^^ @number 31 | # ^^^^^ @number 32 | # ^^^^ @number 33 | -------------------------------------------------------------------------------- /src/tree_sitter/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ALLOC_H_ 2 | #define TREE_SITTER_ALLOC_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Allow clients to override allocation functions 13 | #ifdef TREE_SITTER_REUSE_ALLOCATOR 14 | 15 | extern void *(*ts_current_malloc)(size_t size); 16 | extern void *(*ts_current_calloc)(size_t count, size_t size); 17 | extern void *(*ts_current_realloc)(void *ptr, size_t size); 18 | extern void (*ts_current_free)(void *ptr); 19 | 20 | #ifndef ts_malloc 21 | #define ts_malloc ts_current_malloc 22 | #endif 23 | #ifndef ts_calloc 24 | #define ts_calloc ts_current_calloc 25 | #endif 26 | #ifndef ts_realloc 27 | #define ts_realloc ts_current_realloc 28 | #endif 29 | #ifndef ts_free 30 | #define ts_free ts_current_free 31 | #endif 32 | 33 | #else 34 | 35 | #ifndef ts_malloc 36 | #define ts_malloc malloc 37 | #endif 38 | #ifndef ts_calloc 39 | #define ts_calloc calloc 40 | #endif 41 | #ifndef ts_realloc 42 | #define ts_realloc realloc 43 | #endif 44 | #ifndef ts_free 45 | #define ts_free free 46 | #endif 47 | 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif // TREE_SITTER_ALLOC_H_ 55 | -------------------------------------------------------------------------------- /schema/core/src/tree_sitter/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ALLOC_H_ 2 | #define TREE_SITTER_ALLOC_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Allow clients to override allocation functions 13 | #ifdef TREE_SITTER_REUSE_ALLOCATOR 14 | 15 | extern void *(*ts_current_malloc)(size_t size); 16 | extern void *(*ts_current_calloc)(size_t count, size_t size); 17 | extern void *(*ts_current_realloc)(void *ptr, size_t size); 18 | extern void (*ts_current_free)(void *ptr); 19 | 20 | #ifndef ts_malloc 21 | #define ts_malloc ts_current_malloc 22 | #endif 23 | #ifndef ts_calloc 24 | #define ts_calloc ts_current_calloc 25 | #endif 26 | #ifndef ts_realloc 27 | #define ts_realloc ts_current_realloc 28 | #endif 29 | #ifndef ts_free 30 | #define ts_free ts_current_free 31 | #endif 32 | 33 | #else 34 | 35 | #ifndef ts_malloc 36 | #define ts_malloc malloc 37 | #endif 38 | #ifndef ts_calloc 39 | #define ts_calloc calloc 40 | #endif 41 | #ifndef ts_realloc 42 | #define ts_realloc realloc 43 | #endif 44 | #ifndef ts_free 45 | #define ts_free free 46 | #endif 47 | 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif // TREE_SITTER_ALLOC_H_ 55 | -------------------------------------------------------------------------------- /schema/json/src/tree_sitter/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ALLOC_H_ 2 | #define TREE_SITTER_ALLOC_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Allow clients to override allocation functions 13 | #ifdef TREE_SITTER_REUSE_ALLOCATOR 14 | 15 | extern void *(*ts_current_malloc)(size_t size); 16 | extern void *(*ts_current_calloc)(size_t count, size_t size); 17 | extern void *(*ts_current_realloc)(void *ptr, size_t size); 18 | extern void (*ts_current_free)(void *ptr); 19 | 20 | #ifndef ts_malloc 21 | #define ts_malloc ts_current_malloc 22 | #endif 23 | #ifndef ts_calloc 24 | #define ts_calloc ts_current_calloc 25 | #endif 26 | #ifndef ts_realloc 27 | #define ts_realloc ts_current_realloc 28 | #endif 29 | #ifndef ts_free 30 | #define ts_free ts_current_free 31 | #endif 32 | 33 | #else 34 | 35 | #ifndef ts_malloc 36 | #define ts_malloc malloc 37 | #endif 38 | #ifndef ts_calloc 39 | #define ts_calloc calloc 40 | #endif 41 | #ifndef ts_realloc 42 | #define ts_realloc realloc 43 | #endif 44 | #ifndef ts_free 45 | #define ts_free free 46 | #endif 47 | 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif // TREE_SITTER_ALLOC_H_ 55 | -------------------------------------------------------------------------------- /schema/legacy/src/tree_sitter/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ALLOC_H_ 2 | #define TREE_SITTER_ALLOC_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Allow clients to override allocation functions 13 | #ifdef TREE_SITTER_REUSE_ALLOCATOR 14 | 15 | extern void *(*ts_current_malloc)(size_t size); 16 | extern void *(*ts_current_calloc)(size_t count, size_t size); 17 | extern void *(*ts_current_realloc)(void *ptr, size_t size); 18 | extern void (*ts_current_free)(void *ptr); 19 | 20 | #ifndef ts_malloc 21 | #define ts_malloc ts_current_malloc 22 | #endif 23 | #ifndef ts_calloc 24 | #define ts_calloc ts_current_calloc 25 | #endif 26 | #ifndef ts_realloc 27 | #define ts_realloc ts_current_realloc 28 | #endif 29 | #ifndef ts_free 30 | #define ts_free ts_current_free 31 | #endif 32 | 33 | #else 34 | 35 | #ifndef ts_malloc 36 | #define ts_malloc malloc 37 | #endif 38 | #ifndef ts_calloc 39 | #define ts_calloc calloc 40 | #endif 41 | #ifndef ts_realloc 42 | #define ts_realloc realloc 43 | #endif 44 | #ifndef ts_free 45 | #define ts_free free 46 | #endif 47 | 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif // TREE_SITTER_ALLOC_H_ 55 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | 3 | import Foundation 4 | import PackageDescription 5 | 6 | var sources = ["src/parser.c"] 7 | if FileManager.default.fileExists(atPath: "src/scanner.c") { 8 | sources.append("src/scanner.c") 9 | } 10 | 11 | let package = Package( 12 | name: "TreeSitterYAML", 13 | products: [ 14 | .library(name: "TreeSitterYAML", targets: ["TreeSitterYAML"]), 15 | ], 16 | dependencies: [ 17 | .package(name: "SwiftTreeSitter", url: "https://github.com/tree-sitter/swift-tree-sitter", from: "0.9.0"), 18 | ], 19 | targets: [ 20 | .target( 21 | name: "TreeSitterYAML", 22 | dependencies: [], 23 | path: ".", 24 | sources: sources, 25 | resources: [ 26 | .copy("queries") 27 | ], 28 | publicHeadersPath: "bindings/swift", 29 | cSettings: [.headerSearchPath("src")] 30 | ), 31 | .testTarget( 32 | name: "TreeSitterYAMLTests", 33 | dependencies: [ 34 | "SwiftTreeSitter", 35 | "TreeSitterYAML", 36 | ], 37 | path: "bindings/swift/TreeSitterYAMLTests" 38 | ) 39 | ], 40 | cLanguageStandard: .c11 41 | ) 42 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | (boolean_scalar) @boolean 2 | 3 | (null_scalar) @constant.builtin 4 | 5 | [ 6 | (double_quote_scalar) 7 | (single_quote_scalar) 8 | (block_scalar) 9 | (string_scalar) 10 | ] @string 11 | 12 | [ 13 | (integer_scalar) 14 | (float_scalar) 15 | ] @number 16 | 17 | (comment) @comment 18 | 19 | [ 20 | (anchor_name) 21 | (alias_name) 22 | ] @label 23 | 24 | (tag) @type 25 | 26 | [ 27 | (yaml_directive) 28 | (tag_directive) 29 | (reserved_directive) 30 | ] @attribute 31 | 32 | (block_mapping_pair 33 | key: (flow_node 34 | [ 35 | (double_quote_scalar) 36 | (single_quote_scalar) 37 | ] @property)) 38 | 39 | (block_mapping_pair 40 | key: (flow_node 41 | (plain_scalar 42 | (string_scalar) @property))) 43 | 44 | (flow_mapping 45 | (_ 46 | key: (flow_node 47 | [ 48 | (double_quote_scalar) 49 | (single_quote_scalar) 50 | ] @property))) 51 | 52 | (flow_mapping 53 | (_ 54 | key: (flow_node 55 | (plain_scalar 56 | (string_scalar) @property)))) 57 | 58 | [ 59 | "," 60 | "-" 61 | ":" 62 | ">" 63 | "?" 64 | "|" 65 | ] @punctuation.delimiter 66 | 67 | [ 68 | "[" 69 | "]" 70 | "{" 71 | "}" 72 | ] @punctuation.bracket 73 | 74 | [ 75 | "*" 76 | "&" 77 | "---" 78 | "..." 79 | ] @punctuation.special 80 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tree-sitter-grammars/tree-sitter-yaml", 3 | "version": "0.7.2", 4 | "description": "YAML grammar for tree-sitter", 5 | "repository": "https://github.com/tree-sitter-grammars/tree-sitter-yaml", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Ika", 9 | "email": "ikatyang@gmail.com", 10 | "url": "https://github.com/ikatyang" 11 | }, 12 | "maintainers": [ 13 | { 14 | "name": "Amaan Qureshi", 15 | "email": "amaanq12@gmail.com" 16 | } 17 | ], 18 | "main": "bindings/node", 19 | "types": "bindings/node", 20 | "keywords": [ 21 | "incremental", 22 | "parsing", 23 | "tree-sitter", 24 | "yaml" 25 | ], 26 | "files": [ 27 | "grammar.js", 28 | "tree-sitter.json", 29 | "binding.gyp", 30 | "prebuilds/**", 31 | "bindings/node/*", 32 | "queries/*", 33 | "src/**", 34 | "*.wasm" 35 | ], 36 | "dependencies": { 37 | "node-addon-api": "^8.5.0", 38 | "node-gyp-build": "^4.8.4" 39 | }, 40 | "devDependencies": { 41 | "eslint": "^9.16.0", 42 | "eslint-config-treesitter": "^1.0.2", 43 | "prebuildify": "^6.0.1", 44 | "tree-sitter-cli": "^0.25.4" 45 | }, 46 | "peerDependencies": { 47 | "tree-sitter": "^0.22.4" 48 | }, 49 | "peerDependenciesMeta": { 50 | "tree-sitter": { 51 | "optional": true 52 | } 53 | }, 54 | "scripts": { 55 | "install": "node-gyp-build", 56 | "lint": "eslint grammar.js", 57 | "prestart": "tree-sitter build --wasm", 58 | "start": "tree-sitter playground", 59 | "test": "node --test bindings/node/*_test.js" 60 | }, 61 | "publishConfig": { 62 | "access": "public" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /schema/json/src/grammar.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json", 3 | "name": "json_schema", 4 | "rules": { 5 | "scalar": { 6 | "type": "CHOICE", 7 | "members": [ 8 | { 9 | "type": "SYMBOL", 10 | "name": "null" 11 | }, 12 | { 13 | "type": "SYMBOL", 14 | "name": "bool" 15 | }, 16 | { 17 | "type": "SYMBOL", 18 | "name": "int" 19 | }, 20 | { 21 | "type": "SYMBOL", 22 | "name": "float" 23 | } 24 | ] 25 | }, 26 | "null": { 27 | "type": "TOKEN", 28 | "content": { 29 | "type": "STRING", 30 | "value": "null" 31 | } 32 | }, 33 | "bool": { 34 | "type": "TOKEN", 35 | "content": { 36 | "type": "CHOICE", 37 | "members": [ 38 | { 39 | "type": "STRING", 40 | "value": "true" 41 | }, 42 | { 43 | "type": "STRING", 44 | "value": "false" 45 | } 46 | ] 47 | } 48 | }, 49 | "int": { 50 | "type": "TOKEN", 51 | "content": { 52 | "type": "PATTERN", 53 | "value": "-?(0|[1-9][0-9]*)" 54 | } 55 | }, 56 | "float": { 57 | "type": "TOKEN", 58 | "content": { 59 | "type": "PATTERN", 60 | "value": "-?(0|[1-9][0-9]*)(\\.[0-9]*)?([eE][-+]?[0-9]+)?" 61 | } 62 | } 63 | }, 64 | "extras": [], 65 | "conflicts": [], 66 | "precedences": [], 67 | "externals": [], 68 | "inline": [], 69 | "supertypes": [], 70 | "reserved": {} 71 | } -------------------------------------------------------------------------------- /schema/legacy/grammar.js: -------------------------------------------------------------------------------- 1 | /** @see {@link YAML 1.1|https://yaml.org/type/} */ 2 | 3 | /// 4 | 5 | module.exports = grammar({ 6 | name: "legacy_schema", 7 | 8 | extras: _ => [], 9 | 10 | rules: { 11 | scalar: $ => choice($.null, $.bool, $.int, $.float, $.timestamp), 12 | 13 | null: _ => token(choice("~", "null", "Null", "NULL")), 14 | 15 | bool: _ => token(choice( 16 | "y", "Y", "yes", "Yes", "YES", "n", "N", "no", "No", "NO", 17 | "true", "True", "TRUE", "false", "False", "FALSE", 18 | "on", "On", "ON", "off", "Off", "OFF", 19 | )), 20 | 21 | int: _ => token(choice( 22 | /[-+]?0b[0-1_]+/, // base 2 23 | /[-+]?0[0-7_]+/, // base 8 24 | /[-+]?(0|[1-9][0-9_]*)/, // base 10 25 | /[-+]?0x[0-9a-fA-F_]+/, // base 16 26 | /[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+/, // base 60 27 | )), 28 | 29 | float: _ => token(choice( 30 | /[-+]?([0-9][0-9_]*)?\.[0-9.]*([eE][-+][0-9]+)?/, // base 10 31 | /[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*/, // base 60 32 | seq( 33 | optional(choice("-", "+")), 34 | choice(".inf", ".Inf", ".INF") 35 | ), // infinity 36 | choice(".nan", ".NaN", ".NAN"), // not a number 37 | )), 38 | 39 | timestamp: _ => token(choice( 40 | /\d\d\d\d-\d\d-\d\d/, // ymd 41 | seq( 42 | /\d\d\d\d-\d\d?-\d\d?/, // year-month-day 43 | choice("T", "t", /[ \t]+/), 44 | /\d\d?:\d\d:\d\d/, // hour:minute:second 45 | optional(/\.\d+/), // fraction 46 | optional(choice( 47 | /[ \t]*Z/, 48 | /[-+]\d\d?(:\d\d)?/ 49 | )) // time zone 50 | ) 51 | )) 52 | }, 53 | }); 54 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | paths: 7 | - grammar.js 8 | - src/** 9 | - test/** 10 | - bindings/** 11 | - binding.gyp 12 | pull_request: 13 | paths: 14 | - grammar.js 15 | - src/** 16 | - test/** 17 | - bindings/** 18 | - binding.gyp 19 | 20 | concurrency: 21 | group: ${{github.workflow}}-${{github.ref}} 22 | cancel-in-progress: true 23 | 24 | jobs: 25 | test: 26 | name: Test parsers 27 | runs-on: ${{matrix.os}} 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | os: [ubuntu-latest, windows-latest, macos-latest] 32 | steps: 33 | - name: Checkout repository 34 | uses: actions/checkout@v4 35 | with: 36 | submodules: true 37 | - name: Set up tree-sitter 38 | uses: tree-sitter/setup-action/cli@v2 39 | - name: Run tests 40 | uses: tree-sitter/parser-test-action@v2 41 | with: 42 | generate: false 43 | test-rust: true 44 | - name: Set up test suite 45 | shell: bash 46 | run: |- 47 | printf '%s\n' examples/*.yaml > "$RUNNER_TEMP/test-files" 48 | while read -r file; do 49 | printf '%s\n' "$file" >> "$RUNNER_TEMP/test-files" 50 | if [[ -f ${file/in.yaml/error} ]]; then 51 | printf '%s\n' "$file" >> "$RUNNER_TEMP/invalid-files" 52 | fi 53 | done < <(find -L examples/yaml-test-suite/name -name in.yaml) 54 | - name: Parse test suite 55 | uses: tree-sitter/parse-action@v4 56 | with: 57 | files-list: ${{runner.temp}}/test-files 58 | invalid-files-list: ${{runner.temp}}/invalid-files 59 | -------------------------------------------------------------------------------- /bindings/rust/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides YAML language support for the [tree-sitter] parsing library. 2 | //! 3 | //! Typically, you will use the [`LANGUAGE`] constant to add this language to a 4 | //! tree-sitter [`Parser`], and then use the parser to parse some code: 5 | //! 6 | //! ``` 7 | //! let code = r#" 8 | //! key: value 9 | //! list: 10 | //! - item1 11 | //! - item2 12 | //! "#; 13 | //! let mut parser = tree_sitter::Parser::new(); 14 | //! let language = tree_sitter_yaml::LANGUAGE; 15 | //! parser 16 | //! .set_language(&language.into()) 17 | //! .expect("Error loading YAML parser"); 18 | //! let tree = parser.parse(code, None).unwrap(); 19 | //! assert!(!tree.root_node().has_error()); 20 | //! ``` 21 | //! 22 | //! [`Parser`]: https://docs.rs/tree-sitter/0.25.4/tree_sitter/struct.Parser.html 23 | //! [tree-sitter]: https://tree-sitter.github.io/ 24 | 25 | use tree_sitter_language::LanguageFn; 26 | 27 | extern "C" { 28 | fn tree_sitter_yaml() -> *const (); 29 | } 30 | 31 | /// The tree-sitter [`LanguageFn`] for this grammar. 32 | pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_yaml) }; 33 | 34 | /// The content of the [`node-types.json`] file for this grammar. 35 | /// 36 | /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types 37 | pub const NODE_TYPES: &str = include_str!("../../src/node-types.json"); 38 | 39 | /// The highlight queries for this grammar. 40 | pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); 41 | 42 | #[cfg(test)] 43 | mod tests { 44 | #[test] 45 | fn test_can_load_grammar() { 46 | let mut parser = tree_sitter::Parser::new(); 47 | parser 48 | .set_language(&super::LANGUAGE.into()) 49 | .expect("Error loading YAML parser"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | from sysconfig import get_config_var 3 | 4 | from setuptools import Extension, find_packages, setup 5 | from setuptools.command.build import build 6 | from setuptools.command.build_ext import build_ext 7 | from setuptools.command.egg_info import egg_info 8 | from wheel.bdist_wheel import bdist_wheel 9 | 10 | 11 | class Build(build): 12 | def run(self): 13 | if path.isdir("queries"): 14 | dest = path.join(self.build_lib, "tree_sitter_yaml", "queries") 15 | self.copy_tree("queries", dest) 16 | super().run() 17 | 18 | 19 | class BuildExt(build_ext): 20 | def build_extension(self, ext: Extension): 21 | if self.compiler.compiler_type != "msvc": 22 | ext.extra_compile_args = ["-std=c11", "-fvisibility=hidden"] 23 | else: 24 | ext.extra_compile_args = ["/std:c11", "/utf-8"] 25 | if path.exists("src/scanner.c"): 26 | ext.sources.append("src/scanner.c") 27 | if ext.py_limited_api: 28 | ext.define_macros.append(("Py_LIMITED_API", "0x030A0000")) 29 | super().build_extension(ext) 30 | 31 | 32 | class BdistWheel(bdist_wheel): 33 | def get_tag(self): 34 | python, abi, platform = super().get_tag() 35 | if python.startswith("cp"): 36 | python, abi = "cp310", "abi3" 37 | return python, abi, platform 38 | 39 | 40 | class EggInfo(egg_info): 41 | def find_sources(self): 42 | super().find_sources() 43 | self.filelist.recursive_include("queries", "*.scm") 44 | self.filelist.include("src/tree_sitter/*.h") 45 | 46 | 47 | setup( 48 | packages=find_packages("bindings/python"), 49 | package_dir={"": "bindings/python"}, 50 | package_data={ 51 | "tree_sitter_yaml": ["*.pyi", "py.typed"], 52 | "tree_sitter_yaml.queries": ["*.scm"], 53 | }, 54 | ext_package="tree_sitter_yaml", 55 | ext_modules=[ 56 | Extension( 57 | name="_binding", 58 | sources=[ 59 | "bindings/python/tree_sitter_yaml/binding.c", 60 | "src/parser.c", 61 | ], 62 | define_macros=[ 63 | ("PY_SSIZE_T_CLEAN", None), 64 | ("TREE_SITTER_HIDE_SYMBOLS", None), 65 | ], 66 | include_dirs=["src"], 67 | py_limited_api=not get_config_var("Py_GIL_DISABLED"), 68 | ) 69 | ], 70 | cmdclass={ 71 | "build": Build, 72 | "build_ext": BuildExt, 73 | "bdist_wheel": BdistWheel, 74 | "egg_info": EggInfo, 75 | }, 76 | zip_safe=False 77 | ) 78 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | project(tree-sitter-yaml 4 | VERSION "0.7.2" 5 | DESCRIPTION "YAML grammar for tree-sitter" 6 | HOMEPAGE_URL "https://github.com/tree-sitter-grammars/tree-sitter-yaml" 7 | LANGUAGES C) 8 | 9 | option(BUILD_SHARED_LIBS "Build using shared libraries" ON) 10 | option(TREE_SITTER_REUSE_ALLOCATOR "Reuse the library allocator" OFF) 11 | 12 | set(TREE_SITTER_ABI_VERSION 14 CACHE STRING "Tree-sitter ABI version") 13 | if(NOT ${TREE_SITTER_ABI_VERSION} MATCHES "^[0-9]+$") 14 | unset(TREE_SITTER_ABI_VERSION CACHE) 15 | message(FATAL_ERROR "TREE_SITTER_ABI_VERSION must be an integer") 16 | endif() 17 | 18 | find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI") 19 | 20 | add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" 21 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" 22 | COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json 23 | --abi=${TREE_SITTER_ABI_VERSION} 24 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 25 | COMMENT "Generating parser.c") 26 | 27 | add_library(tree-sitter-yaml src/parser.c) 28 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c) 29 | target_sources(tree-sitter-yaml PRIVATE src/scanner.c) 30 | endif() 31 | target_include_directories(tree-sitter-yaml 32 | PRIVATE src 33 | INTERFACE $ 34 | $) 35 | 36 | 37 | set(YAML_SCHEMA core CACHE STRING "YAML schema") 38 | set(YAML_SCHEMA_VALUES core json legacy CACHE INTERNAL "Allowed schemas") 39 | set_property(CACHE YAML_SCHEMA PROPERTY STRINGS ${YAML_SCHEMA_VALUES}) 40 | if(NOT YAML_SCHEMA IN_LIST YAML_SCHEMA_VALUES) 41 | message(FATAL_ERROR "YAML_SCHEMA must be one of ${YAML_SCHEMA_VALUES}") 42 | endif() 43 | 44 | target_compile_definitions(tree-sitter-yaml PRIVATE 45 | $<$:TREE_SITTER_REUSE_ALLOCATOR> 46 | $<$:TREE_SITTER_DEBUG> 47 | YAML_SCHEMA=${YAML_SCHEMA}) 48 | 49 | set_target_properties(tree-sitter-yaml 50 | PROPERTIES 51 | C_STANDARD 11 52 | POSITION_INDEPENDENT_CODE ON 53 | SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}" 54 | DEFINE_SYMBOL "") 55 | 56 | configure_file(bindings/c/tree-sitter-yaml.pc.in 57 | "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-yaml.pc" @ONLY) 58 | 59 | include(GNUInstallDirs) 60 | 61 | install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bindings/c/tree_sitter" 62 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" 63 | FILES_MATCHING PATTERN "*.h") 64 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-yaml.pc" 65 | DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig") 66 | install(TARGETS tree-sitter-yaml 67 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") 68 | 69 | file(GLOB QUERIES queries/*.scm) 70 | install(FILES ${QUERIES} 71 | DESTINATION "${CMAKE_INSTALL_DATADIR}/tree-sitter/queries/yaml") 72 | 73 | add_custom_target(ts-test "${TREE_SITTER_CLI}" test 74 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 75 | COMMENT "tree-sitter test") 76 | -------------------------------------------------------------------------------- /src/schema.json.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #define SCH_STT_FRZ -1 6 | 7 | #define HAS_TIMESTAMP 0 8 | 9 | typedef enum { 10 | RS_STR, 11 | RS_INT, 12 | RS_BOOL, 13 | RS_NULL, 14 | RS_FLOAT, 15 | } ResultSchema; 16 | 17 | static int8_t adv_sch_stt(int8_t sch_stt, int32_t cur_chr, ResultSchema *rlt_sch) { 18 | switch (sch_stt) { 19 | case SCH_STT_FRZ: 20 | break; 21 | case 0: 22 | if (cur_chr == '-') {*rlt_sch = RS_STR; return 1;} 23 | if (cur_chr == '0') {*rlt_sch = RS_INT; return 16;} 24 | if (cur_chr == 'f') {*rlt_sch = RS_STR; return 2;} 25 | if (cur_chr == 'n') {*rlt_sch = RS_STR; return 10;} 26 | if (cur_chr == 't') {*rlt_sch = RS_STR; return 7;} 27 | if (('1' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_INT; return 17;} 28 | break; 29 | case 1: 30 | if (cur_chr == '0') {*rlt_sch = RS_INT; return 16;} 31 | if (('1' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_INT; return 17;} 32 | break; 33 | case 2: 34 | if (cur_chr == 'a') {*rlt_sch = RS_STR; return 4;} 35 | break; 36 | case 3: 37 | if (cur_chr == 'e') {*rlt_sch = RS_BOOL; return 15;} 38 | break; 39 | case 4: 40 | if (cur_chr == 'l') {*rlt_sch = RS_STR; return 8;} 41 | break; 42 | case 5: 43 | if (cur_chr == 'l') {*rlt_sch = RS_NULL; return 14;} 44 | break; 45 | case 6: 46 | if (cur_chr == 'l') {*rlt_sch = RS_STR; return 5;} 47 | break; 48 | case 7: 49 | if (cur_chr == 'r') {*rlt_sch = RS_STR; return 9;} 50 | break; 51 | case 8: 52 | if (cur_chr == 's') {*rlt_sch = RS_STR; return 3;} 53 | break; 54 | case 9: 55 | if (cur_chr == 'u') {*rlt_sch = RS_STR; return 3;} 56 | break; 57 | case 10: 58 | if (cur_chr == 'u') {*rlt_sch = RS_STR; return 6;} 59 | break; 60 | case 11: 61 | if (cur_chr == '+' || 62 | cur_chr == '-') {*rlt_sch = RS_STR; return 12;} 63 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 19;} 64 | break; 65 | case 12: 66 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 19;} 67 | break; 68 | case 13: 69 | abort(); 70 | break; 71 | case 14: 72 | *rlt_sch = RS_NULL; 73 | break; 74 | case 15: 75 | *rlt_sch = RS_BOOL; 76 | break; 77 | case 16: 78 | *rlt_sch = RS_INT; 79 | if (cur_chr == '.') {*rlt_sch = RS_FLOAT; return 18;} 80 | if (cur_chr == 'E' || 81 | cur_chr == 'e') {*rlt_sch = RS_STR; return 11;} 82 | break; 83 | case 17: 84 | *rlt_sch = RS_INT; 85 | if (cur_chr == '.') {*rlt_sch = RS_FLOAT; return 18;} 86 | if (cur_chr == 'E' || 87 | cur_chr == 'e') {*rlt_sch = RS_STR; return 11;} 88 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_INT; return 17;} 89 | break; 90 | case 18: 91 | *rlt_sch = RS_FLOAT; 92 | if (cur_chr == 'E' || 93 | cur_chr == 'e') {*rlt_sch = RS_STR; return 11;} 94 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 18;} 95 | break; 96 | case 19: 97 | *rlt_sch = RS_FLOAT; 98 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 19;} 99 | break; 100 | default: 101 | *rlt_sch = RS_STR; 102 | return SCH_STT_FRZ; 103 | } 104 | if (cur_chr != '\r' && cur_chr != '\n' && cur_chr != ' ' && cur_chr != 0) *rlt_sch = RS_STR; 105 | return SCH_STT_FRZ; 106 | } 107 | -------------------------------------------------------------------------------- /test/corpus/09_streams.txt: -------------------------------------------------------------------------------- 1 | ============================================================================|||| 2 | Document Prefix 3 | ============================================================================|||| 4 | # Comment 5 | # lines 6 | Document 7 | 8 | ----------------------------------------------------------------------------|||| 9 | 10 | (stream 11 | (comment) 12 | (comment) 13 | (document 14 | (flow_node 15 | (plain_scalar 16 | (string_scalar))))) 17 | 18 | ============================================================================|||| 19 | Document Markers 20 | ============================================================================|||| 21 | %YAML 1.2 22 | --- 23 | Document 24 | ... # Suffix 25 | 26 | ----------------------------------------------------------------------------|||| 27 | 28 | (stream 29 | (document 30 | (yaml_directive 31 | (yaml_version)) 32 | (flow_node 33 | (plain_scalar 34 | (string_scalar)))) 35 | (comment)) 36 | 37 | ============================================================================|||| 38 | Bare Documents 39 | ============================================================================|||| 40 | Bare 41 | document 42 | ... 43 | # No document 44 | ... 45 | | 46 | %!PS-Adobe-2.0 # Not the first line 47 | 48 | ----------------------------------------------------------------------------|||| 49 | 50 | (stream 51 | (document 52 | (flow_node 53 | (plain_scalar 54 | (string_scalar)))) 55 | (comment) 56 | (document) 57 | (document 58 | (block_node 59 | (block_scalar)))) 60 | 61 | ============================================================================|||| 62 | Explicit Documents 63 | ============================================================================|||| 64 | --- 65 | { matches 66 | % : 20 } 67 | ... 68 | --- 69 | # Empty 70 | ... 71 | 72 | ----------------------------------------------------------------------------|||| 73 | 74 | (stream 75 | (document 76 | (flow_node 77 | (flow_mapping 78 | (flow_pair 79 | (flow_node 80 | (plain_scalar 81 | (string_scalar))) 82 | (flow_node 83 | (plain_scalar 84 | (integer_scalar))))))) 85 | (document 86 | (comment))) 87 | 88 | ============================================================================|||| 89 | Directives Documents 90 | ============================================================================|||| 91 | %YAML 1.2 92 | --- | 93 | %!PS-Adobe-2.0 94 | ... 95 | %YAML1.2 96 | --- 97 | # Empty 98 | ... 99 | 100 | ----------------------------------------------------------------------------|||| 101 | 102 | (stream 103 | (document 104 | (yaml_directive 105 | (yaml_version)) 106 | (block_node 107 | (block_scalar))) 108 | (document 109 | (reserved_directive 110 | (directive_name)) 111 | (comment))) 112 | 113 | ============================================================================|||| 114 | Stream 115 | ============================================================================|||| 116 | Document 117 | --- 118 | # Empty 119 | ... 120 | %YAML 1.2 121 | --- 122 | matches %: 20 123 | 124 | ----------------------------------------------------------------------------|||| 125 | 126 | (stream 127 | (document 128 | (flow_node 129 | (plain_scalar 130 | (string_scalar)))) 131 | (document 132 | (comment)) 133 | (document 134 | (yaml_directive 135 | (yaml_version)) 136 | (block_node 137 | (block_mapping 138 | (block_mapping_pair 139 | (flow_node 140 | (plain_scalar 141 | (string_scalar))) 142 | (flow_node 143 | (plain_scalar 144 | (integer_scalar)))))))) 145 | 146 | -------------------------------------------------------------------------------- /schema/update-schema.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // @ts-nocheck 4 | 5 | const { writeFileSync } = require("fs"); 6 | const { readFile } = require("fs/promises"); 7 | const { join } = require("path"); 8 | 9 | const schema = process.argv[2] ?? "core"; 10 | 11 | readFile(join(__dirname, schema, "src", "parser.c"), "utf8").then(input => { 12 | const cases = extractCases(input); 13 | const enums = ["RS_STR"]; 14 | const content = "switch (sch_stt) " + block([ 15 | "case SCH_STT_FRZ:\n break;", 16 | cases 17 | .map(([key, { content }]) => `${(key === "default" ? "default:" : `case ${key}:`)}\n${indent(content)}`) 18 | .join("\n END_STATE();\n") 19 | .replace(/\s+ADVANCE_MAP\(([^]+?)\);\n/, (_, map) => { 20 | return map.replace(/'(.)', (\d+),/g, "if (lookahead == '$1') ADVANCE($2);"); 21 | }) 22 | .replace(/ADVANCE\((\d+)\);/g, (_, state) => { 23 | const stateCase = cases.find(([key]) => key === state); 24 | if (stateCase) { 25 | const [, { acceptToken }] = stateCase; 26 | if (acceptToken) { 27 | return `{${acceptToken} return ${state};}`; 28 | } 29 | } 30 | return `{*rlt_sch = RS_STR; return ${state};}`; 31 | }) 32 | .replace("ACCEPT_TOKEN(ts_builtin_sym_end);", "abort();") 33 | .replace(/ACCEPT_TOKEN\((\w+)\);/g, (_, name) => { 34 | const newName = "RS_" + convertName(name); 35 | if (!enums.includes(newName)) { 36 | enums.push(newName); 37 | } 38 | return `*rlt_sch = ${newName};`; 39 | }) 40 | .replace(/END_STATE\(\);/g, `break;`) 41 | .replace("return false;", '*rlt_sch = RS_STR;\n return SCH_STT_FRZ;') 42 | .replace(/lookahead/g, "cur_chr"), 43 | ]); 44 | const has_timestamp = enums.includes("RS_TIMESTAMP") ? 1 : 0; 45 | writeFileSync( 46 | join(__dirname, "..", "src", `schema.${schema}.c`), 47 | [ 48 | "#include ", 49 | "#include ", 50 | "#define SCH_STT_FRZ -1", 51 | `#define HAS_TIMESTAMP ${has_timestamp}`, 52 | `typedef enum ${block(enums.map((k) => `${k},`))} ResultSchema;`, 53 | `static int8_t adv_sch_stt(int8_t sch_stt, int32_t cur_chr, ResultSchema *rlt_sch) ${block([ 54 | content, 55 | `if (cur_chr != '\\r' && cur_chr != '\\n' && cur_chr != ' ' && cur_chr != 0) *rlt_sch = RS_STR;`, 56 | "return SCH_STT_FRZ;", 57 | ])}`, 58 | ].join("\n\n") + "\n", 59 | ); 60 | }); 61 | 62 | function extractCases(input) { 63 | const MAIN_SIGNATURE = "static bool ts_lex(TSLexer *lexer, TSStateId state) {"; 64 | const SWITCH_CASE = "switch (state) {\n"; 65 | const startIndex = input.indexOf(SWITCH_CASE, input.indexOf(MAIN_SIGNATURE)) + SWITCH_CASE.length; 66 | const endIndex = input.indexOf("}\n}", startIndex); 67 | const content = input.slice(startIndex, endIndex).replace(/^\s*if \(eof\).+\n/mg, "").trimEnd(); 68 | return dedent(dedent(content)).split("END_STATE();").map(text => { 69 | const index = text.indexOf(":\n"); 70 | const key = text.slice(0, index).trim().replace(/^case /, ""); 71 | const content = dedent(text.slice(index + 2)).trim(); 72 | const matchAcceptToken = content.match(/^ACCEPT_TOKEN\(\w+\);/); 73 | const acceptToken = matchAcceptToken && matchAcceptToken[0]; 74 | const hasAcceptTokenOnly = acceptToken && acceptToken.length === content.length; 75 | return [key, { content, acceptToken, hasAcceptTokenOnly }]; 76 | }); 77 | } 78 | 79 | function convertName(name) { 80 | return name.replace("sym_", "").toUpperCase(); 81 | } 82 | 83 | function block(contents) { 84 | return `{\n${indent(contents)}\n}`; 85 | } 86 | 87 | function lines(contents) { 88 | return [].concat(contents).join("\n").split("\n"); 89 | } 90 | 91 | function indent(contents) { 92 | return lines(contents).map(x => " ".repeat(2) + x).join("\n"); 93 | } 94 | 95 | function dedent(contents) { 96 | return lines(contents).map(x => x.replace(/^ /mg, "")).join("\n"); 97 | } 98 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(OS),Windows_NT) 2 | $(error Windows is not supported) 3 | endif 4 | 5 | LANGUAGE_NAME := tree-sitter-yaml 6 | HOMEPAGE_URL := https://github.com/tree-sitter-grammars/tree-sitter-yaml 7 | VERSION := 0.7.2 8 | 9 | # repository 10 | SRC_DIR := src 11 | 12 | TS ?= tree-sitter 13 | 14 | # install directory layout 15 | PREFIX ?= /usr/local 16 | DATADIR ?= $(PREFIX)/share 17 | INCLUDEDIR ?= $(PREFIX)/include 18 | LIBDIR ?= $(PREFIX)/lib 19 | PCLIBDIR ?= $(LIBDIR)/pkgconfig 20 | 21 | # source/object files 22 | PARSER := $(SRC_DIR)/parser.c 23 | EXTRAS := $(SRC_DIR)/scanner.c 24 | OBJS := $(patsubst %.c,%.o,$(PARSER) $(EXTRAS)) 25 | 26 | # schema 27 | YAML_SCHEMA := core 28 | ifeq ($(filter $(YAML_SCHEMA),core json legacy),) 29 | $(error YAML_SCHEMA must be one of core/json/legacy) 30 | endif 31 | 32 | # flags 33 | ARFLAGS ?= rcs 34 | override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC -DYAML_SCHEMA=$(YAML_SCHEMA) 35 | 36 | # ABI versioning 37 | SONAME_MAJOR = $(shell sed -n 's/\#define LANGUAGE_VERSION //p' $(PARSER)) 38 | SONAME_MINOR = $(word 1,$(subst ., ,$(VERSION))) 39 | 40 | # OS-specific bits 41 | ifeq ($(shell uname),Darwin) 42 | SOEXT = dylib 43 | SOEXTVER_MAJOR = $(SONAME_MAJOR).$(SOEXT) 44 | SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT) 45 | LINKSHARED = -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER),-rpath,@executable_path/../Frameworks 46 | else 47 | SOEXT = so 48 | SOEXTVER_MAJOR = $(SOEXT).$(SONAME_MAJOR) 49 | SOEXTVER = $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR) 50 | LINKSHARED = -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER) 51 | endif 52 | ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),) 53 | PCLIBDIR := $(PREFIX)/libdata/pkgconfig 54 | endif 55 | 56 | all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc 57 | 58 | lib$(LANGUAGE_NAME).a: $(OBJS) 59 | $(AR) $(ARFLAGS) $@ $^ 60 | 61 | lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS) 62 | $(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@ 63 | ifneq ($(STRIP),) 64 | $(STRIP) $@ 65 | endif 66 | 67 | $(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in 68 | sed -e 's|@PROJECT_VERSION@|$(VERSION)|' \ 69 | -e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \ 70 | -e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \ 71 | -e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \ 72 | -e 's|@PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \ 73 | -e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@ 74 | 75 | $(PARSER): $(SRC_DIR)/grammar.json 76 | $(TS) generate $^ 77 | 78 | install: all 79 | install -d '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/yaml '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)' 80 | install -m644 bindings/c/tree_sitter/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h 81 | install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 82 | install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a 83 | install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) 84 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) 85 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) 86 | install -m644 queries/*.scm '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/yaml 87 | 88 | uninstall: 89 | $(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \ 90 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \ 91 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \ 92 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \ 93 | '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \ 94 | '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 95 | $(RM) -r '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/yaml 96 | 97 | clean: 98 | $(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) 99 | 100 | test: 101 | $(TS) test 102 | 103 | .PHONY: all install uninstall clean test 104 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= 4 | github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= 5 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 8 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 9 | github.com/tree-sitter/go-tree-sitter v0.24.0 h1:kRZb6aBNfcI/u0Qh8XEt3zjNVnmxTisDBN+kXK0xRYQ= 10 | github.com/tree-sitter/go-tree-sitter v0.24.0/go.mod h1:x681iFVoLMEwOSIHA1chaLkXlroXEN7WY+VHGFaoDbk= 11 | github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb h1:A8425heRM8mylnv4H58FPUiH+aYivyitre0PzxrfmWs= 12 | github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb/go.mod h1:dOF6gtQiF9UwNh995T5OphYmtIypkjsp3ap7r9AN/iA= 13 | github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148 h1:AfFPZwtwGN01BW1jDdqBVqscTwetvMpydqYZz57RSlc= 14 | github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148/go.mod h1:Bh6U3viD57rFXRYIQ+kmiYtr+1Bx0AceypDLJJSyi9s= 15 | github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33 h1:TwqSV3qLp3tKSqirGLRHnjFk9Tc2oy57LIl+FQ4GjI4= 16 | github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33/go.mod h1:CvCKCt3v04Ufos1zZnNCelBDeCGRpPucaN8QczoUsN4= 17 | github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012 h1:Xvxck3tE5FW7F7bTS97iNM2ADMyCMJztVqn5HYKdJGo= 18 | github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012/go.mod h1:T40D0O1cPvUU/+AmiXVXy1cncYQT6wem4Z0g4SfAYvY= 19 | github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0 h1:c46K6uh5Dz00zJeU9BfjXdb8I+E4RkUdfnWJpQADXFo= 20 | github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0/go.mod h1:hcNt/kOJHcIcuMvouE7LJcYdeFUFbVpBJ6d4wmOA+tU= 21 | github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495 h1:jrt4qbJVEFs4H93/ITxygHc6u0TGqAkkate7TQ4wFSA= 22 | github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495/go.mod h1:oyaR7fLnRV0hT9z6qwE9GkaeTom/hTDwK3H2idcOJFc= 23 | github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5 h1:om4X9AVg3asL8gxNJDcz4e/Wp+VpQj1PY3uJXKr6EOg= 24 | github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5/go.mod h1:nNqgPoV/h9uYWk6kYEFdEAhNVOacpfpRW5SFmdaP4tU= 25 | github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5 h1:pfV3G3k7NCKqKk8THBmyuh2zA33lgYHS3GVrzRR8ry4= 26 | github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5/go.mod h1:GbMKRjLfk0H+PI7nLi1Sx5lHf5wCpLz9al8tQYSxpEk= 27 | github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1 h1:ZXZMDwE+IhUtGug4Brv6NjJWUU3rfkZBKpemf6RY8/g= 28 | github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1/go.mod h1:UKCLuYnJ312Mei+3cyTmGOHzn0YAnaPRECgJmHtzrqs= 29 | github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb h1:EXEM82lFM7JjJb6qiKZXkpIDaCcbV2obNn82ghwj9lw= 30 | github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb/go.mod h1:lXCF1nGG5Dr4J3BTS0ObN4xJCCICiSu/b+Xe/VqMV7g= 31 | github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d h1:fcYCvoXdcP1uRQYXqJHRy6Hec+uKScQdKVtMwK9JeCI= 32 | github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d/go.mod h1:T1nShQ4v5AJtozZ8YyAS4uzUtDAJj/iv4YfwXSbUHzg= 33 | github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447 h1:o9alBu1J/WjrcTKEthYtXmdkDc5OVXD+PqlvnEZ0Lzc= 34 | github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447/go.mod h1:1Oh95COkkTn6Ezp0vcMbvfhRP5gLeqqljR0BYnBzWvc= 35 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 36 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 37 | -------------------------------------------------------------------------------- /schema/core/src/grammar.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json", 3 | "name": "core_schema", 4 | "rules": { 5 | "scalar": { 6 | "type": "CHOICE", 7 | "members": [ 8 | { 9 | "type": "SYMBOL", 10 | "name": "null" 11 | }, 12 | { 13 | "type": "SYMBOL", 14 | "name": "bool" 15 | }, 16 | { 17 | "type": "SYMBOL", 18 | "name": "int" 19 | }, 20 | { 21 | "type": "SYMBOL", 22 | "name": "float" 23 | } 24 | ] 25 | }, 26 | "null": { 27 | "type": "TOKEN", 28 | "content": { 29 | "type": "CHOICE", 30 | "members": [ 31 | { 32 | "type": "STRING", 33 | "value": "~" 34 | }, 35 | { 36 | "type": "STRING", 37 | "value": "null" 38 | }, 39 | { 40 | "type": "STRING", 41 | "value": "Null" 42 | }, 43 | { 44 | "type": "STRING", 45 | "value": "NULL" 46 | } 47 | ] 48 | } 49 | }, 50 | "bool": { 51 | "type": "TOKEN", 52 | "content": { 53 | "type": "CHOICE", 54 | "members": [ 55 | { 56 | "type": "STRING", 57 | "value": "true" 58 | }, 59 | { 60 | "type": "STRING", 61 | "value": "True" 62 | }, 63 | { 64 | "type": "STRING", 65 | "value": "TRUE" 66 | }, 67 | { 68 | "type": "STRING", 69 | "value": "false" 70 | }, 71 | { 72 | "type": "STRING", 73 | "value": "False" 74 | }, 75 | { 76 | "type": "STRING", 77 | "value": "FALSE" 78 | } 79 | ] 80 | } 81 | }, 82 | "int": { 83 | "type": "TOKEN", 84 | "content": { 85 | "type": "CHOICE", 86 | "members": [ 87 | { 88 | "type": "PATTERN", 89 | "value": "[-+]?[0-9]+" 90 | }, 91 | { 92 | "type": "PATTERN", 93 | "value": "0o[0-7]+" 94 | }, 95 | { 96 | "type": "PATTERN", 97 | "value": "0x[0-9a-fA-F]+" 98 | } 99 | ] 100 | } 101 | }, 102 | "float": { 103 | "type": "TOKEN", 104 | "content": { 105 | "type": "CHOICE", 106 | "members": [ 107 | { 108 | "type": "PATTERN", 109 | "value": "[-+]?(\\.\\d+|\\d+(\\.\\d*)?)([eE][-+]?\\d+)?" 110 | }, 111 | { 112 | "type": "SEQ", 113 | "members": [ 114 | { 115 | "type": "CHOICE", 116 | "members": [ 117 | { 118 | "type": "CHOICE", 119 | "members": [ 120 | { 121 | "type": "STRING", 122 | "value": "-" 123 | }, 124 | { 125 | "type": "STRING", 126 | "value": "+" 127 | } 128 | ] 129 | }, 130 | { 131 | "type": "BLANK" 132 | } 133 | ] 134 | }, 135 | { 136 | "type": "CHOICE", 137 | "members": [ 138 | { 139 | "type": "STRING", 140 | "value": ".inf" 141 | }, 142 | { 143 | "type": "STRING", 144 | "value": ".Inf" 145 | }, 146 | { 147 | "type": "STRING", 148 | "value": ".INF" 149 | } 150 | ] 151 | } 152 | ] 153 | }, 154 | { 155 | "type": "CHOICE", 156 | "members": [ 157 | { 158 | "type": "STRING", 159 | "value": ".nan" 160 | }, 161 | { 162 | "type": "STRING", 163 | "value": ".NaN" 164 | }, 165 | { 166 | "type": "STRING", 167 | "value": ".NAN" 168 | } 169 | ] 170 | } 171 | ] 172 | } 173 | } 174 | }, 175 | "extras": [], 176 | "conflicts": [], 177 | "precedences": [], 178 | "externals": [], 179 | "inline": [], 180 | "supertypes": [], 181 | "reserved": {} 182 | } -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.3" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "cc" 16 | version = "1.2.39" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" 19 | dependencies = [ 20 | "find-msvc-tools", 21 | "shlex", 22 | ] 23 | 24 | [[package]] 25 | name = "equivalent" 26 | version = "1.0.2" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 29 | 30 | [[package]] 31 | name = "find-msvc-tools" 32 | version = "0.1.2" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" 35 | 36 | [[package]] 37 | name = "hashbrown" 38 | version = "0.16.0" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" 41 | 42 | [[package]] 43 | name = "indexmap" 44 | version = "2.11.4" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" 47 | dependencies = [ 48 | "equivalent", 49 | "hashbrown", 50 | ] 51 | 52 | [[package]] 53 | name = "itoa" 54 | version = "1.0.15" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 57 | 58 | [[package]] 59 | name = "memchr" 60 | version = "2.7.6" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" 63 | 64 | [[package]] 65 | name = "proc-macro2" 66 | version = "1.0.101" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" 69 | dependencies = [ 70 | "unicode-ident", 71 | ] 72 | 73 | [[package]] 74 | name = "quote" 75 | version = "1.0.40" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 78 | dependencies = [ 79 | "proc-macro2", 80 | ] 81 | 82 | [[package]] 83 | name = "regex" 84 | version = "1.11.3" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" 87 | dependencies = [ 88 | "aho-corasick", 89 | "memchr", 90 | "regex-automata", 91 | "regex-syntax", 92 | ] 93 | 94 | [[package]] 95 | name = "regex-automata" 96 | version = "0.4.11" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" 99 | dependencies = [ 100 | "aho-corasick", 101 | "memchr", 102 | "regex-syntax", 103 | ] 104 | 105 | [[package]] 106 | name = "regex-syntax" 107 | version = "0.8.6" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" 110 | 111 | [[package]] 112 | name = "ryu" 113 | version = "1.0.20" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 116 | 117 | [[package]] 118 | name = "serde" 119 | version = "1.0.227" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "80ece43fc6fbed4eb5392ab50c07334d3e577cbf40997ee896fe7af40bba4245" 122 | dependencies = [ 123 | "serde_core", 124 | ] 125 | 126 | [[package]] 127 | name = "serde_core" 128 | version = "1.0.227" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "7a576275b607a2c86ea29e410193df32bc680303c82f31e275bbfcafe8b33be5" 131 | dependencies = [ 132 | "serde_derive", 133 | ] 134 | 135 | [[package]] 136 | name = "serde_derive" 137 | version = "1.0.227" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "51e694923b8824cf0e9b382adf0f60d4e05f348f357b38833a3fa5ed7c2ede04" 140 | dependencies = [ 141 | "proc-macro2", 142 | "quote", 143 | "syn", 144 | ] 145 | 146 | [[package]] 147 | name = "serde_json" 148 | version = "1.0.145" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" 151 | dependencies = [ 152 | "indexmap", 153 | "itoa", 154 | "memchr", 155 | "ryu", 156 | "serde", 157 | "serde_core", 158 | ] 159 | 160 | [[package]] 161 | name = "shlex" 162 | version = "1.3.0" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 165 | 166 | [[package]] 167 | name = "streaming-iterator" 168 | version = "0.1.9" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" 171 | 172 | [[package]] 173 | name = "syn" 174 | version = "2.0.106" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" 177 | dependencies = [ 178 | "proc-macro2", 179 | "quote", 180 | "unicode-ident", 181 | ] 182 | 183 | [[package]] 184 | name = "tree-sitter" 185 | version = "0.25.8" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "6d7b8994f367f16e6fa14b5aebbcb350de5d7cbea82dc5b00ae997dd71680dd2" 188 | dependencies = [ 189 | "cc", 190 | "regex", 191 | "regex-syntax", 192 | "serde_json", 193 | "streaming-iterator", 194 | "tree-sitter-language", 195 | ] 196 | 197 | [[package]] 198 | name = "tree-sitter-language" 199 | version = "0.1.5" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "c4013970217383f67b18aef68f6fb2e8d409bc5755227092d32efb0422ba24b8" 202 | 203 | [[package]] 204 | name = "tree-sitter-yaml" 205 | version = "0.7.2" 206 | dependencies = [ 207 | "cc", 208 | "tree-sitter", 209 | "tree-sitter-language", 210 | ] 211 | 212 | [[package]] 213 | name = "unicode-ident" 214 | version = "1.0.19" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" 217 | -------------------------------------------------------------------------------- /src/schema.core.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #define SCH_STT_FRZ -1 6 | 7 | #define HAS_TIMESTAMP 0 8 | 9 | typedef enum { 10 | RS_STR, 11 | RS_INT, 12 | RS_NULL, 13 | RS_BOOL, 14 | RS_FLOAT, 15 | } ResultSchema; 16 | 17 | static int8_t adv_sch_stt(int8_t sch_stt, int32_t cur_chr, ResultSchema *rlt_sch) { 18 | switch (sch_stt) { 19 | case SCH_STT_FRZ: 20 | break; 21 | case 0: 22 | if (cur_chr == '.') {*rlt_sch = RS_STR; return 6;} 23 | if (cur_chr == '0') {*rlt_sch = RS_INT; return 37;} 24 | if (cur_chr == 'F') {*rlt_sch = RS_STR; return 2;} 25 | if (cur_chr == 'N') {*rlt_sch = RS_STR; return 16;} 26 | if (cur_chr == 'T') {*rlt_sch = RS_STR; return 13;} 27 | if (cur_chr == 'f') {*rlt_sch = RS_STR; return 17;} 28 | if (cur_chr == 'n') {*rlt_sch = RS_STR; return 29;} 29 | if (cur_chr == 't') {*rlt_sch = RS_STR; return 26;} 30 | if (cur_chr == '~') {*rlt_sch = RS_NULL; return 35;} 31 | if (cur_chr == '+') {*rlt_sch = RS_STR; return 1;} 32 | if (cur_chr == '-') {*rlt_sch = RS_STR; return 1;} 33 | if (('1' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_INT; return 38;} 34 | break; 35 | case 1: 36 | if (cur_chr == '.') {*rlt_sch = RS_STR; return 7;} 37 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_INT; return 38;} 38 | break; 39 | case 2: 40 | if (cur_chr == 'A') {*rlt_sch = RS_STR; return 9;} 41 | if (cur_chr == 'a') {*rlt_sch = RS_STR; return 22;} 42 | break; 43 | case 3: 44 | if (cur_chr == 'A') {*rlt_sch = RS_STR; return 12;} 45 | if (cur_chr == 'a') {*rlt_sch = RS_STR; return 12;} 46 | break; 47 | case 4: 48 | if (cur_chr == 'E') {*rlt_sch = RS_BOOL; return 36;} 49 | break; 50 | case 5: 51 | if (cur_chr == 'F') {*rlt_sch = RS_FLOAT; return 41;} 52 | break; 53 | case 6: 54 | if (cur_chr == 'I') {*rlt_sch = RS_STR; return 11;} 55 | if (cur_chr == 'N') {*rlt_sch = RS_STR; return 3;} 56 | if (cur_chr == 'i') {*rlt_sch = RS_STR; return 24;} 57 | if (cur_chr == 'n') {*rlt_sch = RS_STR; return 18;} 58 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 42;} 59 | break; 60 | case 7: 61 | if (cur_chr == 'I') {*rlt_sch = RS_STR; return 11;} 62 | if (cur_chr == 'i') {*rlt_sch = RS_STR; return 24;} 63 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 42;} 64 | break; 65 | case 8: 66 | if (cur_chr == 'L') {*rlt_sch = RS_NULL; return 35;} 67 | break; 68 | case 9: 69 | if (cur_chr == 'L') {*rlt_sch = RS_STR; return 14;} 70 | break; 71 | case 10: 72 | if (cur_chr == 'L') {*rlt_sch = RS_STR; return 8;} 73 | break; 74 | case 11: 75 | if (cur_chr == 'N') {*rlt_sch = RS_STR; return 5;} 76 | if (cur_chr == 'n') {*rlt_sch = RS_STR; return 20;} 77 | break; 78 | case 12: 79 | if (cur_chr == 'N') {*rlt_sch = RS_FLOAT; return 41;} 80 | break; 81 | case 13: 82 | if (cur_chr == 'R') {*rlt_sch = RS_STR; return 15;} 83 | if (cur_chr == 'r') {*rlt_sch = RS_STR; return 28;} 84 | break; 85 | case 14: 86 | if (cur_chr == 'S') {*rlt_sch = RS_STR; return 4;} 87 | break; 88 | case 15: 89 | if (cur_chr == 'U') {*rlt_sch = RS_STR; return 4;} 90 | break; 91 | case 16: 92 | if (cur_chr == 'U') {*rlt_sch = RS_STR; return 10;} 93 | if (cur_chr == 'u') {*rlt_sch = RS_STR; return 23;} 94 | break; 95 | case 17: 96 | if (cur_chr == 'a') {*rlt_sch = RS_STR; return 22;} 97 | break; 98 | case 18: 99 | if (cur_chr == 'a') {*rlt_sch = RS_STR; return 25;} 100 | break; 101 | case 19: 102 | if (cur_chr == 'e') {*rlt_sch = RS_BOOL; return 36;} 103 | break; 104 | case 20: 105 | if (cur_chr == 'f') {*rlt_sch = RS_FLOAT; return 41;} 106 | break; 107 | case 21: 108 | if (cur_chr == 'l') {*rlt_sch = RS_NULL; return 35;} 109 | break; 110 | case 22: 111 | if (cur_chr == 'l') {*rlt_sch = RS_STR; return 27;} 112 | break; 113 | case 23: 114 | if (cur_chr == 'l') {*rlt_sch = RS_STR; return 21;} 115 | break; 116 | case 24: 117 | if (cur_chr == 'n') {*rlt_sch = RS_STR; return 20;} 118 | break; 119 | case 25: 120 | if (cur_chr == 'n') {*rlt_sch = RS_FLOAT; return 41;} 121 | break; 122 | case 26: 123 | if (cur_chr == 'r') {*rlt_sch = RS_STR; return 28;} 124 | break; 125 | case 27: 126 | if (cur_chr == 's') {*rlt_sch = RS_STR; return 19;} 127 | break; 128 | case 28: 129 | if (cur_chr == 'u') {*rlt_sch = RS_STR; return 19;} 130 | break; 131 | case 29: 132 | if (cur_chr == 'u') {*rlt_sch = RS_STR; return 23;} 133 | break; 134 | case 30: 135 | if (cur_chr == '+' || 136 | cur_chr == '-') {*rlt_sch = RS_STR; return 32;} 137 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 43;} 138 | break; 139 | case 31: 140 | if (('0' <= cur_chr && cur_chr <= '7')) {*rlt_sch = RS_INT; return 39;} 141 | break; 142 | case 32: 143 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 43;} 144 | break; 145 | case 33: 146 | if (('0' <= cur_chr && cur_chr <= '9') || 147 | ('A' <= cur_chr && cur_chr <= 'F') || 148 | ('a' <= cur_chr && cur_chr <= 'f')) {*rlt_sch = RS_INT; return 40;} 149 | break; 150 | case 34: 151 | abort(); 152 | break; 153 | case 35: 154 | *rlt_sch = RS_NULL; 155 | break; 156 | case 36: 157 | *rlt_sch = RS_BOOL; 158 | break; 159 | case 37: 160 | *rlt_sch = RS_INT; 161 | if (cur_chr == '.') {*rlt_sch = RS_FLOAT; return 42;} 162 | if (cur_chr == 'o') {*rlt_sch = RS_STR; return 31;} 163 | if (cur_chr == 'x') {*rlt_sch = RS_STR; return 33;} 164 | if (cur_chr == 'E' || 165 | cur_chr == 'e') {*rlt_sch = RS_STR; return 30;} 166 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_INT; return 38;} 167 | break; 168 | case 38: 169 | *rlt_sch = RS_INT; 170 | if (cur_chr == '.') {*rlt_sch = RS_FLOAT; return 42;} 171 | if (cur_chr == 'E' || 172 | cur_chr == 'e') {*rlt_sch = RS_STR; return 30;} 173 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_INT; return 38;} 174 | break; 175 | case 39: 176 | *rlt_sch = RS_INT; 177 | if (('0' <= cur_chr && cur_chr <= '7')) {*rlt_sch = RS_INT; return 39;} 178 | break; 179 | case 40: 180 | *rlt_sch = RS_INT; 181 | if (('0' <= cur_chr && cur_chr <= '9') || 182 | ('A' <= cur_chr && cur_chr <= 'F') || 183 | ('a' <= cur_chr && cur_chr <= 'f')) {*rlt_sch = RS_INT; return 40;} 184 | break; 185 | case 41: 186 | *rlt_sch = RS_FLOAT; 187 | break; 188 | case 42: 189 | *rlt_sch = RS_FLOAT; 190 | if (cur_chr == 'E' || 191 | cur_chr == 'e') {*rlt_sch = RS_STR; return 30;} 192 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 42;} 193 | break; 194 | case 43: 195 | *rlt_sch = RS_FLOAT; 196 | if (('0' <= cur_chr && cur_chr <= '9')) {*rlt_sch = RS_FLOAT; return 43;} 197 | break; 198 | default: 199 | *rlt_sch = RS_STR; 200 | return SCH_STT_FRZ; 201 | } 202 | if (cur_chr != '\r' && cur_chr != '\n' && cur_chr != ' ' && cur_chr != 0) *rlt_sch = RS_STR; 203 | return SCH_STT_FRZ; 204 | } 205 | -------------------------------------------------------------------------------- /schema/json/src/parser.c: -------------------------------------------------------------------------------- 1 | /* Automatically @generated by tree-sitter v0.25.4 (726dcd1e872149d95de581589fc408fb8ea9cb0b) */ 2 | 3 | #include "tree_sitter/parser.h" 4 | 5 | #if defined(__GNUC__) || defined(__clang__) 6 | #pragma GCC diagnostic ignored "-Wmissing-field-initializers" 7 | #endif 8 | 9 | #define LANGUAGE_VERSION 14 10 | #define STATE_COUNT 4 11 | #define LARGE_STATE_COUNT 2 12 | #define SYMBOL_COUNT 6 13 | #define ALIAS_COUNT 0 14 | #define TOKEN_COUNT 5 15 | #define EXTERNAL_TOKEN_COUNT 0 16 | #define FIELD_COUNT 0 17 | #define MAX_ALIAS_SEQUENCE_LENGTH 1 18 | #define MAX_RESERVED_WORD_SET_SIZE 0 19 | #define PRODUCTION_ID_COUNT 1 20 | #define SUPERTYPE_COUNT 0 21 | 22 | enum ts_symbol_identifiers { 23 | sym_null = 1, 24 | sym_bool = 2, 25 | sym_int = 3, 26 | sym_float = 4, 27 | sym_scalar = 5, 28 | }; 29 | 30 | static const char * const ts_symbol_names[] = { 31 | [ts_builtin_sym_end] = "end", 32 | [sym_null] = "null", 33 | [sym_bool] = "bool", 34 | [sym_int] = "int", 35 | [sym_float] = "float", 36 | [sym_scalar] = "scalar", 37 | }; 38 | 39 | static const TSSymbol ts_symbol_map[] = { 40 | [ts_builtin_sym_end] = ts_builtin_sym_end, 41 | [sym_null] = sym_null, 42 | [sym_bool] = sym_bool, 43 | [sym_int] = sym_int, 44 | [sym_float] = sym_float, 45 | [sym_scalar] = sym_scalar, 46 | }; 47 | 48 | static const TSSymbolMetadata ts_symbol_metadata[] = { 49 | [ts_builtin_sym_end] = { 50 | .visible = false, 51 | .named = true, 52 | }, 53 | [sym_null] = { 54 | .visible = true, 55 | .named = true, 56 | }, 57 | [sym_bool] = { 58 | .visible = true, 59 | .named = true, 60 | }, 61 | [sym_int] = { 62 | .visible = true, 63 | .named = true, 64 | }, 65 | [sym_float] = { 66 | .visible = true, 67 | .named = true, 68 | }, 69 | [sym_scalar] = { 70 | .visible = true, 71 | .named = true, 72 | }, 73 | }; 74 | 75 | static const TSSymbol ts_alias_sequences[PRODUCTION_ID_COUNT][MAX_ALIAS_SEQUENCE_LENGTH] = { 76 | [0] = {0}, 77 | }; 78 | 79 | static const uint16_t ts_non_terminal_alias_map[] = { 80 | 0, 81 | }; 82 | 83 | static const TSStateId ts_primary_state_ids[STATE_COUNT] = { 84 | [0] = 0, 85 | [1] = 1, 86 | [2] = 2, 87 | [3] = 3, 88 | }; 89 | 90 | static bool ts_lex(TSLexer *lexer, TSStateId state) { 91 | START_LEXER(); 92 | eof = lexer->eof(lexer); 93 | switch (state) { 94 | case 0: 95 | if (eof) ADVANCE(13); 96 | if (lookahead == '-') ADVANCE(1); 97 | if (lookahead == '0') ADVANCE(16); 98 | if (lookahead == 'f') ADVANCE(2); 99 | if (lookahead == 'n') ADVANCE(10); 100 | if (lookahead == 't') ADVANCE(7); 101 | if (('1' <= lookahead && lookahead <= '9')) ADVANCE(17); 102 | END_STATE(); 103 | case 1: 104 | if (lookahead == '0') ADVANCE(16); 105 | if (('1' <= lookahead && lookahead <= '9')) ADVANCE(17); 106 | END_STATE(); 107 | case 2: 108 | if (lookahead == 'a') ADVANCE(4); 109 | END_STATE(); 110 | case 3: 111 | if (lookahead == 'e') ADVANCE(15); 112 | END_STATE(); 113 | case 4: 114 | if (lookahead == 'l') ADVANCE(8); 115 | END_STATE(); 116 | case 5: 117 | if (lookahead == 'l') ADVANCE(14); 118 | END_STATE(); 119 | case 6: 120 | if (lookahead == 'l') ADVANCE(5); 121 | END_STATE(); 122 | case 7: 123 | if (lookahead == 'r') ADVANCE(9); 124 | END_STATE(); 125 | case 8: 126 | if (lookahead == 's') ADVANCE(3); 127 | END_STATE(); 128 | case 9: 129 | if (lookahead == 'u') ADVANCE(3); 130 | END_STATE(); 131 | case 10: 132 | if (lookahead == 'u') ADVANCE(6); 133 | END_STATE(); 134 | case 11: 135 | if (lookahead == '+' || 136 | lookahead == '-') ADVANCE(12); 137 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(19); 138 | END_STATE(); 139 | case 12: 140 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(19); 141 | END_STATE(); 142 | case 13: 143 | ACCEPT_TOKEN(ts_builtin_sym_end); 144 | END_STATE(); 145 | case 14: 146 | ACCEPT_TOKEN(sym_null); 147 | END_STATE(); 148 | case 15: 149 | ACCEPT_TOKEN(sym_bool); 150 | END_STATE(); 151 | case 16: 152 | ACCEPT_TOKEN(sym_int); 153 | if (lookahead == '.') ADVANCE(18); 154 | if (lookahead == 'E' || 155 | lookahead == 'e') ADVANCE(11); 156 | END_STATE(); 157 | case 17: 158 | ACCEPT_TOKEN(sym_int); 159 | if (lookahead == '.') ADVANCE(18); 160 | if (lookahead == 'E' || 161 | lookahead == 'e') ADVANCE(11); 162 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(17); 163 | END_STATE(); 164 | case 18: 165 | ACCEPT_TOKEN(sym_float); 166 | if (lookahead == 'E' || 167 | lookahead == 'e') ADVANCE(11); 168 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(18); 169 | END_STATE(); 170 | case 19: 171 | ACCEPT_TOKEN(sym_float); 172 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(19); 173 | END_STATE(); 174 | default: 175 | return false; 176 | } 177 | } 178 | 179 | static const TSLexMode ts_lex_modes[STATE_COUNT] = { 180 | [0] = {.lex_state = 0}, 181 | [1] = {.lex_state = 0}, 182 | [2] = {.lex_state = 0}, 183 | [3] = {.lex_state = 0}, 184 | }; 185 | 186 | static const uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = { 187 | [STATE(0)] = { 188 | [ts_builtin_sym_end] = ACTIONS(1), 189 | [sym_null] = ACTIONS(1), 190 | [sym_bool] = ACTIONS(1), 191 | [sym_int] = ACTIONS(1), 192 | [sym_float] = ACTIONS(1), 193 | }, 194 | [STATE(1)] = { 195 | [sym_scalar] = STATE(3), 196 | [sym_null] = ACTIONS(3), 197 | [sym_bool] = ACTIONS(3), 198 | [sym_int] = ACTIONS(5), 199 | [sym_float] = ACTIONS(5), 200 | }, 201 | }; 202 | 203 | static const uint16_t ts_small_parse_table[] = { 204 | [0] = 1, 205 | ACTIONS(7), 1, 206 | ts_builtin_sym_end, 207 | [4] = 1, 208 | ACTIONS(9), 1, 209 | ts_builtin_sym_end, 210 | }; 211 | 212 | static const uint32_t ts_small_parse_table_map[] = { 213 | [SMALL_STATE(2)] = 0, 214 | [SMALL_STATE(3)] = 4, 215 | }; 216 | 217 | static const TSParseActionEntry ts_parse_actions[] = { 218 | [0] = {.entry = {.count = 0, .reusable = false}}, 219 | [1] = {.entry = {.count = 1, .reusable = false}}, RECOVER(), 220 | [3] = {.entry = {.count = 1, .reusable = true}}, SHIFT(2), 221 | [5] = {.entry = {.count = 1, .reusable = false}}, SHIFT(2), 222 | [7] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_scalar, 1, 0, 0), 223 | [9] = {.entry = {.count = 1, .reusable = true}}, ACCEPT_INPUT(), 224 | }; 225 | 226 | #ifdef __cplusplus 227 | extern "C" { 228 | #endif 229 | #ifdef TREE_SITTER_HIDE_SYMBOLS 230 | #define TS_PUBLIC 231 | #elif defined(_WIN32) 232 | #define TS_PUBLIC __declspec(dllexport) 233 | #else 234 | #define TS_PUBLIC __attribute__((visibility("default"))) 235 | #endif 236 | 237 | TS_PUBLIC const TSLanguage *tree_sitter_json_schema(void) { 238 | static const TSLanguage language = { 239 | .abi_version = LANGUAGE_VERSION, 240 | .symbol_count = SYMBOL_COUNT, 241 | .alias_count = ALIAS_COUNT, 242 | .token_count = TOKEN_COUNT, 243 | .external_token_count = EXTERNAL_TOKEN_COUNT, 244 | .state_count = STATE_COUNT, 245 | .large_state_count = LARGE_STATE_COUNT, 246 | .production_id_count = PRODUCTION_ID_COUNT, 247 | .field_count = FIELD_COUNT, 248 | .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, 249 | .parse_table = &ts_parse_table[0][0], 250 | .small_parse_table = ts_small_parse_table, 251 | .small_parse_table_map = ts_small_parse_table_map, 252 | .parse_actions = ts_parse_actions, 253 | .symbol_names = ts_symbol_names, 254 | .symbol_metadata = ts_symbol_metadata, 255 | .public_symbol_map = ts_symbol_map, 256 | .alias_map = ts_non_terminal_alias_map, 257 | .alias_sequences = &ts_alias_sequences[0][0], 258 | .lex_modes = (const void*)ts_lex_modes, 259 | .lex_fn = ts_lex, 260 | .primary_state_ids = ts_primary_state_ids, 261 | }; 262 | return &language; 263 | } 264 | #ifdef __cplusplus 265 | } 266 | #endif 267 | -------------------------------------------------------------------------------- /src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | typedef struct TSLanguageMetadata { 22 | uint8_t major_version; 23 | uint8_t minor_version; 24 | uint8_t patch_version; 25 | } TSLanguageMetadata; 26 | #endif 27 | 28 | typedef struct { 29 | TSFieldId field_id; 30 | uint8_t child_index; 31 | bool inherited; 32 | } TSFieldMapEntry; 33 | 34 | // Used to index the field and supertype maps. 35 | typedef struct { 36 | uint16_t index; 37 | uint16_t length; 38 | } TSMapSlice; 39 | 40 | typedef struct { 41 | bool visible; 42 | bool named; 43 | bool supertype; 44 | } TSSymbolMetadata; 45 | 46 | typedef struct TSLexer TSLexer; 47 | 48 | struct TSLexer { 49 | int32_t lookahead; 50 | TSSymbol result_symbol; 51 | void (*advance)(TSLexer *, bool); 52 | void (*mark_end)(TSLexer *); 53 | uint32_t (*get_column)(TSLexer *); 54 | bool (*is_at_included_range_start)(const TSLexer *); 55 | bool (*eof)(const TSLexer *); 56 | void (*log)(const TSLexer *, const char *, ...); 57 | }; 58 | 59 | typedef enum { 60 | TSParseActionTypeShift, 61 | TSParseActionTypeReduce, 62 | TSParseActionTypeAccept, 63 | TSParseActionTypeRecover, 64 | } TSParseActionType; 65 | 66 | typedef union { 67 | struct { 68 | uint8_t type; 69 | TSStateId state; 70 | bool extra; 71 | bool repetition; 72 | } shift; 73 | struct { 74 | uint8_t type; 75 | uint8_t child_count; 76 | TSSymbol symbol; 77 | int16_t dynamic_precedence; 78 | uint16_t production_id; 79 | } reduce; 80 | uint8_t type; 81 | } TSParseAction; 82 | 83 | typedef struct { 84 | uint16_t lex_state; 85 | uint16_t external_lex_state; 86 | } TSLexMode; 87 | 88 | typedef struct { 89 | uint16_t lex_state; 90 | uint16_t external_lex_state; 91 | uint16_t reserved_word_set_id; 92 | } TSLexerMode; 93 | 94 | typedef union { 95 | TSParseAction action; 96 | struct { 97 | uint8_t count; 98 | bool reusable; 99 | } entry; 100 | } TSParseActionEntry; 101 | 102 | typedef struct { 103 | int32_t start; 104 | int32_t end; 105 | } TSCharacterRange; 106 | 107 | struct TSLanguage { 108 | uint32_t abi_version; 109 | uint32_t symbol_count; 110 | uint32_t alias_count; 111 | uint32_t token_count; 112 | uint32_t external_token_count; 113 | uint32_t state_count; 114 | uint32_t large_state_count; 115 | uint32_t production_id_count; 116 | uint32_t field_count; 117 | uint16_t max_alias_sequence_length; 118 | const uint16_t *parse_table; 119 | const uint16_t *small_parse_table; 120 | const uint32_t *small_parse_table_map; 121 | const TSParseActionEntry *parse_actions; 122 | const char * const *symbol_names; 123 | const char * const *field_names; 124 | const TSMapSlice *field_map_slices; 125 | const TSFieldMapEntry *field_map_entries; 126 | const TSSymbolMetadata *symbol_metadata; 127 | const TSSymbol *public_symbol_map; 128 | const uint16_t *alias_map; 129 | const TSSymbol *alias_sequences; 130 | const TSLexerMode *lex_modes; 131 | bool (*lex_fn)(TSLexer *, TSStateId); 132 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 133 | TSSymbol keyword_capture_token; 134 | struct { 135 | const bool *states; 136 | const TSSymbol *symbol_map; 137 | void *(*create)(void); 138 | void (*destroy)(void *); 139 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 140 | unsigned (*serialize)(void *, char *); 141 | void (*deserialize)(void *, const char *, unsigned); 142 | } external_scanner; 143 | const TSStateId *primary_state_ids; 144 | const char *name; 145 | const TSSymbol *reserved_words; 146 | uint16_t max_reserved_word_set_size; 147 | uint32_t supertype_count; 148 | const TSSymbol *supertype_symbols; 149 | const TSMapSlice *supertype_map_slices; 150 | const TSSymbol *supertype_map_entries; 151 | TSLanguageMetadata metadata; 152 | }; 153 | 154 | static inline bool set_contains(const TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 155 | uint32_t index = 0; 156 | uint32_t size = len - index; 157 | while (size > 1) { 158 | uint32_t half_size = size / 2; 159 | uint32_t mid_index = index + half_size; 160 | const TSCharacterRange *range = &ranges[mid_index]; 161 | if (lookahead >= range->start && lookahead <= range->end) { 162 | return true; 163 | } else if (lookahead > range->end) { 164 | index = mid_index; 165 | } 166 | size -= half_size; 167 | } 168 | const TSCharacterRange *range = &ranges[index]; 169 | return (lookahead >= range->start && lookahead <= range->end); 170 | } 171 | 172 | /* 173 | * Lexer Macros 174 | */ 175 | 176 | #ifdef _MSC_VER 177 | #define UNUSED __pragma(warning(suppress : 4101)) 178 | #else 179 | #define UNUSED __attribute__((unused)) 180 | #endif 181 | 182 | #define START_LEXER() \ 183 | bool result = false; \ 184 | bool skip = false; \ 185 | UNUSED \ 186 | bool eof = false; \ 187 | int32_t lookahead; \ 188 | goto start; \ 189 | next_state: \ 190 | lexer->advance(lexer, skip); \ 191 | start: \ 192 | skip = false; \ 193 | lookahead = lexer->lookahead; 194 | 195 | #define ADVANCE(state_value) \ 196 | { \ 197 | state = state_value; \ 198 | goto next_state; \ 199 | } 200 | 201 | #define ADVANCE_MAP(...) \ 202 | { \ 203 | static const uint16_t map[] = { __VA_ARGS__ }; \ 204 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 205 | if (map[i] == lookahead) { \ 206 | state = map[i + 1]; \ 207 | goto next_state; \ 208 | } \ 209 | } \ 210 | } 211 | 212 | #define SKIP(state_value) \ 213 | { \ 214 | skip = true; \ 215 | state = state_value; \ 216 | goto next_state; \ 217 | } 218 | 219 | #define ACCEPT_TOKEN(symbol_value) \ 220 | result = true; \ 221 | lexer->result_symbol = symbol_value; \ 222 | lexer->mark_end(lexer); 223 | 224 | #define END_STATE() return result; 225 | 226 | /* 227 | * Parse Table Macros 228 | */ 229 | 230 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 231 | 232 | #define STATE(id) id 233 | 234 | #define ACTIONS(id) id 235 | 236 | #define SHIFT(state_value) \ 237 | {{ \ 238 | .shift = { \ 239 | .type = TSParseActionTypeShift, \ 240 | .state = (state_value) \ 241 | } \ 242 | }} 243 | 244 | #define SHIFT_REPEAT(state_value) \ 245 | {{ \ 246 | .shift = { \ 247 | .type = TSParseActionTypeShift, \ 248 | .state = (state_value), \ 249 | .repetition = true \ 250 | } \ 251 | }} 252 | 253 | #define SHIFT_EXTRA() \ 254 | {{ \ 255 | .shift = { \ 256 | .type = TSParseActionTypeShift, \ 257 | .extra = true \ 258 | } \ 259 | }} 260 | 261 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 262 | {{ \ 263 | .reduce = { \ 264 | .type = TSParseActionTypeReduce, \ 265 | .symbol = symbol_name, \ 266 | .child_count = children, \ 267 | .dynamic_precedence = precedence, \ 268 | .production_id = prod_id \ 269 | }, \ 270 | }} 271 | 272 | #define RECOVER() \ 273 | {{ \ 274 | .type = TSParseActionTypeRecover \ 275 | }} 276 | 277 | #define ACCEPT_INPUT() \ 278 | {{ \ 279 | .type = TSParseActionTypeAccept \ 280 | }} 281 | 282 | #ifdef __cplusplus 283 | } 284 | #endif 285 | 286 | #endif // TREE_SITTER_PARSER_H_ 287 | -------------------------------------------------------------------------------- /schema/core/src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | typedef struct TSLanguageMetadata { 22 | uint8_t major_version; 23 | uint8_t minor_version; 24 | uint8_t patch_version; 25 | } TSLanguageMetadata; 26 | #endif 27 | 28 | typedef struct { 29 | TSFieldId field_id; 30 | uint8_t child_index; 31 | bool inherited; 32 | } TSFieldMapEntry; 33 | 34 | // Used to index the field and supertype maps. 35 | typedef struct { 36 | uint16_t index; 37 | uint16_t length; 38 | } TSMapSlice; 39 | 40 | typedef struct { 41 | bool visible; 42 | bool named; 43 | bool supertype; 44 | } TSSymbolMetadata; 45 | 46 | typedef struct TSLexer TSLexer; 47 | 48 | struct TSLexer { 49 | int32_t lookahead; 50 | TSSymbol result_symbol; 51 | void (*advance)(TSLexer *, bool); 52 | void (*mark_end)(TSLexer *); 53 | uint32_t (*get_column)(TSLexer *); 54 | bool (*is_at_included_range_start)(const TSLexer *); 55 | bool (*eof)(const TSLexer *); 56 | void (*log)(const TSLexer *, const char *, ...); 57 | }; 58 | 59 | typedef enum { 60 | TSParseActionTypeShift, 61 | TSParseActionTypeReduce, 62 | TSParseActionTypeAccept, 63 | TSParseActionTypeRecover, 64 | } TSParseActionType; 65 | 66 | typedef union { 67 | struct { 68 | uint8_t type; 69 | TSStateId state; 70 | bool extra; 71 | bool repetition; 72 | } shift; 73 | struct { 74 | uint8_t type; 75 | uint8_t child_count; 76 | TSSymbol symbol; 77 | int16_t dynamic_precedence; 78 | uint16_t production_id; 79 | } reduce; 80 | uint8_t type; 81 | } TSParseAction; 82 | 83 | typedef struct { 84 | uint16_t lex_state; 85 | uint16_t external_lex_state; 86 | } TSLexMode; 87 | 88 | typedef struct { 89 | uint16_t lex_state; 90 | uint16_t external_lex_state; 91 | uint16_t reserved_word_set_id; 92 | } TSLexerMode; 93 | 94 | typedef union { 95 | TSParseAction action; 96 | struct { 97 | uint8_t count; 98 | bool reusable; 99 | } entry; 100 | } TSParseActionEntry; 101 | 102 | typedef struct { 103 | int32_t start; 104 | int32_t end; 105 | } TSCharacterRange; 106 | 107 | struct TSLanguage { 108 | uint32_t abi_version; 109 | uint32_t symbol_count; 110 | uint32_t alias_count; 111 | uint32_t token_count; 112 | uint32_t external_token_count; 113 | uint32_t state_count; 114 | uint32_t large_state_count; 115 | uint32_t production_id_count; 116 | uint32_t field_count; 117 | uint16_t max_alias_sequence_length; 118 | const uint16_t *parse_table; 119 | const uint16_t *small_parse_table; 120 | const uint32_t *small_parse_table_map; 121 | const TSParseActionEntry *parse_actions; 122 | const char * const *symbol_names; 123 | const char * const *field_names; 124 | const TSMapSlice *field_map_slices; 125 | const TSFieldMapEntry *field_map_entries; 126 | const TSSymbolMetadata *symbol_metadata; 127 | const TSSymbol *public_symbol_map; 128 | const uint16_t *alias_map; 129 | const TSSymbol *alias_sequences; 130 | const TSLexerMode *lex_modes; 131 | bool (*lex_fn)(TSLexer *, TSStateId); 132 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 133 | TSSymbol keyword_capture_token; 134 | struct { 135 | const bool *states; 136 | const TSSymbol *symbol_map; 137 | void *(*create)(void); 138 | void (*destroy)(void *); 139 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 140 | unsigned (*serialize)(void *, char *); 141 | void (*deserialize)(void *, const char *, unsigned); 142 | } external_scanner; 143 | const TSStateId *primary_state_ids; 144 | const char *name; 145 | const TSSymbol *reserved_words; 146 | uint16_t max_reserved_word_set_size; 147 | uint32_t supertype_count; 148 | const TSSymbol *supertype_symbols; 149 | const TSMapSlice *supertype_map_slices; 150 | const TSSymbol *supertype_map_entries; 151 | TSLanguageMetadata metadata; 152 | }; 153 | 154 | static inline bool set_contains(const TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 155 | uint32_t index = 0; 156 | uint32_t size = len - index; 157 | while (size > 1) { 158 | uint32_t half_size = size / 2; 159 | uint32_t mid_index = index + half_size; 160 | const TSCharacterRange *range = &ranges[mid_index]; 161 | if (lookahead >= range->start && lookahead <= range->end) { 162 | return true; 163 | } else if (lookahead > range->end) { 164 | index = mid_index; 165 | } 166 | size -= half_size; 167 | } 168 | const TSCharacterRange *range = &ranges[index]; 169 | return (lookahead >= range->start && lookahead <= range->end); 170 | } 171 | 172 | /* 173 | * Lexer Macros 174 | */ 175 | 176 | #ifdef _MSC_VER 177 | #define UNUSED __pragma(warning(suppress : 4101)) 178 | #else 179 | #define UNUSED __attribute__((unused)) 180 | #endif 181 | 182 | #define START_LEXER() \ 183 | bool result = false; \ 184 | bool skip = false; \ 185 | UNUSED \ 186 | bool eof = false; \ 187 | int32_t lookahead; \ 188 | goto start; \ 189 | next_state: \ 190 | lexer->advance(lexer, skip); \ 191 | start: \ 192 | skip = false; \ 193 | lookahead = lexer->lookahead; 194 | 195 | #define ADVANCE(state_value) \ 196 | { \ 197 | state = state_value; \ 198 | goto next_state; \ 199 | } 200 | 201 | #define ADVANCE_MAP(...) \ 202 | { \ 203 | static const uint16_t map[] = { __VA_ARGS__ }; \ 204 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 205 | if (map[i] == lookahead) { \ 206 | state = map[i + 1]; \ 207 | goto next_state; \ 208 | } \ 209 | } \ 210 | } 211 | 212 | #define SKIP(state_value) \ 213 | { \ 214 | skip = true; \ 215 | state = state_value; \ 216 | goto next_state; \ 217 | } 218 | 219 | #define ACCEPT_TOKEN(symbol_value) \ 220 | result = true; \ 221 | lexer->result_symbol = symbol_value; \ 222 | lexer->mark_end(lexer); 223 | 224 | #define END_STATE() return result; 225 | 226 | /* 227 | * Parse Table Macros 228 | */ 229 | 230 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 231 | 232 | #define STATE(id) id 233 | 234 | #define ACTIONS(id) id 235 | 236 | #define SHIFT(state_value) \ 237 | {{ \ 238 | .shift = { \ 239 | .type = TSParseActionTypeShift, \ 240 | .state = (state_value) \ 241 | } \ 242 | }} 243 | 244 | #define SHIFT_REPEAT(state_value) \ 245 | {{ \ 246 | .shift = { \ 247 | .type = TSParseActionTypeShift, \ 248 | .state = (state_value), \ 249 | .repetition = true \ 250 | } \ 251 | }} 252 | 253 | #define SHIFT_EXTRA() \ 254 | {{ \ 255 | .shift = { \ 256 | .type = TSParseActionTypeShift, \ 257 | .extra = true \ 258 | } \ 259 | }} 260 | 261 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 262 | {{ \ 263 | .reduce = { \ 264 | .type = TSParseActionTypeReduce, \ 265 | .symbol = symbol_name, \ 266 | .child_count = children, \ 267 | .dynamic_precedence = precedence, \ 268 | .production_id = prod_id \ 269 | }, \ 270 | }} 271 | 272 | #define RECOVER() \ 273 | {{ \ 274 | .type = TSParseActionTypeRecover \ 275 | }} 276 | 277 | #define ACCEPT_INPUT() \ 278 | {{ \ 279 | .type = TSParseActionTypeAccept \ 280 | }} 281 | 282 | #ifdef __cplusplus 283 | } 284 | #endif 285 | 286 | #endif // TREE_SITTER_PARSER_H_ 287 | -------------------------------------------------------------------------------- /schema/json/src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | typedef struct TSLanguageMetadata { 22 | uint8_t major_version; 23 | uint8_t minor_version; 24 | uint8_t patch_version; 25 | } TSLanguageMetadata; 26 | #endif 27 | 28 | typedef struct { 29 | TSFieldId field_id; 30 | uint8_t child_index; 31 | bool inherited; 32 | } TSFieldMapEntry; 33 | 34 | // Used to index the field and supertype maps. 35 | typedef struct { 36 | uint16_t index; 37 | uint16_t length; 38 | } TSMapSlice; 39 | 40 | typedef struct { 41 | bool visible; 42 | bool named; 43 | bool supertype; 44 | } TSSymbolMetadata; 45 | 46 | typedef struct TSLexer TSLexer; 47 | 48 | struct TSLexer { 49 | int32_t lookahead; 50 | TSSymbol result_symbol; 51 | void (*advance)(TSLexer *, bool); 52 | void (*mark_end)(TSLexer *); 53 | uint32_t (*get_column)(TSLexer *); 54 | bool (*is_at_included_range_start)(const TSLexer *); 55 | bool (*eof)(const TSLexer *); 56 | void (*log)(const TSLexer *, const char *, ...); 57 | }; 58 | 59 | typedef enum { 60 | TSParseActionTypeShift, 61 | TSParseActionTypeReduce, 62 | TSParseActionTypeAccept, 63 | TSParseActionTypeRecover, 64 | } TSParseActionType; 65 | 66 | typedef union { 67 | struct { 68 | uint8_t type; 69 | TSStateId state; 70 | bool extra; 71 | bool repetition; 72 | } shift; 73 | struct { 74 | uint8_t type; 75 | uint8_t child_count; 76 | TSSymbol symbol; 77 | int16_t dynamic_precedence; 78 | uint16_t production_id; 79 | } reduce; 80 | uint8_t type; 81 | } TSParseAction; 82 | 83 | typedef struct { 84 | uint16_t lex_state; 85 | uint16_t external_lex_state; 86 | } TSLexMode; 87 | 88 | typedef struct { 89 | uint16_t lex_state; 90 | uint16_t external_lex_state; 91 | uint16_t reserved_word_set_id; 92 | } TSLexerMode; 93 | 94 | typedef union { 95 | TSParseAction action; 96 | struct { 97 | uint8_t count; 98 | bool reusable; 99 | } entry; 100 | } TSParseActionEntry; 101 | 102 | typedef struct { 103 | int32_t start; 104 | int32_t end; 105 | } TSCharacterRange; 106 | 107 | struct TSLanguage { 108 | uint32_t abi_version; 109 | uint32_t symbol_count; 110 | uint32_t alias_count; 111 | uint32_t token_count; 112 | uint32_t external_token_count; 113 | uint32_t state_count; 114 | uint32_t large_state_count; 115 | uint32_t production_id_count; 116 | uint32_t field_count; 117 | uint16_t max_alias_sequence_length; 118 | const uint16_t *parse_table; 119 | const uint16_t *small_parse_table; 120 | const uint32_t *small_parse_table_map; 121 | const TSParseActionEntry *parse_actions; 122 | const char * const *symbol_names; 123 | const char * const *field_names; 124 | const TSMapSlice *field_map_slices; 125 | const TSFieldMapEntry *field_map_entries; 126 | const TSSymbolMetadata *symbol_metadata; 127 | const TSSymbol *public_symbol_map; 128 | const uint16_t *alias_map; 129 | const TSSymbol *alias_sequences; 130 | const TSLexerMode *lex_modes; 131 | bool (*lex_fn)(TSLexer *, TSStateId); 132 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 133 | TSSymbol keyword_capture_token; 134 | struct { 135 | const bool *states; 136 | const TSSymbol *symbol_map; 137 | void *(*create)(void); 138 | void (*destroy)(void *); 139 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 140 | unsigned (*serialize)(void *, char *); 141 | void (*deserialize)(void *, const char *, unsigned); 142 | } external_scanner; 143 | const TSStateId *primary_state_ids; 144 | const char *name; 145 | const TSSymbol *reserved_words; 146 | uint16_t max_reserved_word_set_size; 147 | uint32_t supertype_count; 148 | const TSSymbol *supertype_symbols; 149 | const TSMapSlice *supertype_map_slices; 150 | const TSSymbol *supertype_map_entries; 151 | TSLanguageMetadata metadata; 152 | }; 153 | 154 | static inline bool set_contains(const TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 155 | uint32_t index = 0; 156 | uint32_t size = len - index; 157 | while (size > 1) { 158 | uint32_t half_size = size / 2; 159 | uint32_t mid_index = index + half_size; 160 | const TSCharacterRange *range = &ranges[mid_index]; 161 | if (lookahead >= range->start && lookahead <= range->end) { 162 | return true; 163 | } else if (lookahead > range->end) { 164 | index = mid_index; 165 | } 166 | size -= half_size; 167 | } 168 | const TSCharacterRange *range = &ranges[index]; 169 | return (lookahead >= range->start && lookahead <= range->end); 170 | } 171 | 172 | /* 173 | * Lexer Macros 174 | */ 175 | 176 | #ifdef _MSC_VER 177 | #define UNUSED __pragma(warning(suppress : 4101)) 178 | #else 179 | #define UNUSED __attribute__((unused)) 180 | #endif 181 | 182 | #define START_LEXER() \ 183 | bool result = false; \ 184 | bool skip = false; \ 185 | UNUSED \ 186 | bool eof = false; \ 187 | int32_t lookahead; \ 188 | goto start; \ 189 | next_state: \ 190 | lexer->advance(lexer, skip); \ 191 | start: \ 192 | skip = false; \ 193 | lookahead = lexer->lookahead; 194 | 195 | #define ADVANCE(state_value) \ 196 | { \ 197 | state = state_value; \ 198 | goto next_state; \ 199 | } 200 | 201 | #define ADVANCE_MAP(...) \ 202 | { \ 203 | static const uint16_t map[] = { __VA_ARGS__ }; \ 204 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 205 | if (map[i] == lookahead) { \ 206 | state = map[i + 1]; \ 207 | goto next_state; \ 208 | } \ 209 | } \ 210 | } 211 | 212 | #define SKIP(state_value) \ 213 | { \ 214 | skip = true; \ 215 | state = state_value; \ 216 | goto next_state; \ 217 | } 218 | 219 | #define ACCEPT_TOKEN(symbol_value) \ 220 | result = true; \ 221 | lexer->result_symbol = symbol_value; \ 222 | lexer->mark_end(lexer); 223 | 224 | #define END_STATE() return result; 225 | 226 | /* 227 | * Parse Table Macros 228 | */ 229 | 230 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 231 | 232 | #define STATE(id) id 233 | 234 | #define ACTIONS(id) id 235 | 236 | #define SHIFT(state_value) \ 237 | {{ \ 238 | .shift = { \ 239 | .type = TSParseActionTypeShift, \ 240 | .state = (state_value) \ 241 | } \ 242 | }} 243 | 244 | #define SHIFT_REPEAT(state_value) \ 245 | {{ \ 246 | .shift = { \ 247 | .type = TSParseActionTypeShift, \ 248 | .state = (state_value), \ 249 | .repetition = true \ 250 | } \ 251 | }} 252 | 253 | #define SHIFT_EXTRA() \ 254 | {{ \ 255 | .shift = { \ 256 | .type = TSParseActionTypeShift, \ 257 | .extra = true \ 258 | } \ 259 | }} 260 | 261 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 262 | {{ \ 263 | .reduce = { \ 264 | .type = TSParseActionTypeReduce, \ 265 | .symbol = symbol_name, \ 266 | .child_count = children, \ 267 | .dynamic_precedence = precedence, \ 268 | .production_id = prod_id \ 269 | }, \ 270 | }} 271 | 272 | #define RECOVER() \ 273 | {{ \ 274 | .type = TSParseActionTypeRecover \ 275 | }} 276 | 277 | #define ACCEPT_INPUT() \ 278 | {{ \ 279 | .type = TSParseActionTypeAccept \ 280 | }} 281 | 282 | #ifdef __cplusplus 283 | } 284 | #endif 285 | 286 | #endif // TREE_SITTER_PARSER_H_ 287 | -------------------------------------------------------------------------------- /schema/legacy/src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | typedef struct TSLanguageMetadata { 22 | uint8_t major_version; 23 | uint8_t minor_version; 24 | uint8_t patch_version; 25 | } TSLanguageMetadata; 26 | #endif 27 | 28 | typedef struct { 29 | TSFieldId field_id; 30 | uint8_t child_index; 31 | bool inherited; 32 | } TSFieldMapEntry; 33 | 34 | // Used to index the field and supertype maps. 35 | typedef struct { 36 | uint16_t index; 37 | uint16_t length; 38 | } TSMapSlice; 39 | 40 | typedef struct { 41 | bool visible; 42 | bool named; 43 | bool supertype; 44 | } TSSymbolMetadata; 45 | 46 | typedef struct TSLexer TSLexer; 47 | 48 | struct TSLexer { 49 | int32_t lookahead; 50 | TSSymbol result_symbol; 51 | void (*advance)(TSLexer *, bool); 52 | void (*mark_end)(TSLexer *); 53 | uint32_t (*get_column)(TSLexer *); 54 | bool (*is_at_included_range_start)(const TSLexer *); 55 | bool (*eof)(const TSLexer *); 56 | void (*log)(const TSLexer *, const char *, ...); 57 | }; 58 | 59 | typedef enum { 60 | TSParseActionTypeShift, 61 | TSParseActionTypeReduce, 62 | TSParseActionTypeAccept, 63 | TSParseActionTypeRecover, 64 | } TSParseActionType; 65 | 66 | typedef union { 67 | struct { 68 | uint8_t type; 69 | TSStateId state; 70 | bool extra; 71 | bool repetition; 72 | } shift; 73 | struct { 74 | uint8_t type; 75 | uint8_t child_count; 76 | TSSymbol symbol; 77 | int16_t dynamic_precedence; 78 | uint16_t production_id; 79 | } reduce; 80 | uint8_t type; 81 | } TSParseAction; 82 | 83 | typedef struct { 84 | uint16_t lex_state; 85 | uint16_t external_lex_state; 86 | } TSLexMode; 87 | 88 | typedef struct { 89 | uint16_t lex_state; 90 | uint16_t external_lex_state; 91 | uint16_t reserved_word_set_id; 92 | } TSLexerMode; 93 | 94 | typedef union { 95 | TSParseAction action; 96 | struct { 97 | uint8_t count; 98 | bool reusable; 99 | } entry; 100 | } TSParseActionEntry; 101 | 102 | typedef struct { 103 | int32_t start; 104 | int32_t end; 105 | } TSCharacterRange; 106 | 107 | struct TSLanguage { 108 | uint32_t abi_version; 109 | uint32_t symbol_count; 110 | uint32_t alias_count; 111 | uint32_t token_count; 112 | uint32_t external_token_count; 113 | uint32_t state_count; 114 | uint32_t large_state_count; 115 | uint32_t production_id_count; 116 | uint32_t field_count; 117 | uint16_t max_alias_sequence_length; 118 | const uint16_t *parse_table; 119 | const uint16_t *small_parse_table; 120 | const uint32_t *small_parse_table_map; 121 | const TSParseActionEntry *parse_actions; 122 | const char * const *symbol_names; 123 | const char * const *field_names; 124 | const TSMapSlice *field_map_slices; 125 | const TSFieldMapEntry *field_map_entries; 126 | const TSSymbolMetadata *symbol_metadata; 127 | const TSSymbol *public_symbol_map; 128 | const uint16_t *alias_map; 129 | const TSSymbol *alias_sequences; 130 | const TSLexerMode *lex_modes; 131 | bool (*lex_fn)(TSLexer *, TSStateId); 132 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 133 | TSSymbol keyword_capture_token; 134 | struct { 135 | const bool *states; 136 | const TSSymbol *symbol_map; 137 | void *(*create)(void); 138 | void (*destroy)(void *); 139 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 140 | unsigned (*serialize)(void *, char *); 141 | void (*deserialize)(void *, const char *, unsigned); 142 | } external_scanner; 143 | const TSStateId *primary_state_ids; 144 | const char *name; 145 | const TSSymbol *reserved_words; 146 | uint16_t max_reserved_word_set_size; 147 | uint32_t supertype_count; 148 | const TSSymbol *supertype_symbols; 149 | const TSMapSlice *supertype_map_slices; 150 | const TSSymbol *supertype_map_entries; 151 | TSLanguageMetadata metadata; 152 | }; 153 | 154 | static inline bool set_contains(const TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 155 | uint32_t index = 0; 156 | uint32_t size = len - index; 157 | while (size > 1) { 158 | uint32_t half_size = size / 2; 159 | uint32_t mid_index = index + half_size; 160 | const TSCharacterRange *range = &ranges[mid_index]; 161 | if (lookahead >= range->start && lookahead <= range->end) { 162 | return true; 163 | } else if (lookahead > range->end) { 164 | index = mid_index; 165 | } 166 | size -= half_size; 167 | } 168 | const TSCharacterRange *range = &ranges[index]; 169 | return (lookahead >= range->start && lookahead <= range->end); 170 | } 171 | 172 | /* 173 | * Lexer Macros 174 | */ 175 | 176 | #ifdef _MSC_VER 177 | #define UNUSED __pragma(warning(suppress : 4101)) 178 | #else 179 | #define UNUSED __attribute__((unused)) 180 | #endif 181 | 182 | #define START_LEXER() \ 183 | bool result = false; \ 184 | bool skip = false; \ 185 | UNUSED \ 186 | bool eof = false; \ 187 | int32_t lookahead; \ 188 | goto start; \ 189 | next_state: \ 190 | lexer->advance(lexer, skip); \ 191 | start: \ 192 | skip = false; \ 193 | lookahead = lexer->lookahead; 194 | 195 | #define ADVANCE(state_value) \ 196 | { \ 197 | state = state_value; \ 198 | goto next_state; \ 199 | } 200 | 201 | #define ADVANCE_MAP(...) \ 202 | { \ 203 | static const uint16_t map[] = { __VA_ARGS__ }; \ 204 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 205 | if (map[i] == lookahead) { \ 206 | state = map[i + 1]; \ 207 | goto next_state; \ 208 | } \ 209 | } \ 210 | } 211 | 212 | #define SKIP(state_value) \ 213 | { \ 214 | skip = true; \ 215 | state = state_value; \ 216 | goto next_state; \ 217 | } 218 | 219 | #define ACCEPT_TOKEN(symbol_value) \ 220 | result = true; \ 221 | lexer->result_symbol = symbol_value; \ 222 | lexer->mark_end(lexer); 223 | 224 | #define END_STATE() return result; 225 | 226 | /* 227 | * Parse Table Macros 228 | */ 229 | 230 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 231 | 232 | #define STATE(id) id 233 | 234 | #define ACTIONS(id) id 235 | 236 | #define SHIFT(state_value) \ 237 | {{ \ 238 | .shift = { \ 239 | .type = TSParseActionTypeShift, \ 240 | .state = (state_value) \ 241 | } \ 242 | }} 243 | 244 | #define SHIFT_REPEAT(state_value) \ 245 | {{ \ 246 | .shift = { \ 247 | .type = TSParseActionTypeShift, \ 248 | .state = (state_value), \ 249 | .repetition = true \ 250 | } \ 251 | }} 252 | 253 | #define SHIFT_EXTRA() \ 254 | {{ \ 255 | .shift = { \ 256 | .type = TSParseActionTypeShift, \ 257 | .extra = true \ 258 | } \ 259 | }} 260 | 261 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 262 | {{ \ 263 | .reduce = { \ 264 | .type = TSParseActionTypeReduce, \ 265 | .symbol = symbol_name, \ 266 | .child_count = children, \ 267 | .dynamic_precedence = precedence, \ 268 | .production_id = prod_id \ 269 | }, \ 270 | }} 271 | 272 | #define RECOVER() \ 273 | {{ \ 274 | .type = TSParseActionTypeRecover \ 275 | }} 276 | 277 | #define ACCEPT_INPUT() \ 278 | {{ \ 279 | .type = TSParseActionTypeAccept \ 280 | }} 281 | 282 | #ifdef __cplusplus 283 | } 284 | #endif 285 | 286 | #endif // TREE_SITTER_PARSER_H_ 287 | -------------------------------------------------------------------------------- /schema/legacy/src/grammar.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json", 3 | "name": "legacy_schema", 4 | "rules": { 5 | "scalar": { 6 | "type": "CHOICE", 7 | "members": [ 8 | { 9 | "type": "SYMBOL", 10 | "name": "null" 11 | }, 12 | { 13 | "type": "SYMBOL", 14 | "name": "bool" 15 | }, 16 | { 17 | "type": "SYMBOL", 18 | "name": "int" 19 | }, 20 | { 21 | "type": "SYMBOL", 22 | "name": "float" 23 | }, 24 | { 25 | "type": "SYMBOL", 26 | "name": "timestamp" 27 | } 28 | ] 29 | }, 30 | "null": { 31 | "type": "TOKEN", 32 | "content": { 33 | "type": "CHOICE", 34 | "members": [ 35 | { 36 | "type": "STRING", 37 | "value": "~" 38 | }, 39 | { 40 | "type": "STRING", 41 | "value": "null" 42 | }, 43 | { 44 | "type": "STRING", 45 | "value": "Null" 46 | }, 47 | { 48 | "type": "STRING", 49 | "value": "NULL" 50 | } 51 | ] 52 | } 53 | }, 54 | "bool": { 55 | "type": "TOKEN", 56 | "content": { 57 | "type": "CHOICE", 58 | "members": [ 59 | { 60 | "type": "STRING", 61 | "value": "y" 62 | }, 63 | { 64 | "type": "STRING", 65 | "value": "Y" 66 | }, 67 | { 68 | "type": "STRING", 69 | "value": "yes" 70 | }, 71 | { 72 | "type": "STRING", 73 | "value": "Yes" 74 | }, 75 | { 76 | "type": "STRING", 77 | "value": "YES" 78 | }, 79 | { 80 | "type": "STRING", 81 | "value": "n" 82 | }, 83 | { 84 | "type": "STRING", 85 | "value": "N" 86 | }, 87 | { 88 | "type": "STRING", 89 | "value": "no" 90 | }, 91 | { 92 | "type": "STRING", 93 | "value": "No" 94 | }, 95 | { 96 | "type": "STRING", 97 | "value": "NO" 98 | }, 99 | { 100 | "type": "STRING", 101 | "value": "true" 102 | }, 103 | { 104 | "type": "STRING", 105 | "value": "True" 106 | }, 107 | { 108 | "type": "STRING", 109 | "value": "TRUE" 110 | }, 111 | { 112 | "type": "STRING", 113 | "value": "false" 114 | }, 115 | { 116 | "type": "STRING", 117 | "value": "False" 118 | }, 119 | { 120 | "type": "STRING", 121 | "value": "FALSE" 122 | }, 123 | { 124 | "type": "STRING", 125 | "value": "on" 126 | }, 127 | { 128 | "type": "STRING", 129 | "value": "On" 130 | }, 131 | { 132 | "type": "STRING", 133 | "value": "ON" 134 | }, 135 | { 136 | "type": "STRING", 137 | "value": "off" 138 | }, 139 | { 140 | "type": "STRING", 141 | "value": "Off" 142 | }, 143 | { 144 | "type": "STRING", 145 | "value": "OFF" 146 | } 147 | ] 148 | } 149 | }, 150 | "int": { 151 | "type": "TOKEN", 152 | "content": { 153 | "type": "CHOICE", 154 | "members": [ 155 | { 156 | "type": "PATTERN", 157 | "value": "[-+]?0b[0-1_]+" 158 | }, 159 | { 160 | "type": "PATTERN", 161 | "value": "[-+]?0[0-7_]+" 162 | }, 163 | { 164 | "type": "PATTERN", 165 | "value": "[-+]?(0|[1-9][0-9_]*)" 166 | }, 167 | { 168 | "type": "PATTERN", 169 | "value": "[-+]?0x[0-9a-fA-F_]+" 170 | }, 171 | { 172 | "type": "PATTERN", 173 | "value": "[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+" 174 | } 175 | ] 176 | } 177 | }, 178 | "float": { 179 | "type": "TOKEN", 180 | "content": { 181 | "type": "CHOICE", 182 | "members": [ 183 | { 184 | "type": "PATTERN", 185 | "value": "[-+]?([0-9][0-9_]*)?\\.[0-9.]*([eE][-+][0-9]+)?" 186 | }, 187 | { 188 | "type": "PATTERN", 189 | "value": "[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\\.[0-9_]*" 190 | }, 191 | { 192 | "type": "SEQ", 193 | "members": [ 194 | { 195 | "type": "CHOICE", 196 | "members": [ 197 | { 198 | "type": "CHOICE", 199 | "members": [ 200 | { 201 | "type": "STRING", 202 | "value": "-" 203 | }, 204 | { 205 | "type": "STRING", 206 | "value": "+" 207 | } 208 | ] 209 | }, 210 | { 211 | "type": "BLANK" 212 | } 213 | ] 214 | }, 215 | { 216 | "type": "CHOICE", 217 | "members": [ 218 | { 219 | "type": "STRING", 220 | "value": ".inf" 221 | }, 222 | { 223 | "type": "STRING", 224 | "value": ".Inf" 225 | }, 226 | { 227 | "type": "STRING", 228 | "value": ".INF" 229 | } 230 | ] 231 | } 232 | ] 233 | }, 234 | { 235 | "type": "CHOICE", 236 | "members": [ 237 | { 238 | "type": "STRING", 239 | "value": ".nan" 240 | }, 241 | { 242 | "type": "STRING", 243 | "value": ".NaN" 244 | }, 245 | { 246 | "type": "STRING", 247 | "value": ".NAN" 248 | } 249 | ] 250 | } 251 | ] 252 | } 253 | }, 254 | "timestamp": { 255 | "type": "TOKEN", 256 | "content": { 257 | "type": "CHOICE", 258 | "members": [ 259 | { 260 | "type": "PATTERN", 261 | "value": "\\d\\d\\d\\d-\\d\\d-\\d\\d" 262 | }, 263 | { 264 | "type": "SEQ", 265 | "members": [ 266 | { 267 | "type": "PATTERN", 268 | "value": "\\d\\d\\d\\d-\\d\\d?-\\d\\d?" 269 | }, 270 | { 271 | "type": "CHOICE", 272 | "members": [ 273 | { 274 | "type": "STRING", 275 | "value": "T" 276 | }, 277 | { 278 | "type": "STRING", 279 | "value": "t" 280 | }, 281 | { 282 | "type": "PATTERN", 283 | "value": "[ \\t]+" 284 | } 285 | ] 286 | }, 287 | { 288 | "type": "PATTERN", 289 | "value": "\\d\\d?:\\d\\d:\\d\\d" 290 | }, 291 | { 292 | "type": "CHOICE", 293 | "members": [ 294 | { 295 | "type": "PATTERN", 296 | "value": "\\.\\d+" 297 | }, 298 | { 299 | "type": "BLANK" 300 | } 301 | ] 302 | }, 303 | { 304 | "type": "CHOICE", 305 | "members": [ 306 | { 307 | "type": "CHOICE", 308 | "members": [ 309 | { 310 | "type": "PATTERN", 311 | "value": "[ \\t]*Z" 312 | }, 313 | { 314 | "type": "PATTERN", 315 | "value": "[-+]\\d\\d?(:\\d\\d)?" 316 | } 317 | ] 318 | }, 319 | { 320 | "type": "BLANK" 321 | } 322 | ] 323 | } 324 | ] 325 | } 326 | ] 327 | } 328 | } 329 | }, 330 | "extras": [], 331 | "conflicts": [], 332 | "precedences": [], 333 | "externals": [], 334 | "inline": [], 335 | "supertypes": [], 336 | "reserved": {} 337 | } -------------------------------------------------------------------------------- /test/corpus/05_characters.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Byte Order Mark 3 | ================================================================================ 4 | # Comment only. 5 | 6 | -------------------------------------------------------------------------------- 7 | 8 | (stream 9 | (comment)) 10 | 11 | ================================================================================ 12 | Invalid Byte Order Mark 13 | :error 14 | ================================================================================ 15 | - Invalid use of BOM 16 |  17 | - Inside a document. 18 | 19 | -------------------------------------------------------------------------------- 20 | 21 | ================================================================================ 22 | Block Structure Indicators 23 | ================================================================================ 24 | sequence: 25 | - one 26 | - two 27 | mapping: 28 | ? sky 29 | : blue 30 | sea : green 31 | 32 | -------------------------------------------------------------------------------- 33 | 34 | (stream 35 | (document 36 | (block_node 37 | (block_mapping 38 | (block_mapping_pair 39 | (flow_node 40 | (plain_scalar 41 | (string_scalar))) 42 | (block_node 43 | (block_sequence 44 | (block_sequence_item 45 | (flow_node 46 | (plain_scalar 47 | (string_scalar)))) 48 | (block_sequence_item 49 | (flow_node 50 | (plain_scalar 51 | (string_scalar))))))) 52 | (block_mapping_pair 53 | (flow_node 54 | (plain_scalar 55 | (string_scalar))) 56 | (block_node 57 | (block_mapping 58 | (block_mapping_pair 59 | (flow_node 60 | (plain_scalar 61 | (string_scalar))) 62 | (flow_node 63 | (plain_scalar 64 | (string_scalar)))) 65 | (block_mapping_pair 66 | (flow_node 67 | (plain_scalar 68 | (string_scalar))) 69 | (flow_node 70 | (plain_scalar 71 | (string_scalar))))))))))) 72 | 73 | ================================================================================ 74 | Flow Collection Indicators 75 | ================================================================================ 76 | sequence: [ one, two, ] 77 | mapping: { sky: blue, sea: green } 78 | 79 | -------------------------------------------------------------------------------- 80 | 81 | (stream 82 | (document 83 | (block_node 84 | (block_mapping 85 | (block_mapping_pair 86 | (flow_node 87 | (plain_scalar 88 | (string_scalar))) 89 | (flow_node 90 | (flow_sequence 91 | (flow_node 92 | (plain_scalar 93 | (string_scalar))) 94 | (flow_node 95 | (plain_scalar 96 | (string_scalar)))))) 97 | (block_mapping_pair 98 | (flow_node 99 | (plain_scalar 100 | (string_scalar))) 101 | (flow_node 102 | (flow_mapping 103 | (flow_pair 104 | (flow_node 105 | (plain_scalar 106 | (string_scalar))) 107 | (flow_node 108 | (plain_scalar 109 | (string_scalar)))) 110 | (flow_pair 111 | (flow_node 112 | (plain_scalar 113 | (string_scalar))) 114 | (flow_node 115 | (plain_scalar 116 | (string_scalar))))))))))) 117 | 118 | ================================================================================ 119 | Comment Indicator 120 | ================================================================================ 121 | # Comment only. 122 | 123 | -------------------------------------------------------------------------------- 124 | 125 | (stream 126 | (comment)) 127 | 128 | ================================================================================ 129 | Node Property Indicators 130 | ================================================================================ 131 | anchored: !local &anchor value 132 | alias: *anchor 133 | 134 | -------------------------------------------------------------------------------- 135 | 136 | (stream 137 | (document 138 | (block_node 139 | (block_mapping 140 | (block_mapping_pair 141 | (flow_node 142 | (plain_scalar 143 | (string_scalar))) 144 | (flow_node 145 | (tag) 146 | (anchor 147 | (anchor_name)) 148 | (plain_scalar 149 | (string_scalar)))) 150 | (block_mapping_pair 151 | (flow_node 152 | (plain_scalar 153 | (string_scalar))) 154 | (flow_node 155 | (alias 156 | (alias_name)))))))) 157 | 158 | ================================================================================ 159 | Block Scalar Indicators 160 | ================================================================================ 161 | literal: | 162 | some 163 | text 164 | folded: > 165 | some 166 | text 167 | 168 | -------------------------------------------------------------------------------- 169 | 170 | (stream 171 | (document 172 | (block_node 173 | (block_mapping 174 | (block_mapping_pair 175 | (flow_node 176 | (plain_scalar 177 | (string_scalar))) 178 | (block_node 179 | (block_scalar))) 180 | (block_mapping_pair 181 | (flow_node 182 | (plain_scalar 183 | (string_scalar))) 184 | (block_node 185 | (block_scalar))))))) 186 | 187 | ================================================================================ 188 | Quoted Scalar Indicators 189 | ================================================================================ 190 | single: 'text' 191 | double: "text" 192 | 193 | -------------------------------------------------------------------------------- 194 | 195 | (stream 196 | (document 197 | (block_node 198 | (block_mapping 199 | (block_mapping_pair 200 | (flow_node 201 | (plain_scalar 202 | (string_scalar))) 203 | (flow_node 204 | (single_quote_scalar))) 205 | (block_mapping_pair 206 | (flow_node 207 | (plain_scalar 208 | (string_scalar))) 209 | (flow_node 210 | (double_quote_scalar))))))) 211 | 212 | ================================================================================ 213 | Directive Indicator 214 | ================================================================================ 215 | %YAML 1.2 216 | --- text 217 | 218 | -------------------------------------------------------------------------------- 219 | 220 | (stream 221 | (document 222 | (yaml_directive 223 | (yaml_version)) 224 | (flow_node 225 | (plain_scalar 226 | (string_scalar))))) 227 | 228 | ================================================================================ 229 | Invalid use of Reserved Indicators 230 | :error 231 | ================================================================================ 232 | commercial-at: @text 233 | grave-accent: `text 234 | 235 | -------------------------------------------------------------------------------- 236 | 237 | ================================================================================ 238 | Line Break Characters 239 | ================================================================================ 240 | | 241 | Line break (no glyph) 242 | Line break (glyphed) 243 | 244 | 245 | -------------------------------------------------------------------------------- 246 | 247 | (stream 248 | (document 249 | (block_node 250 | (block_scalar)))) 251 | 252 | ================================================================================ 253 | Tabs and Spaces 254 | ================================================================================ 255 | # Tabs and spaces 256 | quoted: "Quoted " 257 | block: | 258 | void main() { 259 | printf("Hello, world!\n"); 260 | } 261 | 262 | -------------------------------------------------------------------------------- 263 | 264 | (stream 265 | (comment) 266 | (document 267 | (block_node 268 | (block_mapping 269 | (block_mapping_pair 270 | (flow_node 271 | (plain_scalar 272 | (string_scalar))) 273 | (flow_node 274 | (double_quote_scalar))) 275 | (block_mapping_pair 276 | (flow_node 277 | (plain_scalar 278 | (string_scalar))) 279 | (block_node 280 | (block_scalar))))))) 281 | 282 | ================================================================================ 283 | Escaped Characters 284 | ================================================================================ 285 | "Fun with \\ 286 | \" \a \b \e \f 287 | \n \r \t \v \0 288 | \ \_ \N \L \P 289 | \x41 \u0041 \U00000041" 290 | 291 | -------------------------------------------------------------------------------- 292 | 293 | (stream 294 | (document 295 | (flow_node 296 | (double_quote_scalar 297 | (escape_sequence) 298 | (escape_sequence) 299 | (escape_sequence) 300 | (escape_sequence) 301 | (escape_sequence) 302 | (escape_sequence) 303 | (escape_sequence) 304 | (escape_sequence) 305 | (escape_sequence) 306 | (escape_sequence) 307 | (escape_sequence) 308 | (escape_sequence) 309 | (escape_sequence) 310 | (escape_sequence) 311 | (escape_sequence) 312 | (escape_sequence) 313 | (escape_sequence) 314 | (escape_sequence) 315 | (escape_sequence))))) 316 | 317 | ================================================================================ 318 | Invalid Escaped Characters 319 | :error 320 | ================================================================================ 321 | Bad escapes: 322 | "\c 323 | \xq-" 324 | 325 | -------------------------------------------------------------------------------- 326 | 327 | -------------------------------------------------------------------------------- /schema/core/src/parser.c: -------------------------------------------------------------------------------- 1 | /* Automatically @generated by tree-sitter v0.25.4 (726dcd1e872149d95de581589fc408fb8ea9cb0b) */ 2 | 3 | #include "tree_sitter/parser.h" 4 | 5 | #if defined(__GNUC__) || defined(__clang__) 6 | #pragma GCC diagnostic ignored "-Wmissing-field-initializers" 7 | #endif 8 | 9 | #define LANGUAGE_VERSION 14 10 | #define STATE_COUNT 4 11 | #define LARGE_STATE_COUNT 2 12 | #define SYMBOL_COUNT 6 13 | #define ALIAS_COUNT 0 14 | #define TOKEN_COUNT 5 15 | #define EXTERNAL_TOKEN_COUNT 0 16 | #define FIELD_COUNT 0 17 | #define MAX_ALIAS_SEQUENCE_LENGTH 1 18 | #define MAX_RESERVED_WORD_SET_SIZE 0 19 | #define PRODUCTION_ID_COUNT 1 20 | #define SUPERTYPE_COUNT 0 21 | 22 | enum ts_symbol_identifiers { 23 | sym_null = 1, 24 | sym_bool = 2, 25 | sym_int = 3, 26 | sym_float = 4, 27 | sym_scalar = 5, 28 | }; 29 | 30 | static const char * const ts_symbol_names[] = { 31 | [ts_builtin_sym_end] = "end", 32 | [sym_null] = "null", 33 | [sym_bool] = "bool", 34 | [sym_int] = "int", 35 | [sym_float] = "float", 36 | [sym_scalar] = "scalar", 37 | }; 38 | 39 | static const TSSymbol ts_symbol_map[] = { 40 | [ts_builtin_sym_end] = ts_builtin_sym_end, 41 | [sym_null] = sym_null, 42 | [sym_bool] = sym_bool, 43 | [sym_int] = sym_int, 44 | [sym_float] = sym_float, 45 | [sym_scalar] = sym_scalar, 46 | }; 47 | 48 | static const TSSymbolMetadata ts_symbol_metadata[] = { 49 | [ts_builtin_sym_end] = { 50 | .visible = false, 51 | .named = true, 52 | }, 53 | [sym_null] = { 54 | .visible = true, 55 | .named = true, 56 | }, 57 | [sym_bool] = { 58 | .visible = true, 59 | .named = true, 60 | }, 61 | [sym_int] = { 62 | .visible = true, 63 | .named = true, 64 | }, 65 | [sym_float] = { 66 | .visible = true, 67 | .named = true, 68 | }, 69 | [sym_scalar] = { 70 | .visible = true, 71 | .named = true, 72 | }, 73 | }; 74 | 75 | static const TSSymbol ts_alias_sequences[PRODUCTION_ID_COUNT][MAX_ALIAS_SEQUENCE_LENGTH] = { 76 | [0] = {0}, 77 | }; 78 | 79 | static const uint16_t ts_non_terminal_alias_map[] = { 80 | 0, 81 | }; 82 | 83 | static const TSStateId ts_primary_state_ids[STATE_COUNT] = { 84 | [0] = 0, 85 | [1] = 1, 86 | [2] = 2, 87 | [3] = 3, 88 | }; 89 | 90 | static bool ts_lex(TSLexer *lexer, TSStateId state) { 91 | START_LEXER(); 92 | eof = lexer->eof(lexer); 93 | switch (state) { 94 | case 0: 95 | if (eof) ADVANCE(34); 96 | ADVANCE_MAP( 97 | '.', 6, 98 | '0', 37, 99 | 'F', 2, 100 | 'N', 16, 101 | 'T', 13, 102 | 'f', 17, 103 | 'n', 29, 104 | 't', 26, 105 | '~', 35, 106 | '+', 1, 107 | '-', 1, 108 | ); 109 | if (('1' <= lookahead && lookahead <= '9')) ADVANCE(38); 110 | END_STATE(); 111 | case 1: 112 | if (lookahead == '.') ADVANCE(7); 113 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(38); 114 | END_STATE(); 115 | case 2: 116 | if (lookahead == 'A') ADVANCE(9); 117 | if (lookahead == 'a') ADVANCE(22); 118 | END_STATE(); 119 | case 3: 120 | if (lookahead == 'A') ADVANCE(12); 121 | if (lookahead == 'a') ADVANCE(12); 122 | END_STATE(); 123 | case 4: 124 | if (lookahead == 'E') ADVANCE(36); 125 | END_STATE(); 126 | case 5: 127 | if (lookahead == 'F') ADVANCE(41); 128 | END_STATE(); 129 | case 6: 130 | if (lookahead == 'I') ADVANCE(11); 131 | if (lookahead == 'N') ADVANCE(3); 132 | if (lookahead == 'i') ADVANCE(24); 133 | if (lookahead == 'n') ADVANCE(18); 134 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(42); 135 | END_STATE(); 136 | case 7: 137 | if (lookahead == 'I') ADVANCE(11); 138 | if (lookahead == 'i') ADVANCE(24); 139 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(42); 140 | END_STATE(); 141 | case 8: 142 | if (lookahead == 'L') ADVANCE(35); 143 | END_STATE(); 144 | case 9: 145 | if (lookahead == 'L') ADVANCE(14); 146 | END_STATE(); 147 | case 10: 148 | if (lookahead == 'L') ADVANCE(8); 149 | END_STATE(); 150 | case 11: 151 | if (lookahead == 'N') ADVANCE(5); 152 | if (lookahead == 'n') ADVANCE(20); 153 | END_STATE(); 154 | case 12: 155 | if (lookahead == 'N') ADVANCE(41); 156 | END_STATE(); 157 | case 13: 158 | if (lookahead == 'R') ADVANCE(15); 159 | if (lookahead == 'r') ADVANCE(28); 160 | END_STATE(); 161 | case 14: 162 | if (lookahead == 'S') ADVANCE(4); 163 | END_STATE(); 164 | case 15: 165 | if (lookahead == 'U') ADVANCE(4); 166 | END_STATE(); 167 | case 16: 168 | if (lookahead == 'U') ADVANCE(10); 169 | if (lookahead == 'u') ADVANCE(23); 170 | END_STATE(); 171 | case 17: 172 | if (lookahead == 'a') ADVANCE(22); 173 | END_STATE(); 174 | case 18: 175 | if (lookahead == 'a') ADVANCE(25); 176 | END_STATE(); 177 | case 19: 178 | if (lookahead == 'e') ADVANCE(36); 179 | END_STATE(); 180 | case 20: 181 | if (lookahead == 'f') ADVANCE(41); 182 | END_STATE(); 183 | case 21: 184 | if (lookahead == 'l') ADVANCE(35); 185 | END_STATE(); 186 | case 22: 187 | if (lookahead == 'l') ADVANCE(27); 188 | END_STATE(); 189 | case 23: 190 | if (lookahead == 'l') ADVANCE(21); 191 | END_STATE(); 192 | case 24: 193 | if (lookahead == 'n') ADVANCE(20); 194 | END_STATE(); 195 | case 25: 196 | if (lookahead == 'n') ADVANCE(41); 197 | END_STATE(); 198 | case 26: 199 | if (lookahead == 'r') ADVANCE(28); 200 | END_STATE(); 201 | case 27: 202 | if (lookahead == 's') ADVANCE(19); 203 | END_STATE(); 204 | case 28: 205 | if (lookahead == 'u') ADVANCE(19); 206 | END_STATE(); 207 | case 29: 208 | if (lookahead == 'u') ADVANCE(23); 209 | END_STATE(); 210 | case 30: 211 | if (lookahead == '+' || 212 | lookahead == '-') ADVANCE(32); 213 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(43); 214 | END_STATE(); 215 | case 31: 216 | if (('0' <= lookahead && lookahead <= '7')) ADVANCE(39); 217 | END_STATE(); 218 | case 32: 219 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(43); 220 | END_STATE(); 221 | case 33: 222 | if (('0' <= lookahead && lookahead <= '9') || 223 | ('A' <= lookahead && lookahead <= 'F') || 224 | ('a' <= lookahead && lookahead <= 'f')) ADVANCE(40); 225 | END_STATE(); 226 | case 34: 227 | ACCEPT_TOKEN(ts_builtin_sym_end); 228 | END_STATE(); 229 | case 35: 230 | ACCEPT_TOKEN(sym_null); 231 | END_STATE(); 232 | case 36: 233 | ACCEPT_TOKEN(sym_bool); 234 | END_STATE(); 235 | case 37: 236 | ACCEPT_TOKEN(sym_int); 237 | if (lookahead == '.') ADVANCE(42); 238 | if (lookahead == 'o') ADVANCE(31); 239 | if (lookahead == 'x') ADVANCE(33); 240 | if (lookahead == 'E' || 241 | lookahead == 'e') ADVANCE(30); 242 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(38); 243 | END_STATE(); 244 | case 38: 245 | ACCEPT_TOKEN(sym_int); 246 | if (lookahead == '.') ADVANCE(42); 247 | if (lookahead == 'E' || 248 | lookahead == 'e') ADVANCE(30); 249 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(38); 250 | END_STATE(); 251 | case 39: 252 | ACCEPT_TOKEN(sym_int); 253 | if (('0' <= lookahead && lookahead <= '7')) ADVANCE(39); 254 | END_STATE(); 255 | case 40: 256 | ACCEPT_TOKEN(sym_int); 257 | if (('0' <= lookahead && lookahead <= '9') || 258 | ('A' <= lookahead && lookahead <= 'F') || 259 | ('a' <= lookahead && lookahead <= 'f')) ADVANCE(40); 260 | END_STATE(); 261 | case 41: 262 | ACCEPT_TOKEN(sym_float); 263 | END_STATE(); 264 | case 42: 265 | ACCEPT_TOKEN(sym_float); 266 | if (lookahead == 'E' || 267 | lookahead == 'e') ADVANCE(30); 268 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(42); 269 | END_STATE(); 270 | case 43: 271 | ACCEPT_TOKEN(sym_float); 272 | if (('0' <= lookahead && lookahead <= '9')) ADVANCE(43); 273 | END_STATE(); 274 | default: 275 | return false; 276 | } 277 | } 278 | 279 | static const TSLexMode ts_lex_modes[STATE_COUNT] = { 280 | [0] = {.lex_state = 0}, 281 | [1] = {.lex_state = 0}, 282 | [2] = {.lex_state = 0}, 283 | [3] = {.lex_state = 0}, 284 | }; 285 | 286 | static const uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = { 287 | [STATE(0)] = { 288 | [ts_builtin_sym_end] = ACTIONS(1), 289 | [sym_null] = ACTIONS(1), 290 | [sym_bool] = ACTIONS(1), 291 | [sym_int] = ACTIONS(1), 292 | [sym_float] = ACTIONS(1), 293 | }, 294 | [STATE(1)] = { 295 | [sym_scalar] = STATE(3), 296 | [sym_null] = ACTIONS(3), 297 | [sym_bool] = ACTIONS(3), 298 | [sym_int] = ACTIONS(5), 299 | [sym_float] = ACTIONS(5), 300 | }, 301 | }; 302 | 303 | static const uint16_t ts_small_parse_table[] = { 304 | [0] = 1, 305 | ACTIONS(7), 1, 306 | ts_builtin_sym_end, 307 | [4] = 1, 308 | ACTIONS(9), 1, 309 | ts_builtin_sym_end, 310 | }; 311 | 312 | static const uint32_t ts_small_parse_table_map[] = { 313 | [SMALL_STATE(2)] = 0, 314 | [SMALL_STATE(3)] = 4, 315 | }; 316 | 317 | static const TSParseActionEntry ts_parse_actions[] = { 318 | [0] = {.entry = {.count = 0, .reusable = false}}, 319 | [1] = {.entry = {.count = 1, .reusable = false}}, RECOVER(), 320 | [3] = {.entry = {.count = 1, .reusable = true}}, SHIFT(2), 321 | [5] = {.entry = {.count = 1, .reusable = false}}, SHIFT(2), 322 | [7] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_scalar, 1, 0, 0), 323 | [9] = {.entry = {.count = 1, .reusable = true}}, ACCEPT_INPUT(), 324 | }; 325 | 326 | #ifdef __cplusplus 327 | extern "C" { 328 | #endif 329 | #ifdef TREE_SITTER_HIDE_SYMBOLS 330 | #define TS_PUBLIC 331 | #elif defined(_WIN32) 332 | #define TS_PUBLIC __declspec(dllexport) 333 | #else 334 | #define TS_PUBLIC __attribute__((visibility("default"))) 335 | #endif 336 | 337 | TS_PUBLIC const TSLanguage *tree_sitter_core_schema(void) { 338 | static const TSLanguage language = { 339 | .abi_version = LANGUAGE_VERSION, 340 | .symbol_count = SYMBOL_COUNT, 341 | .alias_count = ALIAS_COUNT, 342 | .token_count = TOKEN_COUNT, 343 | .external_token_count = EXTERNAL_TOKEN_COUNT, 344 | .state_count = STATE_COUNT, 345 | .large_state_count = LARGE_STATE_COUNT, 346 | .production_id_count = PRODUCTION_ID_COUNT, 347 | .field_count = FIELD_COUNT, 348 | .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, 349 | .parse_table = &ts_parse_table[0][0], 350 | .small_parse_table = ts_small_parse_table, 351 | .small_parse_table_map = ts_small_parse_table_map, 352 | .parse_actions = ts_parse_actions, 353 | .symbol_names = ts_symbol_names, 354 | .symbol_metadata = ts_symbol_metadata, 355 | .public_symbol_map = ts_symbol_map, 356 | .alias_map = ts_non_terminal_alias_map, 357 | .alias_sequences = &ts_alias_sequences[0][0], 358 | .lex_modes = (const void*)ts_lex_modes, 359 | .lex_fn = ts_lex, 360 | .primary_state_ids = ts_primary_state_ids, 361 | }; 362 | return &language; 363 | } 364 | #ifdef __cplusplus 365 | } 366 | #endif 367 | -------------------------------------------------------------------------------- /src/tree_sitter/array.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ARRAY_H_ 2 | #define TREE_SITTER_ARRAY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "./alloc.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _MSC_VER 17 | #pragma warning(push) 18 | #pragma warning(disable : 4101) 19 | #elif defined(__GNUC__) || defined(__clang__) 20 | #pragma GCC diagnostic push 21 | #pragma GCC diagnostic ignored "-Wunused-variable" 22 | #endif 23 | 24 | #define Array(T) \ 25 | struct { \ 26 | T *contents; \ 27 | uint32_t size; \ 28 | uint32_t capacity; \ 29 | } 30 | 31 | /// Initialize an array. 32 | #define array_init(self) \ 33 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 34 | 35 | /// Create an empty array. 36 | #define array_new() \ 37 | { NULL, 0, 0 } 38 | 39 | /// Get a pointer to the element at a given `index` in the array. 40 | #define array_get(self, _index) \ 41 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 42 | 43 | /// Get a pointer to the first element in the array. 44 | #define array_front(self) array_get(self, 0) 45 | 46 | /// Get a pointer to the last element in the array. 47 | #define array_back(self) array_get(self, (self)->size - 1) 48 | 49 | /// Clear the array, setting its size to zero. Note that this does not free any 50 | /// memory allocated for the array's contents. 51 | #define array_clear(self) ((self)->size = 0) 52 | 53 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 54 | /// less than the array's current capacity, this function has no effect. 55 | #define array_reserve(self, new_capacity) \ 56 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 57 | 58 | /// Free any memory allocated for this array. Note that this does not free any 59 | /// memory allocated for the array's contents. 60 | #define array_delete(self) _array__delete((Array *)(self)) 61 | 62 | /// Push a new `element` onto the end of the array. 63 | #define array_push(self, element) \ 64 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 65 | (self)->contents[(self)->size++] = (element)) 66 | 67 | /// Increase the array's size by `count` elements. 68 | /// New elements are zero-initialized. 69 | #define array_grow_by(self, count) \ 70 | do { \ 71 | if ((count) == 0) break; \ 72 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 73 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 74 | (self)->size += (count); \ 75 | } while (0) 76 | 77 | /// Append all elements from one array to the end of another. 78 | #define array_push_all(self, other) \ 79 | array_extend((self), (other)->size, (other)->contents) 80 | 81 | /// Append `count` elements to the end of the array, reading their values from the 82 | /// `contents` pointer. 83 | #define array_extend(self, count, contents) \ 84 | _array__splice( \ 85 | (Array *)(self), array_elem_size(self), (self)->size, \ 86 | 0, count, contents \ 87 | ) 88 | 89 | /// Remove `old_count` elements from the array starting at the given `index`. At 90 | /// the same index, insert `new_count` new elements, reading their values from the 91 | /// `new_contents` pointer. 92 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 93 | _array__splice( \ 94 | (Array *)(self), array_elem_size(self), _index, \ 95 | old_count, new_count, new_contents \ 96 | ) 97 | 98 | /// Insert one `element` into the array at the given `index`. 99 | #define array_insert(self, _index, element) \ 100 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 101 | 102 | /// Remove one element from the array at the given `index`. 103 | #define array_erase(self, _index) \ 104 | _array__erase((Array *)(self), array_elem_size(self), _index) 105 | 106 | /// Pop the last element off the array, returning the element by value. 107 | #define array_pop(self) ((self)->contents[--(self)->size]) 108 | 109 | /// Assign the contents of one array to another, reallocating if necessary. 110 | #define array_assign(self, other) \ 111 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 112 | 113 | /// Swap one array with another 114 | #define array_swap(self, other) \ 115 | _array__swap((Array *)(self), (Array *)(other)) 116 | 117 | /// Get the size of the array contents 118 | #define array_elem_size(self) (sizeof *(self)->contents) 119 | 120 | /// Search a sorted array for a given `needle` value, using the given `compare` 121 | /// callback to determine the order. 122 | /// 123 | /// If an existing element is found to be equal to `needle`, then the `index` 124 | /// out-parameter is set to the existing value's index, and the `exists` 125 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 126 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 127 | /// is set to false. 128 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 129 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 130 | 131 | /// Search a sorted array for a given `needle` value, using integer comparisons 132 | /// of a given struct field (specified with a leading dot) to determine the order. 133 | /// 134 | /// See also `array_search_sorted_with`. 135 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 136 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 137 | 138 | /// Insert a given `value` into a sorted array, using the given `compare` 139 | /// callback to determine the order. 140 | #define array_insert_sorted_with(self, compare, value) \ 141 | do { \ 142 | unsigned _index, _exists; \ 143 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 144 | if (!_exists) array_insert(self, _index, value); \ 145 | } while (0) 146 | 147 | /// Insert a given `value` into a sorted array, using integer comparisons of 148 | /// a given struct field (specified with a leading dot) to determine the order. 149 | /// 150 | /// See also `array_search_sorted_by`. 151 | #define array_insert_sorted_by(self, field, value) \ 152 | do { \ 153 | unsigned _index, _exists; \ 154 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 155 | if (!_exists) array_insert(self, _index, value); \ 156 | } while (0) 157 | 158 | // Private 159 | 160 | typedef Array(void) Array; 161 | 162 | /// This is not what you're looking for, see `array_delete`. 163 | static inline void _array__delete(Array *self) { 164 | if (self->contents) { 165 | ts_free(self->contents); 166 | self->contents = NULL; 167 | self->size = 0; 168 | self->capacity = 0; 169 | } 170 | } 171 | 172 | /// This is not what you're looking for, see `array_erase`. 173 | static inline void _array__erase(Array *self, size_t element_size, 174 | uint32_t index) { 175 | assert(index < self->size); 176 | char *contents = (char *)self->contents; 177 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 178 | (self->size - index - 1) * element_size); 179 | self->size--; 180 | } 181 | 182 | /// This is not what you're looking for, see `array_reserve`. 183 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 184 | if (new_capacity > self->capacity) { 185 | if (self->contents) { 186 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 187 | } else { 188 | self->contents = ts_malloc(new_capacity * element_size); 189 | } 190 | self->capacity = new_capacity; 191 | } 192 | } 193 | 194 | /// This is not what you're looking for, see `array_assign`. 195 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 196 | _array__reserve(self, element_size, other->size); 197 | self->size = other->size; 198 | memcpy(self->contents, other->contents, self->size * element_size); 199 | } 200 | 201 | /// This is not what you're looking for, see `array_swap`. 202 | static inline void _array__swap(Array *self, Array *other) { 203 | Array swap = *other; 204 | *other = *self; 205 | *self = swap; 206 | } 207 | 208 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 209 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 210 | uint32_t new_size = self->size + count; 211 | if (new_size > self->capacity) { 212 | uint32_t new_capacity = self->capacity * 2; 213 | if (new_capacity < 8) new_capacity = 8; 214 | if (new_capacity < new_size) new_capacity = new_size; 215 | _array__reserve(self, element_size, new_capacity); 216 | } 217 | } 218 | 219 | /// This is not what you're looking for, see `array_splice`. 220 | static inline void _array__splice(Array *self, size_t element_size, 221 | uint32_t index, uint32_t old_count, 222 | uint32_t new_count, const void *elements) { 223 | uint32_t new_size = self->size + new_count - old_count; 224 | uint32_t old_end = index + old_count; 225 | uint32_t new_end = index + new_count; 226 | assert(old_end <= self->size); 227 | 228 | _array__reserve(self, element_size, new_size); 229 | 230 | char *contents = (char *)self->contents; 231 | if (self->size > old_end) { 232 | memmove( 233 | contents + new_end * element_size, 234 | contents + old_end * element_size, 235 | (self->size - old_end) * element_size 236 | ); 237 | } 238 | if (new_count > 0) { 239 | if (elements) { 240 | memcpy( 241 | (contents + index * element_size), 242 | elements, 243 | new_count * element_size 244 | ); 245 | } else { 246 | memset( 247 | (contents + index * element_size), 248 | 0, 249 | new_count * element_size 250 | ); 251 | } 252 | } 253 | self->size += new_count - old_count; 254 | } 255 | 256 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 257 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 258 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 259 | do { \ 260 | *(_index) = start; \ 261 | *(_exists) = false; \ 262 | uint32_t size = (self)->size - *(_index); \ 263 | if (size == 0) break; \ 264 | int comparison; \ 265 | while (size > 1) { \ 266 | uint32_t half_size = size / 2; \ 267 | uint32_t mid_index = *(_index) + half_size; \ 268 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 269 | if (comparison <= 0) *(_index) = mid_index; \ 270 | size -= half_size; \ 271 | } \ 272 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 273 | if (comparison == 0) *(_exists) = true; \ 274 | else if (comparison < 0) *(_index) += 1; \ 275 | } while (0) 276 | 277 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 278 | /// parameter by reference in order to work with the generic sorting function above. 279 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 280 | 281 | #ifdef _MSC_VER 282 | #pragma warning(pop) 283 | #elif defined(__GNUC__) || defined(__clang__) 284 | #pragma GCC diagnostic pop 285 | #endif 286 | 287 | #ifdef __cplusplus 288 | } 289 | #endif 290 | 291 | #endif // TREE_SITTER_ARRAY_H_ 292 | -------------------------------------------------------------------------------- /schema/core/src/tree_sitter/array.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ARRAY_H_ 2 | #define TREE_SITTER_ARRAY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "./alloc.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _MSC_VER 17 | #pragma warning(push) 18 | #pragma warning(disable : 4101) 19 | #elif defined(__GNUC__) || defined(__clang__) 20 | #pragma GCC diagnostic push 21 | #pragma GCC diagnostic ignored "-Wunused-variable" 22 | #endif 23 | 24 | #define Array(T) \ 25 | struct { \ 26 | T *contents; \ 27 | uint32_t size; \ 28 | uint32_t capacity; \ 29 | } 30 | 31 | /// Initialize an array. 32 | #define array_init(self) \ 33 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 34 | 35 | /// Create an empty array. 36 | #define array_new() \ 37 | { NULL, 0, 0 } 38 | 39 | /// Get a pointer to the element at a given `index` in the array. 40 | #define array_get(self, _index) \ 41 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 42 | 43 | /// Get a pointer to the first element in the array. 44 | #define array_front(self) array_get(self, 0) 45 | 46 | /// Get a pointer to the last element in the array. 47 | #define array_back(self) array_get(self, (self)->size - 1) 48 | 49 | /// Clear the array, setting its size to zero. Note that this does not free any 50 | /// memory allocated for the array's contents. 51 | #define array_clear(self) ((self)->size = 0) 52 | 53 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 54 | /// less than the array's current capacity, this function has no effect. 55 | #define array_reserve(self, new_capacity) \ 56 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 57 | 58 | /// Free any memory allocated for this array. Note that this does not free any 59 | /// memory allocated for the array's contents. 60 | #define array_delete(self) _array__delete((Array *)(self)) 61 | 62 | /// Push a new `element` onto the end of the array. 63 | #define array_push(self, element) \ 64 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 65 | (self)->contents[(self)->size++] = (element)) 66 | 67 | /// Increase the array's size by `count` elements. 68 | /// New elements are zero-initialized. 69 | #define array_grow_by(self, count) \ 70 | do { \ 71 | if ((count) == 0) break; \ 72 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 73 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 74 | (self)->size += (count); \ 75 | } while (0) 76 | 77 | /// Append all elements from one array to the end of another. 78 | #define array_push_all(self, other) \ 79 | array_extend((self), (other)->size, (other)->contents) 80 | 81 | /// Append `count` elements to the end of the array, reading their values from the 82 | /// `contents` pointer. 83 | #define array_extend(self, count, contents) \ 84 | _array__splice( \ 85 | (Array *)(self), array_elem_size(self), (self)->size, \ 86 | 0, count, contents \ 87 | ) 88 | 89 | /// Remove `old_count` elements from the array starting at the given `index`. At 90 | /// the same index, insert `new_count` new elements, reading their values from the 91 | /// `new_contents` pointer. 92 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 93 | _array__splice( \ 94 | (Array *)(self), array_elem_size(self), _index, \ 95 | old_count, new_count, new_contents \ 96 | ) 97 | 98 | /// Insert one `element` into the array at the given `index`. 99 | #define array_insert(self, _index, element) \ 100 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 101 | 102 | /// Remove one element from the array at the given `index`. 103 | #define array_erase(self, _index) \ 104 | _array__erase((Array *)(self), array_elem_size(self), _index) 105 | 106 | /// Pop the last element off the array, returning the element by value. 107 | #define array_pop(self) ((self)->contents[--(self)->size]) 108 | 109 | /// Assign the contents of one array to another, reallocating if necessary. 110 | #define array_assign(self, other) \ 111 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 112 | 113 | /// Swap one array with another 114 | #define array_swap(self, other) \ 115 | _array__swap((Array *)(self), (Array *)(other)) 116 | 117 | /// Get the size of the array contents 118 | #define array_elem_size(self) (sizeof *(self)->contents) 119 | 120 | /// Search a sorted array for a given `needle` value, using the given `compare` 121 | /// callback to determine the order. 122 | /// 123 | /// If an existing element is found to be equal to `needle`, then the `index` 124 | /// out-parameter is set to the existing value's index, and the `exists` 125 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 126 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 127 | /// is set to false. 128 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 129 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 130 | 131 | /// Search a sorted array for a given `needle` value, using integer comparisons 132 | /// of a given struct field (specified with a leading dot) to determine the order. 133 | /// 134 | /// See also `array_search_sorted_with`. 135 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 136 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 137 | 138 | /// Insert a given `value` into a sorted array, using the given `compare` 139 | /// callback to determine the order. 140 | #define array_insert_sorted_with(self, compare, value) \ 141 | do { \ 142 | unsigned _index, _exists; \ 143 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 144 | if (!_exists) array_insert(self, _index, value); \ 145 | } while (0) 146 | 147 | /// Insert a given `value` into a sorted array, using integer comparisons of 148 | /// a given struct field (specified with a leading dot) to determine the order. 149 | /// 150 | /// See also `array_search_sorted_by`. 151 | #define array_insert_sorted_by(self, field, value) \ 152 | do { \ 153 | unsigned _index, _exists; \ 154 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 155 | if (!_exists) array_insert(self, _index, value); \ 156 | } while (0) 157 | 158 | // Private 159 | 160 | typedef Array(void) Array; 161 | 162 | /// This is not what you're looking for, see `array_delete`. 163 | static inline void _array__delete(Array *self) { 164 | if (self->contents) { 165 | ts_free(self->contents); 166 | self->contents = NULL; 167 | self->size = 0; 168 | self->capacity = 0; 169 | } 170 | } 171 | 172 | /// This is not what you're looking for, see `array_erase`. 173 | static inline void _array__erase(Array *self, size_t element_size, 174 | uint32_t index) { 175 | assert(index < self->size); 176 | char *contents = (char *)self->contents; 177 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 178 | (self->size - index - 1) * element_size); 179 | self->size--; 180 | } 181 | 182 | /// This is not what you're looking for, see `array_reserve`. 183 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 184 | if (new_capacity > self->capacity) { 185 | if (self->contents) { 186 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 187 | } else { 188 | self->contents = ts_malloc(new_capacity * element_size); 189 | } 190 | self->capacity = new_capacity; 191 | } 192 | } 193 | 194 | /// This is not what you're looking for, see `array_assign`. 195 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 196 | _array__reserve(self, element_size, other->size); 197 | self->size = other->size; 198 | memcpy(self->contents, other->contents, self->size * element_size); 199 | } 200 | 201 | /// This is not what you're looking for, see `array_swap`. 202 | static inline void _array__swap(Array *self, Array *other) { 203 | Array swap = *other; 204 | *other = *self; 205 | *self = swap; 206 | } 207 | 208 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 209 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 210 | uint32_t new_size = self->size + count; 211 | if (new_size > self->capacity) { 212 | uint32_t new_capacity = self->capacity * 2; 213 | if (new_capacity < 8) new_capacity = 8; 214 | if (new_capacity < new_size) new_capacity = new_size; 215 | _array__reserve(self, element_size, new_capacity); 216 | } 217 | } 218 | 219 | /// This is not what you're looking for, see `array_splice`. 220 | static inline void _array__splice(Array *self, size_t element_size, 221 | uint32_t index, uint32_t old_count, 222 | uint32_t new_count, const void *elements) { 223 | uint32_t new_size = self->size + new_count - old_count; 224 | uint32_t old_end = index + old_count; 225 | uint32_t new_end = index + new_count; 226 | assert(old_end <= self->size); 227 | 228 | _array__reserve(self, element_size, new_size); 229 | 230 | char *contents = (char *)self->contents; 231 | if (self->size > old_end) { 232 | memmove( 233 | contents + new_end * element_size, 234 | contents + old_end * element_size, 235 | (self->size - old_end) * element_size 236 | ); 237 | } 238 | if (new_count > 0) { 239 | if (elements) { 240 | memcpy( 241 | (contents + index * element_size), 242 | elements, 243 | new_count * element_size 244 | ); 245 | } else { 246 | memset( 247 | (contents + index * element_size), 248 | 0, 249 | new_count * element_size 250 | ); 251 | } 252 | } 253 | self->size += new_count - old_count; 254 | } 255 | 256 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 257 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 258 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 259 | do { \ 260 | *(_index) = start; \ 261 | *(_exists) = false; \ 262 | uint32_t size = (self)->size - *(_index); \ 263 | if (size == 0) break; \ 264 | int comparison; \ 265 | while (size > 1) { \ 266 | uint32_t half_size = size / 2; \ 267 | uint32_t mid_index = *(_index) + half_size; \ 268 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 269 | if (comparison <= 0) *(_index) = mid_index; \ 270 | size -= half_size; \ 271 | } \ 272 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 273 | if (comparison == 0) *(_exists) = true; \ 274 | else if (comparison < 0) *(_index) += 1; \ 275 | } while (0) 276 | 277 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 278 | /// parameter by reference in order to work with the generic sorting function above. 279 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 280 | 281 | #ifdef _MSC_VER 282 | #pragma warning(pop) 283 | #elif defined(__GNUC__) || defined(__clang__) 284 | #pragma GCC diagnostic pop 285 | #endif 286 | 287 | #ifdef __cplusplus 288 | } 289 | #endif 290 | 291 | #endif // TREE_SITTER_ARRAY_H_ 292 | -------------------------------------------------------------------------------- /schema/json/src/tree_sitter/array.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ARRAY_H_ 2 | #define TREE_SITTER_ARRAY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "./alloc.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _MSC_VER 17 | #pragma warning(push) 18 | #pragma warning(disable : 4101) 19 | #elif defined(__GNUC__) || defined(__clang__) 20 | #pragma GCC diagnostic push 21 | #pragma GCC diagnostic ignored "-Wunused-variable" 22 | #endif 23 | 24 | #define Array(T) \ 25 | struct { \ 26 | T *contents; \ 27 | uint32_t size; \ 28 | uint32_t capacity; \ 29 | } 30 | 31 | /// Initialize an array. 32 | #define array_init(self) \ 33 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 34 | 35 | /// Create an empty array. 36 | #define array_new() \ 37 | { NULL, 0, 0 } 38 | 39 | /// Get a pointer to the element at a given `index` in the array. 40 | #define array_get(self, _index) \ 41 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 42 | 43 | /// Get a pointer to the first element in the array. 44 | #define array_front(self) array_get(self, 0) 45 | 46 | /// Get a pointer to the last element in the array. 47 | #define array_back(self) array_get(self, (self)->size - 1) 48 | 49 | /// Clear the array, setting its size to zero. Note that this does not free any 50 | /// memory allocated for the array's contents. 51 | #define array_clear(self) ((self)->size = 0) 52 | 53 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 54 | /// less than the array's current capacity, this function has no effect. 55 | #define array_reserve(self, new_capacity) \ 56 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 57 | 58 | /// Free any memory allocated for this array. Note that this does not free any 59 | /// memory allocated for the array's contents. 60 | #define array_delete(self) _array__delete((Array *)(self)) 61 | 62 | /// Push a new `element` onto the end of the array. 63 | #define array_push(self, element) \ 64 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 65 | (self)->contents[(self)->size++] = (element)) 66 | 67 | /// Increase the array's size by `count` elements. 68 | /// New elements are zero-initialized. 69 | #define array_grow_by(self, count) \ 70 | do { \ 71 | if ((count) == 0) break; \ 72 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 73 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 74 | (self)->size += (count); \ 75 | } while (0) 76 | 77 | /// Append all elements from one array to the end of another. 78 | #define array_push_all(self, other) \ 79 | array_extend((self), (other)->size, (other)->contents) 80 | 81 | /// Append `count` elements to the end of the array, reading their values from the 82 | /// `contents` pointer. 83 | #define array_extend(self, count, contents) \ 84 | _array__splice( \ 85 | (Array *)(self), array_elem_size(self), (self)->size, \ 86 | 0, count, contents \ 87 | ) 88 | 89 | /// Remove `old_count` elements from the array starting at the given `index`. At 90 | /// the same index, insert `new_count` new elements, reading their values from the 91 | /// `new_contents` pointer. 92 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 93 | _array__splice( \ 94 | (Array *)(self), array_elem_size(self), _index, \ 95 | old_count, new_count, new_contents \ 96 | ) 97 | 98 | /// Insert one `element` into the array at the given `index`. 99 | #define array_insert(self, _index, element) \ 100 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 101 | 102 | /// Remove one element from the array at the given `index`. 103 | #define array_erase(self, _index) \ 104 | _array__erase((Array *)(self), array_elem_size(self), _index) 105 | 106 | /// Pop the last element off the array, returning the element by value. 107 | #define array_pop(self) ((self)->contents[--(self)->size]) 108 | 109 | /// Assign the contents of one array to another, reallocating if necessary. 110 | #define array_assign(self, other) \ 111 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 112 | 113 | /// Swap one array with another 114 | #define array_swap(self, other) \ 115 | _array__swap((Array *)(self), (Array *)(other)) 116 | 117 | /// Get the size of the array contents 118 | #define array_elem_size(self) (sizeof *(self)->contents) 119 | 120 | /// Search a sorted array for a given `needle` value, using the given `compare` 121 | /// callback to determine the order. 122 | /// 123 | /// If an existing element is found to be equal to `needle`, then the `index` 124 | /// out-parameter is set to the existing value's index, and the `exists` 125 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 126 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 127 | /// is set to false. 128 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 129 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 130 | 131 | /// Search a sorted array for a given `needle` value, using integer comparisons 132 | /// of a given struct field (specified with a leading dot) to determine the order. 133 | /// 134 | /// See also `array_search_sorted_with`. 135 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 136 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 137 | 138 | /// Insert a given `value` into a sorted array, using the given `compare` 139 | /// callback to determine the order. 140 | #define array_insert_sorted_with(self, compare, value) \ 141 | do { \ 142 | unsigned _index, _exists; \ 143 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 144 | if (!_exists) array_insert(self, _index, value); \ 145 | } while (0) 146 | 147 | /// Insert a given `value` into a sorted array, using integer comparisons of 148 | /// a given struct field (specified with a leading dot) to determine the order. 149 | /// 150 | /// See also `array_search_sorted_by`. 151 | #define array_insert_sorted_by(self, field, value) \ 152 | do { \ 153 | unsigned _index, _exists; \ 154 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 155 | if (!_exists) array_insert(self, _index, value); \ 156 | } while (0) 157 | 158 | // Private 159 | 160 | typedef Array(void) Array; 161 | 162 | /// This is not what you're looking for, see `array_delete`. 163 | static inline void _array__delete(Array *self) { 164 | if (self->contents) { 165 | ts_free(self->contents); 166 | self->contents = NULL; 167 | self->size = 0; 168 | self->capacity = 0; 169 | } 170 | } 171 | 172 | /// This is not what you're looking for, see `array_erase`. 173 | static inline void _array__erase(Array *self, size_t element_size, 174 | uint32_t index) { 175 | assert(index < self->size); 176 | char *contents = (char *)self->contents; 177 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 178 | (self->size - index - 1) * element_size); 179 | self->size--; 180 | } 181 | 182 | /// This is not what you're looking for, see `array_reserve`. 183 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 184 | if (new_capacity > self->capacity) { 185 | if (self->contents) { 186 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 187 | } else { 188 | self->contents = ts_malloc(new_capacity * element_size); 189 | } 190 | self->capacity = new_capacity; 191 | } 192 | } 193 | 194 | /// This is not what you're looking for, see `array_assign`. 195 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 196 | _array__reserve(self, element_size, other->size); 197 | self->size = other->size; 198 | memcpy(self->contents, other->contents, self->size * element_size); 199 | } 200 | 201 | /// This is not what you're looking for, see `array_swap`. 202 | static inline void _array__swap(Array *self, Array *other) { 203 | Array swap = *other; 204 | *other = *self; 205 | *self = swap; 206 | } 207 | 208 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 209 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 210 | uint32_t new_size = self->size + count; 211 | if (new_size > self->capacity) { 212 | uint32_t new_capacity = self->capacity * 2; 213 | if (new_capacity < 8) new_capacity = 8; 214 | if (new_capacity < new_size) new_capacity = new_size; 215 | _array__reserve(self, element_size, new_capacity); 216 | } 217 | } 218 | 219 | /// This is not what you're looking for, see `array_splice`. 220 | static inline void _array__splice(Array *self, size_t element_size, 221 | uint32_t index, uint32_t old_count, 222 | uint32_t new_count, const void *elements) { 223 | uint32_t new_size = self->size + new_count - old_count; 224 | uint32_t old_end = index + old_count; 225 | uint32_t new_end = index + new_count; 226 | assert(old_end <= self->size); 227 | 228 | _array__reserve(self, element_size, new_size); 229 | 230 | char *contents = (char *)self->contents; 231 | if (self->size > old_end) { 232 | memmove( 233 | contents + new_end * element_size, 234 | contents + old_end * element_size, 235 | (self->size - old_end) * element_size 236 | ); 237 | } 238 | if (new_count > 0) { 239 | if (elements) { 240 | memcpy( 241 | (contents + index * element_size), 242 | elements, 243 | new_count * element_size 244 | ); 245 | } else { 246 | memset( 247 | (contents + index * element_size), 248 | 0, 249 | new_count * element_size 250 | ); 251 | } 252 | } 253 | self->size += new_count - old_count; 254 | } 255 | 256 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 257 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 258 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 259 | do { \ 260 | *(_index) = start; \ 261 | *(_exists) = false; \ 262 | uint32_t size = (self)->size - *(_index); \ 263 | if (size == 0) break; \ 264 | int comparison; \ 265 | while (size > 1) { \ 266 | uint32_t half_size = size / 2; \ 267 | uint32_t mid_index = *(_index) + half_size; \ 268 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 269 | if (comparison <= 0) *(_index) = mid_index; \ 270 | size -= half_size; \ 271 | } \ 272 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 273 | if (comparison == 0) *(_exists) = true; \ 274 | else if (comparison < 0) *(_index) += 1; \ 275 | } while (0) 276 | 277 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 278 | /// parameter by reference in order to work with the generic sorting function above. 279 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 280 | 281 | #ifdef _MSC_VER 282 | #pragma warning(pop) 283 | #elif defined(__GNUC__) || defined(__clang__) 284 | #pragma GCC diagnostic pop 285 | #endif 286 | 287 | #ifdef __cplusplus 288 | } 289 | #endif 290 | 291 | #endif // TREE_SITTER_ARRAY_H_ 292 | -------------------------------------------------------------------------------- /schema/legacy/src/tree_sitter/array.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ARRAY_H_ 2 | #define TREE_SITTER_ARRAY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "./alloc.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _MSC_VER 17 | #pragma warning(push) 18 | #pragma warning(disable : 4101) 19 | #elif defined(__GNUC__) || defined(__clang__) 20 | #pragma GCC diagnostic push 21 | #pragma GCC diagnostic ignored "-Wunused-variable" 22 | #endif 23 | 24 | #define Array(T) \ 25 | struct { \ 26 | T *contents; \ 27 | uint32_t size; \ 28 | uint32_t capacity; \ 29 | } 30 | 31 | /// Initialize an array. 32 | #define array_init(self) \ 33 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 34 | 35 | /// Create an empty array. 36 | #define array_new() \ 37 | { NULL, 0, 0 } 38 | 39 | /// Get a pointer to the element at a given `index` in the array. 40 | #define array_get(self, _index) \ 41 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 42 | 43 | /// Get a pointer to the first element in the array. 44 | #define array_front(self) array_get(self, 0) 45 | 46 | /// Get a pointer to the last element in the array. 47 | #define array_back(self) array_get(self, (self)->size - 1) 48 | 49 | /// Clear the array, setting its size to zero. Note that this does not free any 50 | /// memory allocated for the array's contents. 51 | #define array_clear(self) ((self)->size = 0) 52 | 53 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 54 | /// less than the array's current capacity, this function has no effect. 55 | #define array_reserve(self, new_capacity) \ 56 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 57 | 58 | /// Free any memory allocated for this array. Note that this does not free any 59 | /// memory allocated for the array's contents. 60 | #define array_delete(self) _array__delete((Array *)(self)) 61 | 62 | /// Push a new `element` onto the end of the array. 63 | #define array_push(self, element) \ 64 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 65 | (self)->contents[(self)->size++] = (element)) 66 | 67 | /// Increase the array's size by `count` elements. 68 | /// New elements are zero-initialized. 69 | #define array_grow_by(self, count) \ 70 | do { \ 71 | if ((count) == 0) break; \ 72 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 73 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 74 | (self)->size += (count); \ 75 | } while (0) 76 | 77 | /// Append all elements from one array to the end of another. 78 | #define array_push_all(self, other) \ 79 | array_extend((self), (other)->size, (other)->contents) 80 | 81 | /// Append `count` elements to the end of the array, reading their values from the 82 | /// `contents` pointer. 83 | #define array_extend(self, count, contents) \ 84 | _array__splice( \ 85 | (Array *)(self), array_elem_size(self), (self)->size, \ 86 | 0, count, contents \ 87 | ) 88 | 89 | /// Remove `old_count` elements from the array starting at the given `index`. At 90 | /// the same index, insert `new_count` new elements, reading their values from the 91 | /// `new_contents` pointer. 92 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 93 | _array__splice( \ 94 | (Array *)(self), array_elem_size(self), _index, \ 95 | old_count, new_count, new_contents \ 96 | ) 97 | 98 | /// Insert one `element` into the array at the given `index`. 99 | #define array_insert(self, _index, element) \ 100 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 101 | 102 | /// Remove one element from the array at the given `index`. 103 | #define array_erase(self, _index) \ 104 | _array__erase((Array *)(self), array_elem_size(self), _index) 105 | 106 | /// Pop the last element off the array, returning the element by value. 107 | #define array_pop(self) ((self)->contents[--(self)->size]) 108 | 109 | /// Assign the contents of one array to another, reallocating if necessary. 110 | #define array_assign(self, other) \ 111 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 112 | 113 | /// Swap one array with another 114 | #define array_swap(self, other) \ 115 | _array__swap((Array *)(self), (Array *)(other)) 116 | 117 | /// Get the size of the array contents 118 | #define array_elem_size(self) (sizeof *(self)->contents) 119 | 120 | /// Search a sorted array for a given `needle` value, using the given `compare` 121 | /// callback to determine the order. 122 | /// 123 | /// If an existing element is found to be equal to `needle`, then the `index` 124 | /// out-parameter is set to the existing value's index, and the `exists` 125 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 126 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 127 | /// is set to false. 128 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 129 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 130 | 131 | /// Search a sorted array for a given `needle` value, using integer comparisons 132 | /// of a given struct field (specified with a leading dot) to determine the order. 133 | /// 134 | /// See also `array_search_sorted_with`. 135 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 136 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 137 | 138 | /// Insert a given `value` into a sorted array, using the given `compare` 139 | /// callback to determine the order. 140 | #define array_insert_sorted_with(self, compare, value) \ 141 | do { \ 142 | unsigned _index, _exists; \ 143 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 144 | if (!_exists) array_insert(self, _index, value); \ 145 | } while (0) 146 | 147 | /// Insert a given `value` into a sorted array, using integer comparisons of 148 | /// a given struct field (specified with a leading dot) to determine the order. 149 | /// 150 | /// See also `array_search_sorted_by`. 151 | #define array_insert_sorted_by(self, field, value) \ 152 | do { \ 153 | unsigned _index, _exists; \ 154 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 155 | if (!_exists) array_insert(self, _index, value); \ 156 | } while (0) 157 | 158 | // Private 159 | 160 | typedef Array(void) Array; 161 | 162 | /// This is not what you're looking for, see `array_delete`. 163 | static inline void _array__delete(Array *self) { 164 | if (self->contents) { 165 | ts_free(self->contents); 166 | self->contents = NULL; 167 | self->size = 0; 168 | self->capacity = 0; 169 | } 170 | } 171 | 172 | /// This is not what you're looking for, see `array_erase`. 173 | static inline void _array__erase(Array *self, size_t element_size, 174 | uint32_t index) { 175 | assert(index < self->size); 176 | char *contents = (char *)self->contents; 177 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 178 | (self->size - index - 1) * element_size); 179 | self->size--; 180 | } 181 | 182 | /// This is not what you're looking for, see `array_reserve`. 183 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 184 | if (new_capacity > self->capacity) { 185 | if (self->contents) { 186 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 187 | } else { 188 | self->contents = ts_malloc(new_capacity * element_size); 189 | } 190 | self->capacity = new_capacity; 191 | } 192 | } 193 | 194 | /// This is not what you're looking for, see `array_assign`. 195 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 196 | _array__reserve(self, element_size, other->size); 197 | self->size = other->size; 198 | memcpy(self->contents, other->contents, self->size * element_size); 199 | } 200 | 201 | /// This is not what you're looking for, see `array_swap`. 202 | static inline void _array__swap(Array *self, Array *other) { 203 | Array swap = *other; 204 | *other = *self; 205 | *self = swap; 206 | } 207 | 208 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 209 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 210 | uint32_t new_size = self->size + count; 211 | if (new_size > self->capacity) { 212 | uint32_t new_capacity = self->capacity * 2; 213 | if (new_capacity < 8) new_capacity = 8; 214 | if (new_capacity < new_size) new_capacity = new_size; 215 | _array__reserve(self, element_size, new_capacity); 216 | } 217 | } 218 | 219 | /// This is not what you're looking for, see `array_splice`. 220 | static inline void _array__splice(Array *self, size_t element_size, 221 | uint32_t index, uint32_t old_count, 222 | uint32_t new_count, const void *elements) { 223 | uint32_t new_size = self->size + new_count - old_count; 224 | uint32_t old_end = index + old_count; 225 | uint32_t new_end = index + new_count; 226 | assert(old_end <= self->size); 227 | 228 | _array__reserve(self, element_size, new_size); 229 | 230 | char *contents = (char *)self->contents; 231 | if (self->size > old_end) { 232 | memmove( 233 | contents + new_end * element_size, 234 | contents + old_end * element_size, 235 | (self->size - old_end) * element_size 236 | ); 237 | } 238 | if (new_count > 0) { 239 | if (elements) { 240 | memcpy( 241 | (contents + index * element_size), 242 | elements, 243 | new_count * element_size 244 | ); 245 | } else { 246 | memset( 247 | (contents + index * element_size), 248 | 0, 249 | new_count * element_size 250 | ); 251 | } 252 | } 253 | self->size += new_count - old_count; 254 | } 255 | 256 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 257 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 258 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 259 | do { \ 260 | *(_index) = start; \ 261 | *(_exists) = false; \ 262 | uint32_t size = (self)->size - *(_index); \ 263 | if (size == 0) break; \ 264 | int comparison; \ 265 | while (size > 1) { \ 266 | uint32_t half_size = size / 2; \ 267 | uint32_t mid_index = *(_index) + half_size; \ 268 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 269 | if (comparison <= 0) *(_index) = mid_index; \ 270 | size -= half_size; \ 271 | } \ 272 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 273 | if (comparison == 0) *(_exists) = true; \ 274 | else if (comparison < 0) *(_index) += 1; \ 275 | } while (0) 276 | 277 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 278 | /// parameter by reference in order to work with the generic sorting function above. 279 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 280 | 281 | #ifdef _MSC_VER 282 | #pragma warning(pop) 283 | #elif defined(__GNUC__) || defined(__clang__) 284 | #pragma GCC diagnostic pop 285 | #endif 286 | 287 | #ifdef __cplusplus 288 | } 289 | #endif 290 | 291 | #endif // TREE_SITTER_ARRAY_H_ 292 | -------------------------------------------------------------------------------- /src/node-types.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "alias", 4 | "named": true, 5 | "fields": {}, 6 | "children": { 7 | "multiple": false, 8 | "required": true, 9 | "types": [ 10 | { 11 | "type": "alias_name", 12 | "named": true 13 | } 14 | ] 15 | } 16 | }, 17 | { 18 | "type": "anchor", 19 | "named": true, 20 | "fields": {}, 21 | "children": { 22 | "multiple": false, 23 | "required": true, 24 | "types": [ 25 | { 26 | "type": "anchor_name", 27 | "named": true 28 | } 29 | ] 30 | } 31 | }, 32 | { 33 | "type": "block_mapping", 34 | "named": true, 35 | "fields": {}, 36 | "children": { 37 | "multiple": true, 38 | "required": true, 39 | "types": [ 40 | { 41 | "type": "block_mapping_pair", 42 | "named": true 43 | } 44 | ] 45 | } 46 | }, 47 | { 48 | "type": "block_mapping_pair", 49 | "named": true, 50 | "fields": { 51 | "key": { 52 | "multiple": false, 53 | "required": false, 54 | "types": [ 55 | { 56 | "type": "block_node", 57 | "named": true 58 | }, 59 | { 60 | "type": "flow_node", 61 | "named": true 62 | } 63 | ] 64 | }, 65 | "value": { 66 | "multiple": false, 67 | "required": false, 68 | "types": [ 69 | { 70 | "type": "block_node", 71 | "named": true 72 | }, 73 | { 74 | "type": "flow_node", 75 | "named": true 76 | } 77 | ] 78 | } 79 | } 80 | }, 81 | { 82 | "type": "block_node", 83 | "named": true, 84 | "fields": {}, 85 | "children": { 86 | "multiple": true, 87 | "required": true, 88 | "types": [ 89 | { 90 | "type": "anchor", 91 | "named": true 92 | }, 93 | { 94 | "type": "block_mapping", 95 | "named": true 96 | }, 97 | { 98 | "type": "block_scalar", 99 | "named": true 100 | }, 101 | { 102 | "type": "block_sequence", 103 | "named": true 104 | }, 105 | { 106 | "type": "tag", 107 | "named": true 108 | } 109 | ] 110 | } 111 | }, 112 | { 113 | "type": "block_scalar", 114 | "named": true, 115 | "fields": {} 116 | }, 117 | { 118 | "type": "block_sequence", 119 | "named": true, 120 | "fields": {}, 121 | "children": { 122 | "multiple": true, 123 | "required": true, 124 | "types": [ 125 | { 126 | "type": "block_sequence_item", 127 | "named": true 128 | } 129 | ] 130 | } 131 | }, 132 | { 133 | "type": "block_sequence_item", 134 | "named": true, 135 | "fields": {}, 136 | "children": { 137 | "multiple": false, 138 | "required": false, 139 | "types": [ 140 | { 141 | "type": "block_node", 142 | "named": true 143 | }, 144 | { 145 | "type": "flow_node", 146 | "named": true 147 | } 148 | ] 149 | } 150 | }, 151 | { 152 | "type": "document", 153 | "named": true, 154 | "fields": {}, 155 | "children": { 156 | "multiple": true, 157 | "required": false, 158 | "types": [ 159 | { 160 | "type": "block_node", 161 | "named": true 162 | }, 163 | { 164 | "type": "flow_node", 165 | "named": true 166 | }, 167 | { 168 | "type": "reserved_directive", 169 | "named": true 170 | }, 171 | { 172 | "type": "tag_directive", 173 | "named": true 174 | }, 175 | { 176 | "type": "yaml_directive", 177 | "named": true 178 | } 179 | ] 180 | } 181 | }, 182 | { 183 | "type": "double_quote_scalar", 184 | "named": true, 185 | "fields": {}, 186 | "children": { 187 | "multiple": true, 188 | "required": false, 189 | "types": [ 190 | { 191 | "type": "escape_sequence", 192 | "named": true 193 | } 194 | ] 195 | } 196 | }, 197 | { 198 | "type": "flow_mapping", 199 | "named": true, 200 | "fields": {}, 201 | "children": { 202 | "multiple": true, 203 | "required": false, 204 | "types": [ 205 | { 206 | "type": "flow_node", 207 | "named": true 208 | }, 209 | { 210 | "type": "flow_pair", 211 | "named": true 212 | } 213 | ] 214 | } 215 | }, 216 | { 217 | "type": "flow_node", 218 | "named": true, 219 | "fields": {}, 220 | "children": { 221 | "multiple": true, 222 | "required": true, 223 | "types": [ 224 | { 225 | "type": "alias", 226 | "named": true 227 | }, 228 | { 229 | "type": "anchor", 230 | "named": true 231 | }, 232 | { 233 | "type": "double_quote_scalar", 234 | "named": true 235 | }, 236 | { 237 | "type": "flow_mapping", 238 | "named": true 239 | }, 240 | { 241 | "type": "flow_sequence", 242 | "named": true 243 | }, 244 | { 245 | "type": "plain_scalar", 246 | "named": true 247 | }, 248 | { 249 | "type": "single_quote_scalar", 250 | "named": true 251 | }, 252 | { 253 | "type": "tag", 254 | "named": true 255 | } 256 | ] 257 | } 258 | }, 259 | { 260 | "type": "flow_pair", 261 | "named": true, 262 | "fields": { 263 | "key": { 264 | "multiple": false, 265 | "required": false, 266 | "types": [ 267 | { 268 | "type": "flow_node", 269 | "named": true 270 | } 271 | ] 272 | }, 273 | "value": { 274 | "multiple": false, 275 | "required": false, 276 | "types": [ 277 | { 278 | "type": "flow_node", 279 | "named": true 280 | } 281 | ] 282 | } 283 | } 284 | }, 285 | { 286 | "type": "flow_sequence", 287 | "named": true, 288 | "fields": {}, 289 | "children": { 290 | "multiple": true, 291 | "required": false, 292 | "types": [ 293 | { 294 | "type": "flow_node", 295 | "named": true 296 | }, 297 | { 298 | "type": "flow_pair", 299 | "named": true 300 | } 301 | ] 302 | } 303 | }, 304 | { 305 | "type": "plain_scalar", 306 | "named": true, 307 | "fields": {}, 308 | "children": { 309 | "multiple": false, 310 | "required": true, 311 | "types": [ 312 | { 313 | "type": "boolean_scalar", 314 | "named": true 315 | }, 316 | { 317 | "type": "float_scalar", 318 | "named": true 319 | }, 320 | { 321 | "type": "integer_scalar", 322 | "named": true 323 | }, 324 | { 325 | "type": "null_scalar", 326 | "named": true 327 | }, 328 | { 329 | "type": "string_scalar", 330 | "named": true 331 | }, 332 | { 333 | "type": "timestamp_scalar", 334 | "named": true 335 | } 336 | ] 337 | } 338 | }, 339 | { 340 | "type": "reserved_directive", 341 | "named": true, 342 | "fields": {}, 343 | "children": { 344 | "multiple": true, 345 | "required": true, 346 | "types": [ 347 | { 348 | "type": "directive_name", 349 | "named": true 350 | }, 351 | { 352 | "type": "directive_parameter", 353 | "named": true 354 | } 355 | ] 356 | } 357 | }, 358 | { 359 | "type": "single_quote_scalar", 360 | "named": true, 361 | "fields": {}, 362 | "children": { 363 | "multiple": true, 364 | "required": false, 365 | "types": [ 366 | { 367 | "type": "escape_sequence", 368 | "named": true 369 | } 370 | ] 371 | } 372 | }, 373 | { 374 | "type": "stream", 375 | "named": true, 376 | "root": true, 377 | "fields": {}, 378 | "children": { 379 | "multiple": true, 380 | "required": false, 381 | "types": [ 382 | { 383 | "type": "document", 384 | "named": true 385 | } 386 | ] 387 | } 388 | }, 389 | { 390 | "type": "tag_directive", 391 | "named": true, 392 | "fields": {}, 393 | "children": { 394 | "multiple": true, 395 | "required": true, 396 | "types": [ 397 | { 398 | "type": "tag_handle", 399 | "named": true 400 | }, 401 | { 402 | "type": "tag_prefix", 403 | "named": true 404 | } 405 | ] 406 | } 407 | }, 408 | { 409 | "type": "yaml_directive", 410 | "named": true, 411 | "fields": {}, 412 | "children": { 413 | "multiple": false, 414 | "required": true, 415 | "types": [ 416 | { 417 | "type": "yaml_version", 418 | "named": true 419 | } 420 | ] 421 | } 422 | }, 423 | { 424 | "type": "\"", 425 | "named": false 426 | }, 427 | { 428 | "type": "&", 429 | "named": false 430 | }, 431 | { 432 | "type": "'", 433 | "named": false 434 | }, 435 | { 436 | "type": "*", 437 | "named": false 438 | }, 439 | { 440 | "type": ",", 441 | "named": false 442 | }, 443 | { 444 | "type": "-", 445 | "named": false 446 | }, 447 | { 448 | "type": "---", 449 | "named": false 450 | }, 451 | { 452 | "type": "...", 453 | "named": false 454 | }, 455 | { 456 | "type": ":", 457 | "named": false 458 | }, 459 | { 460 | "type": ">", 461 | "named": false 462 | }, 463 | { 464 | "type": "?", 465 | "named": false 466 | }, 467 | { 468 | "type": "[", 469 | "named": false 470 | }, 471 | { 472 | "type": "]", 473 | "named": false 474 | }, 475 | { 476 | "type": "alias_name", 477 | "named": true 478 | }, 479 | { 480 | "type": "anchor_name", 481 | "named": true 482 | }, 483 | { 484 | "type": "boolean_scalar", 485 | "named": true 486 | }, 487 | { 488 | "type": "comment", 489 | "named": true, 490 | "extra": true 491 | }, 492 | { 493 | "type": "directive_name", 494 | "named": true 495 | }, 496 | { 497 | "type": "directive_parameter", 498 | "named": true 499 | }, 500 | { 501 | "type": "escape_sequence", 502 | "named": true 503 | }, 504 | { 505 | "type": "float_scalar", 506 | "named": true 507 | }, 508 | { 509 | "type": "integer_scalar", 510 | "named": true 511 | }, 512 | { 513 | "type": "null_scalar", 514 | "named": true 515 | }, 516 | { 517 | "type": "string_scalar", 518 | "named": true 519 | }, 520 | { 521 | "type": "tag", 522 | "named": true 523 | }, 524 | { 525 | "type": "tag_handle", 526 | "named": true 527 | }, 528 | { 529 | "type": "tag_prefix", 530 | "named": true 531 | }, 532 | { 533 | "type": "timestamp_scalar", 534 | "named": true 535 | }, 536 | { 537 | "type": "yaml_version", 538 | "named": true 539 | }, 540 | { 541 | "type": "{", 542 | "named": false 543 | }, 544 | { 545 | "type": "|", 546 | "named": false 547 | }, 548 | { 549 | "type": "}", 550 | "named": false 551 | } 552 | ] --------------------------------------------------------------------------------