├── .envrc ├── bindings ├── python │ ├── tree_sitter_powershell │ │ ├── py.typed │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── __init__.py │ └── tests │ │ └── test_binding.py ├── node │ ├── binding_test.js │ ├── index.js │ ├── index.d.ts │ └── binding.cc ├── c │ ├── tree_sitter │ │ └── tree-sitter-powershell.h │ └── tree-sitter-powershell.pc.in ├── swift │ ├── TreeSitterPowershell │ │ └── powershell.h │ └── TreeSitterPowershellTests │ │ └── TreeSitterPowershellTests.swift ├── go │ ├── binding.go │ └── binding_test.go └── rust │ ├── build.rs │ └── lib.rs ├── eslint.config.mjs ├── go.mod ├── README.md ├── .gitattributes ├── .zed └── settings.json ├── .github └── workflows │ └── lint.yml ├── .editorconfig ├── .gitignore ├── tree-sitter.json ├── pyproject.toml ├── Cargo.toml ├── binding.gyp ├── LICENSE ├── src ├── tree_sitter │ ├── alloc.h │ ├── parser.h │ └── array.h └── scanner.c ├── test └── corpus │ ├── enum.txt │ ├── pipeline_chains.txt │ ├── comments.txt │ ├── classes.txt │ ├── number.txt │ ├── type.txt │ ├── obfuscated.txt │ ├── strings.txt │ ├── commands.txt │ ├── operators.txt │ ├── variables.txt │ └── functions.txt ├── Package.swift ├── package.json ├── flake.nix ├── flake.lock ├── setup.py ├── queries └── highlights.scm ├── CMakeLists.txt ├── Makefile └── Cargo.lock /.envrc: -------------------------------------------------------------------------------- 1 | use flake path:. 2 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_powershell/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import treesitter from "eslint-config-treesitter"; 2 | 3 | export default [...treesitter]; 4 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/airbus-cert/tree-sitter-powershell 2 | 3 | go 1.22 4 | 5 | require github.com/tree-sitter/go-tree-sitter v0.24.0 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-powershell 2 | 3 | Powershell grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter) 4 | 5 | ## References 6 | 7 | * [Powershell 7.3](https://learn.microsoft.com/en-us/powershell/scripting/lang-spec/chapter-15?view=powershell-7.3) -------------------------------------------------------------------------------- /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/python/tree_sitter_powershell/__init__.pyi: -------------------------------------------------------------------------------- 1 | from typing import Final 2 | 3 | # NOTE: uncomment these to include any queries that this grammar contains: 4 | 5 | # HIGHLIGHTS_QUERY: Final[str] 6 | # INJECTIONS_QUERY: Final[str] 7 | # LOCALS_QUERY: Final[str] 8 | # TAGS_QUERY: Final[str] 9 | 10 | def language() -> object: ... 11 | -------------------------------------------------------------------------------- /bindings/c/tree_sitter/tree-sitter-powershell.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_POWERSHELL_H_ 2 | #define TREE_SITTER_POWERSHELL_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_powershell(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_POWERSHELL_H_ 17 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterPowershell/powershell.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_POWERSHELL_H_ 2 | #define TREE_SITTER_POWERSHELL_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_powershell(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_POWERSHELL_H_ 17 | -------------------------------------------------------------------------------- /bindings/c/tree-sitter-powershell.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 3 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ 4 | 5 | Name: tree-sitter-powershell 6 | Description: @PROJECT_DESCRIPTION@ 7 | URL: @PROJECT_HOMEPAGE_URL@ 8 | Version: @PROJECT_VERSION@ 9 | Libs: -L${libdir} -ltree-sitter-powershell 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_powershell 5 | 6 | 7 | class TestLanguage(TestCase): 8 | def test_can_load_grammar(self): 9 | try: 10 | Parser(Language(tree_sitter_powershell.language())) 11 | except Exception: 12 | self.fail("Error loading Powershell grammar") 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | 3 | src/*.json linguist-generated 4 | src/parser.c linguist-generated 5 | src/tree_sitter/* linguist-generated 6 | 7 | bindings/** linguist-generated 8 | binding.gyp linguist-generated 9 | setup.py linguist-generated 10 | Makefile linguist-generated 11 | Package.swift linguist-generated 12 | 13 | # Zig bindings 14 | build.zig linguist-generated 15 | build.zig.zon linguist-generated 16 | -------------------------------------------------------------------------------- /bindings/go/binding.go: -------------------------------------------------------------------------------- 1 | package tree_sitter_powershell 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_powershell()) 15 | } 16 | -------------------------------------------------------------------------------- /.zed/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "languages": { 3 | "JavaScript": { 4 | "formatter": "language_server", 5 | "code_actions_on_format": { 6 | "source.fixAll.eslint": true 7 | } 8 | }, 9 | "TypeScript": { 10 | "formatter": "language_server", 11 | "code_actions_on_format": { 12 | "source.fixAll.eslint": true 13 | } 14 | } 15 | }, 16 | "formatter": "language_server" 17 | } 18 | -------------------------------------------------------------------------------- /bindings/go/binding_test.go: -------------------------------------------------------------------------------- 1 | package tree_sitter_powershell_test 2 | 3 | import ( 4 | "testing" 5 | 6 | tree_sitter "github.com/tree-sitter/go-tree-sitter" 7 | tree_sitter_powershell "github.com/airbus-cert/tree-sitter-powershell/bindings/go" 8 | ) 9 | 10 | func TestCanLoadGrammar(t *testing.T) { 11 | language := tree_sitter.NewLanguage(tree_sitter_powershell.Language()) 12 | if language == nil { 13 | t.Errorf("Error loading Powershell grammar") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterPowershellTests/TreeSitterPowershellTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SwiftTreeSitter 3 | import TreeSitterPowershell 4 | 5 | final class TreeSitterPowershellTests: XCTestCase { 6 | func testCanLoadGrammar() throws { 7 | let parser = Parser() 8 | let language = Language(language: tree_sitter_powershell()) 9 | XCTAssertNoThrow(try parser.setLanguage(language), 10 | "Error loading Powershell grammar") 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /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-powershell.node`) 7 | : require("node-gyp-build")(root); 8 | 9 | try { 10 | module.exports.nodeTypeInfo = require("../../src/node-types.json"); 11 | } catch (_) {} 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /bindings/node/binding.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | extern "C" TSLanguage *tree_sitter_powershell(); 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_powershell()); 14 | language.TypeTag(&LANGUAGE_TYPE_TAG); 15 | exports["language"] = language; 16 | return exports; 17 | } 18 | 19 | NODE_API_MODULE(tree_sitter_powershell_binding, Init) 20 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [main] 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@v5 18 | - name: Set up Node.js 19 | uses: actions/setup-node@v5 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 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [*.{json,toml,yml,gyp}] 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [*.js] 14 | indent_style = space 15 | indent_size = 2 16 | 17 | [*.rs] 18 | indent_style = space 19 | indent_size = 4 20 | 21 | [*.{c,cc,h}] 22 | indent_style = space 23 | indent_size = 4 24 | 25 | [*.{py,pyi}] 26 | indent_style = space 27 | indent_size = 4 28 | 29 | [*.swift] 30 | indent_style = space 31 | indent_size = 4 32 | 33 | [*.go] 34 | indent_style = tab 35 | indent_size = 8 36 | 37 | [Makefile] 38 | indent_style = tab 39 | indent_size = 8 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Nix direnv build 2 | .direnv 3 | 4 | # Rust artifacts 5 | target/ 6 | Cargo.lock 7 | 8 | # Node artifacts 9 | build/ 10 | prebuilds/ 11 | node_modules/ 12 | package-lock.json 13 | 14 | # Swift artifacts 15 | .build/ 16 | Package.resolved 17 | 18 | # Go artifacts 19 | _obj/ 20 | 21 | # Python artifacts 22 | .venv/ 23 | dist/ 24 | *.egg-info 25 | *.whl 26 | 27 | # C artifacts 28 | *.a 29 | *.so 30 | *.so.* 31 | *.dylib 32 | *.dll 33 | *.pc 34 | *.exp 35 | *.lib 36 | 37 | # Zig artifacts 38 | .zig-cache/ 39 | zig-cache/ 40 | zig-out/ 41 | 42 | # Example dirs 43 | /examples/*/ 44 | 45 | # Grammar volatiles 46 | *.wasm 47 | *.obj 48 | *.o 49 | 50 | # Archives 51 | *.tar.gz 52 | *.tgz 53 | *.zip 54 | -------------------------------------------------------------------------------- /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 | 7 | #[cfg(target_env = "msvc")] 8 | c_config.flag("-utf-8"); 9 | 10 | let parser_path = src_dir.join("parser.c"); 11 | c_config.file(&parser_path); 12 | println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); 13 | 14 | let scanner_path = src_dir.join("scanner.c"); 15 | if scanner_path.exists() { 16 | c_config.file(&scanner_path); 17 | println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); 18 | } 19 | 20 | c_config.compile("tree-sitter-powershell"); 21 | } 22 | -------------------------------------------------------------------------------- /tree-sitter.json: -------------------------------------------------------------------------------- 1 | { 2 | "grammars": [ 3 | { 4 | "name": "powershell", 5 | "camelcase": "Powershell", 6 | "scope": "source.ps1", 7 | "path": ".", 8 | "file-types": [ 9 | "ps1", 10 | "psm1" 11 | ], 12 | "highlights": [ 13 | "queries/highlights.scm" 14 | ], 15 | "injection-regex": "^(ps1|psm1)$" 16 | } 17 | ], 18 | "metadata": { 19 | "version": "0.25.10", 20 | "license": "MIT", 21 | "description": "", 22 | "links": { 23 | "repository": "https://github.com/airbus-cert/tree-sitter-powershell" 24 | } 25 | }, 26 | "bindings": { 27 | "c": true, 28 | "go": true, 29 | "node": true, 30 | "python": true, 31 | "rust": true, 32 | "swift": true 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=62.4.0", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "tree-sitter-powershell" 7 | description = "" 8 | version = "0.25.10" 9 | keywords = ["incremental", "parsing", "tree-sitter", "powershell"] 10 | classifiers = [ 11 | "Intended Audience :: Developers", 12 | "Topic :: Software Development :: Compilers", 13 | "Topic :: Text Processing :: Linguistic", 14 | "Typing :: Typed", 15 | ] 16 | requires-python = ">=3.10" 17 | license.text = "MIT" 18 | readme = "README.md" 19 | 20 | [project.urls] 21 | Homepage = "https://github.com/airbus-cert/tree-sitter-powershell" 22 | 23 | [project.optional-dependencies] 24 | core = ["tree-sitter~=0.24"] 25 | 26 | [tool.cibuildwheel] 27 | build = "cp310-*" 28 | build-frontend = "build" 29 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-powershell" 3 | description = "Powershell grammar for tree-sitter " 4 | version = "0.25.10" 5 | license = "MIT" 6 | readme = "README.md" 7 | keywords = ["incremental", "parsing", "tree-sitter", "powershell"] 8 | categories = ["parser-implementations", "parsing", "text-editors"] 9 | repository = "https://github.com/airbus-cert/tree-sitter-powershell" 10 | edition = "2021" 11 | autoexamples = false 12 | 13 | build = "bindings/rust/build.rs" 14 | include = [ 15 | "bindings/rust/*", 16 | "grammar.js", 17 | "queries/*", 18 | "src/*", 19 | "tree-sitter.json", 20 | "/LICENSE", 21 | ] 22 | 23 | [lib] 24 | path = "bindings/rust/lib.rs" 25 | 26 | [dependencies] 27 | tree-sitter-language = "0.1" 28 | 29 | [build-dependencies] 30 | cc = "1.2" 31 | 32 | [dev-dependencies] 33 | tree-sitter = "0.25.10" 34 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_powershell_binding", 5 | "dependencies": [ 6 | " 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | TSLanguage *tree_sitter_powershell(void); 6 | 7 | static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) { 8 | return PyCapsule_New(tree_sitter_powershell(), "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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Airbus CERT 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/corpus/enum.txt: -------------------------------------------------------------------------------- 1 | === 2 | Enum : Simple enum 3 | === 4 | 5 | enum MyEnum 6 | { 7 | One 8 | } 9 | 10 | --- 11 | 12 | (program 13 | (statement_list 14 | (enum_statement 15 | (simple_name) 16 | (enum_member 17 | (simple_name))))) 18 | 19 | 20 | 21 | === 22 | More complex enum 23 | === 24 | 25 | enum Enum2 26 | { 27 | Part1; Two 28 | 29 | Three 30 | 31 | 32 | 33 | Four 34 | } 35 | 36 | --- 37 | 38 | (program 39 | (statement_list 40 | (enum_statement 41 | (simple_name) 42 | (enum_member 43 | (simple_name)) 44 | (enum_member 45 | (simple_name)) 46 | (enum_member 47 | (simple_name)) 48 | (enum_member 49 | (simple_name))))) 50 | 51 | === 52 | Enum : Complex enum 53 | === 54 | 55 | enum MyEnum 56 | { 57 | One 58 | Two = 2; Three = 3 59 | } 60 | 61 | --- 62 | 63 | (program 64 | (statement_list 65 | (enum_statement 66 | (simple_name) 67 | (enum_member 68 | (simple_name)) 69 | (enum_member 70 | (simple_name) 71 | (integer_literal 72 | (decimal_integer_literal))) 73 | (enum_member 74 | (simple_name) 75 | (integer_literal 76 | (decimal_integer_literal)))))) -------------------------------------------------------------------------------- /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: "TreeSitterPowershell", 13 | products: [ 14 | .library(name: "TreeSitterPowershell", targets: ["TreeSitterPowershell"]), 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: "TreeSitterPowershell", 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: "TreeSitterPowershellTests", 33 | dependencies: [ 34 | "SwiftTreeSitter", 35 | "TreeSitterPowershell", 36 | ], 37 | path: "bindings/swift/TreeSitterPowershellTests" 38 | ) 39 | ], 40 | cLanguageStandard: .c11 41 | ) 42 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-powershell", 3 | "version": "0.25.10", 4 | "description": "", 5 | "main": "bindings/node", 6 | "types": "bindings/node", 7 | "scripts": { 8 | "generate": "tree-sitter generate", 9 | "build-node": "tree-sitter generate && node-gyp build", 10 | "test": "tree-sitter test", 11 | "parse": "tree-sitter parse", 12 | "parse-debug": "tree-sitter parse -d", 13 | "build-wasm": "tree-sitter build --wasm", 14 | "install": "node-gyp-build", 15 | "lint": "eslint grammar.js", 16 | "prebuildify": "prebuildify --napi --strip" 17 | }, 18 | "author": "", 19 | "license": "MIT", 20 | "dependencies": { 21 | "node-addon-api": "^7.1.0", 22 | "node-gyp-build": "^4.8.0" 23 | }, 24 | "peerDependencies": { 25 | "tree-sitter": "^0.25.0" 26 | }, 27 | "peerDependenciesMeta": { 28 | "tree-sitter": { 29 | "optional": true 30 | } 31 | }, 32 | "devDependencies": { 33 | "eslint": "^9.38.0", 34 | "eslint-config-treesitter": "^1.0.2", 35 | "node-gyp": "^9.4.0", 36 | "prebuildify": "^6.0.0", 37 | "tree-sitter-cli": "^0.25.0" 38 | }, 39 | "files": [ 40 | "grammar.js", 41 | "binding.gyp", 42 | "prebuilds/**", 43 | "bindings/node/*", 44 | "queries/*", 45 | "src/**", 46 | "*.wasm" 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_powershell/__init__.py: -------------------------------------------------------------------------------- 1 | """""" 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 | # NOTE: uncomment these to include any queries that this grammar contains: 16 | 17 | # if name == "HIGHLIGHTS_QUERY": 18 | # return _get_query("HIGHLIGHTS_QUERY", "highlights.scm") 19 | # if name == "INJECTIONS_QUERY": 20 | # return _get_query("INJECTIONS_QUERY", "injections.scm") 21 | # if name == "LOCALS_QUERY": 22 | # return _get_query("LOCALS_QUERY", "locals.scm") 23 | # if name == "TAGS_QUERY": 24 | # return _get_query("TAGS_QUERY", "tags.scm") 25 | 26 | raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 27 | 28 | 29 | __all__ = [ 30 | "language", 31 | # "HIGHLIGHTS_QUERY", 32 | # "INJECTIONS_QUERY", 33 | # "LOCALS_QUERY", 34 | # "TAGS_QUERY", 35 | ] 36 | 37 | 38 | def __dir__(): 39 | return sorted(__all__ + [ 40 | "__all__", "__builtins__", "__cached__", "__doc__", "__file__", 41 | "__loader__", "__name__", "__package__", "__path__", "__spec__", 42 | ]) 43 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | # source: https://github.com/nix-community/poetry2nix/blob/master/templates/app/flake.nix 2 | { 3 | description = "tree-sitter-powershell"; 4 | 5 | inputs = { 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; 8 | nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; 9 | }; 10 | 11 | outputs = 12 | { 13 | self, 14 | nixpkgs, 15 | nixpkgs-unstable, 16 | flake-utils, 17 | }: 18 | flake-utils.lib.eachDefaultSystem ( 19 | system: 20 | let 21 | pkgs = nixpkgs.legacyPackages.${system}; 22 | pkgs-unstable = nixpkgs-unstable.legacyPackages.${system}; 23 | in 24 | { 25 | packages = { 26 | default = self.packages.${system}.myapp; 27 | }; 28 | 29 | devShells.default = pkgs.mkShell { 30 | packages = [ 31 | # Dev tools 32 | pkgs.gnumake 33 | pkgs.nixpkgs-fmt 34 | pkgs.nil 35 | pkgs.nixd 36 | pkgs.alejandra 37 | 38 | # Rust 39 | pkgs-unstable.rustc 40 | pkgs-unstable.cargo 41 | pkgs-unstable.rust-analyzer 42 | pkgs-unstable.rustfmt 43 | 44 | # Tree-sitter 45 | pkgs.nodejs_24 46 | pkgs-unstable.emscripten 47 | pkgs-unstable.binaryen 48 | (pkgs-unstable.tree-sitter.override { 49 | webUISupport = true; 50 | }) 51 | ]; 52 | }; 53 | } 54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /bindings/rust/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides Powershell 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 | //! "#; 9 | //! let mut parser = tree_sitter::Parser::new(); 10 | //! let language = tree_sitter_powershell::LANGUAGE; 11 | //! parser 12 | //! .set_language(&language.into()) 13 | //! .expect("Error loading Powershell parser"); 14 | //! let tree = parser.parse(code, None).unwrap(); 15 | //! assert!(!tree.root_node().has_error()); 16 | //! ``` 17 | //! 18 | //! [`Parser`]: https://docs.rs/tree-sitter/0.25.10/tree_sitter/struct.Parser.html 19 | //! [tree-sitter]: https://tree-sitter.github.io/ 20 | 21 | use tree_sitter_language::LanguageFn; 22 | 23 | extern "C" { 24 | fn tree_sitter_powershell() -> *const (); 25 | } 26 | 27 | /// The tree-sitter [`LanguageFn`] for this grammar. 28 | pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_powershell) }; 29 | 30 | /// The content of the [`node-types.json`] file for this grammar. 31 | /// 32 | /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types 33 | pub const NODE_TYPES: &str = include_str!("../../src/node-types.json"); 34 | 35 | // NOTE: uncomment these to include any queries that this grammar contains: 36 | 37 | // pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); 38 | // pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm"); 39 | // pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); 40 | // pub const TAGS_QUERY: &str = include_str!("../../queries/tags.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 Powershell parser"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1764983851, 24 | "narHash": "sha256-y7RPKl/jJ/KAP/VKLMghMgXTlvNIJMHKskl8/Uuar7o=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "d9bc5c7dceb30d8d6fafa10aeb6aa8a48c218454", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixos-25.11", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "nixpkgs-unstable": { 38 | "locked": { 39 | "lastModified": 1761114652, 40 | "narHash": "sha256-f/QCJM/YhrV/lavyCVz8iU3rlZun6d+dAiC3H+CDle4=", 41 | "owner": "NixOS", 42 | "repo": "nixpkgs", 43 | "rev": "01f116e4df6a15f4ccdffb1bcd41096869fb385c", 44 | "type": "github" 45 | }, 46 | "original": { 47 | "owner": "NixOS", 48 | "ref": "nixos-unstable", 49 | "repo": "nixpkgs", 50 | "type": "github" 51 | } 52 | }, 53 | "root": { 54 | "inputs": { 55 | "flake-utils": "flake-utils", 56 | "nixpkgs": "nixpkgs", 57 | "nixpkgs-unstable": "nixpkgs-unstable" 58 | } 59 | }, 60 | "systems": { 61 | "locked": { 62 | "lastModified": 1681028828, 63 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 64 | "owner": "nix-systems", 65 | "repo": "default", 66 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 67 | "type": "github" 68 | }, 69 | "original": { 70 | "owner": "nix-systems", 71 | "repo": "default", 72 | "type": "github" 73 | } 74 | } 75 | }, 76 | "root": "root", 77 | "version": 7 78 | } 79 | -------------------------------------------------------------------------------- /src/scanner.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. See the LICENSE file in the project root for full license information. 3 | 4 | #include 5 | #include 6 | 7 | enum TOKEN_TYPE { 8 | STATEMENT_TERMINATOR 9 | }; 10 | 11 | /* --- API --- */ 12 | 13 | void *tree_sitter_powershell_external_scanner_create(); 14 | 15 | void tree_sitter_powershell_external_scanner_destroy(void *p); 16 | 17 | unsigned tree_sitter_powershell_external_scanner_serialize(void *payload, char *buffer); 18 | 19 | void tree_sitter_powershell_external_scanner_deserialize(void *payload, const char *buffer, unsigned length); 20 | 21 | bool tree_sitter_powershell_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols); 22 | 23 | /* --- Internal Functions --- */ 24 | 25 | static void skip(TSLexer *lexer) { lexer->advance(lexer, true); } 26 | 27 | static bool scan_statement_terminator(void *payload, TSLexer *lexer, const bool *valid_symbols) 28 | { 29 | if (valid_symbols[STATEMENT_TERMINATOR]) { 30 | lexer->result_symbol = STATEMENT_TERMINATOR; 31 | // This token has no characters -- everything is lookahead to determine its existence 32 | lexer->mark_end(lexer); 33 | 34 | for (;;) { 35 | if (lexer->lookahead == 0) return true; 36 | if (lexer->lookahead == '}') return true; 37 | if (lexer->lookahead == ';') return true; 38 | if (lexer->lookahead == ')') return true; 39 | if (lexer->lookahead == '\n') return true; 40 | if (!iswspace(lexer->lookahead)) return false; 41 | skip(lexer); 42 | } 43 | } 44 | 45 | return false; 46 | } 47 | 48 | /* --- API Implementation --- */ 49 | 50 | bool tree_sitter_powershell_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) 51 | { 52 | return scan_statement_terminator(payload, lexer, valid_symbols); 53 | } 54 | 55 | void *tree_sitter_powershell_external_scanner_create() 56 | { 57 | return NULL; 58 | } 59 | 60 | void tree_sitter_powershell_external_scanner_destroy(void *p) 61 | { 62 | } 63 | 64 | unsigned tree_sitter_powershell_external_scanner_serialize(void *payload, char *buffer) 65 | { 66 | return 0; 67 | } 68 | 69 | void tree_sitter_powershell_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) 70 | { 71 | } 72 | -------------------------------------------------------------------------------- /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_powershell", "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_powershell": ["*.pyi", "py.typed"], 52 | "tree_sitter_powershell.queries": ["*.scm"], 53 | }, 54 | ext_package="tree_sitter_powershell", 55 | ext_modules=[ 56 | Extension( 57 | name="_binding", 58 | sources=[ 59 | "bindings/python/tree_sitter_powershell/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 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | "param" @keyword 2 | "dynamicparam" @keyword 3 | "begin" @keyword 4 | "process" @keyword 5 | "end" @keyword 6 | "if" @keyword 7 | "elseif" @keyword 8 | "else" @keyword 9 | "switch" @keyword 10 | "foreach" @keyword 11 | "for" @keyword 12 | "while" @keyword 13 | "do" @keyword 14 | "until" @keyword 15 | "function" @keyword 16 | "filter" @keyword 17 | "workflow" @keyword 18 | "break" @keyword 19 | "continue" @keyword 20 | "throw" @keyword 21 | "return" @keyword 22 | "exit" @keyword 23 | "trap" @keyword 24 | "try" @keyword 25 | "catch" @keyword 26 | "finally" @keyword 27 | "data" @keyword 28 | "inlinescript" @keyword 29 | "parallel" @keyword 30 | "sequence" @keyword 31 | 32 | "-as" @operator 33 | "-ccontains" @operator 34 | "-ceq" @operator 35 | "-cge" @operator 36 | "-cgt" @operator 37 | "-cle" @operator 38 | "-clike" @operator 39 | "-clt" @operator 40 | "-cmatch" @operator 41 | "-cne" @operator 42 | "-cnotcontains" @operator 43 | "-cnotlike" @operator 44 | "-cnotmatch" @operator 45 | "-contains" @operator 46 | "-creplace" @operator 47 | "-csplit" @operator 48 | "-eq" @operator 49 | "-ge" @operator 50 | "-gt" @operator 51 | "-icontains" @operator 52 | "-ieq" @operator 53 | "-ige" @operator 54 | "-igt" @operator 55 | "-ile" @operator 56 | "-ilike" @operator 57 | "-ilt" @operator 58 | "-imatch" @operator 59 | "-in" @operator 60 | "-ine" @operator 61 | "-inotcontains" @operator 62 | "-inotlike" @operator 63 | "-inotmatch" @operator 64 | "-ireplace" @operator 65 | "-is" @operator 66 | "-isnot" @operator 67 | "-isplit" @operator 68 | "-join" @operator 69 | "-le" @operator 70 | "-like" @operator 71 | "-lt" @operator 72 | "-match" @operator 73 | "-ne" @operator 74 | "-notcontains" @operator 75 | "-notin" @operator 76 | "-notlike" @operator 77 | "-notmatch" @operator 78 | "-replace" @operator 79 | "-shl" @operator 80 | "-shr" @operator 81 | "-split" @operator 82 | "-and" @operator 83 | "-or" @operator 84 | "-xor" @operator 85 | "-band" @operator 86 | "-bor" @operator 87 | "-bxor" @operator 88 | "+" @operator 89 | "-" @operator 90 | "/" @operator 91 | "\\" @operator 92 | "%" @operator 93 | "*" @operator 94 | ".." @operator 95 | "-not" @operator 96 | 97 | 98 | ";" @delimiter 99 | 100 | (string_literal) @string 101 | 102 | (integer_literal) @number 103 | (real_literal) @number 104 | 105 | (command 106 | command_name: (command_name) @function) 107 | 108 | (function_statement 109 | (function_name) @function) 110 | 111 | (invokation_expression 112 | (member_name) @function) 113 | 114 | (member_access 115 | (member_name) @property) 116 | 117 | (command_invokation_operator) @operator 118 | 119 | (type_spec) @type 120 | 121 | (variable) @variable 122 | 123 | (comment) @comment 124 | 125 | (array_expression) @array 126 | 127 | (assignment_expression 128 | value: (pipeline) @assignvalue) -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | project(tree-sitter-powershell 4 | VERSION "0.25.0" 5 | DESCRIPTION "" 6 | HOMEPAGE_URL "https://github.com/airbus-cert/tree-sitter-powershell" 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 15 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 | include(GNUInstallDirs) 19 | 20 | find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI") 21 | 22 | add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" 23 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" 24 | COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json 25 | --abi=${TREE_SITTER_ABI_VERSION} 26 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 27 | COMMENT "Generating parser.c") 28 | 29 | add_library(tree-sitter-powershell src/parser.c) 30 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src/scanner.c) 31 | target_sources(tree-sitter-powershell PRIVATE src/scanner.c) 32 | endif() 33 | target_include_directories(tree-sitter-powershell 34 | PRIVATE src 35 | INTERFACE $ 36 | $) 37 | 38 | target_compile_definitions(tree-sitter-powershell PRIVATE 39 | $<$:TREE_SITTER_REUSE_ALLOCATOR> 40 | $<$:TREE_SITTER_DEBUG>) 41 | 42 | set_target_properties(tree-sitter-powershell 43 | PROPERTIES 44 | C_STANDARD 11 45 | POSITION_INDEPENDENT_CODE ON 46 | SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}" 47 | DEFINE_SYMBOL "") 48 | 49 | configure_file(bindings/c/tree-sitter-powershell.pc.in 50 | "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-powershell.pc" @ONLY) 51 | 52 | install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bindings/c/tree_sitter" 53 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" 54 | FILES_MATCHING PATTERN "*.h") 55 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-powershell.pc" 56 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 57 | install(TARGETS tree-sitter-powershell 58 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") 59 | 60 | file(GLOB QUERIES queries/*.scm) 61 | install(FILES ${QUERIES} 62 | DESTINATION "${CMAKE_INSTALL_DATADIR}/tree-sitter/queries/powershell") 63 | 64 | add_custom_target(ts-test "${TREE_SITTER_CLI}" test 65 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 66 | COMMENT "tree-sitter test") 67 | -------------------------------------------------------------------------------- /test/corpus/pipeline_chains.txt: -------------------------------------------------------------------------------- 1 | === 2 | Pipeline chain #1: && 3 | === 4 | 5 | echo toto && echo tata 6 | 7 | --- 8 | 9 | (program 10 | (statement_list 11 | (pipeline 12 | (pipeline_chain 13 | (command 14 | command_name: (command_name) 15 | command_elements: (command_elements 16 | (command_argument_sep) 17 | (generic_token) 18 | (command_argument_sep)))) 19 | (pipeline_chain_tail) 20 | (pipeline_chain 21 | (command 22 | command_name: (command_name) 23 | command_elements: (command_elements 24 | (command_argument_sep) 25 | (generic_token))))))) 26 | 27 | === 28 | Pipeline chain #2: || 29 | === 30 | 31 | echo toto || echo tata 32 | 33 | --- 34 | 35 | (program 36 | (statement_list 37 | (pipeline 38 | (pipeline_chain 39 | (command 40 | command_name: (command_name) 41 | command_elements: (command_elements 42 | (command_argument_sep) 43 | (generic_token) 44 | (command_argument_sep)))) 45 | (pipeline_chain_tail) 46 | (pipeline_chain 47 | (command 48 | command_name: (command_name) 49 | command_elements: (command_elements 50 | (command_argument_sep) 51 | (generic_token))))))) 52 | 53 | === 54 | Pipeline chain #3: Priority over redirection and pipe 55 | === 56 | 57 | echo toto > tmp1 && 1+1 | write-output > tmp2 58 | 59 | --- 60 | 61 | (program 62 | (statement_list 63 | (pipeline 64 | (pipeline_chain 65 | (command 66 | command_name: (command_name) 67 | command_elements: (command_elements 68 | (command_argument_sep) 69 | (generic_token) 70 | (command_argument_sep) 71 | (redirection 72 | (file_redirection_operator) 73 | (redirected_file_name 74 | (command_argument_sep) 75 | (generic_token))) 76 | (command_argument_sep)))) 77 | (pipeline_chain_tail) 78 | (pipeline_chain 79 | (logical_expression 80 | (bitwise_expression 81 | (comparison_expression 82 | (additive_expression 83 | (additive_expression 84 | (multiplicative_expression 85 | (format_expression 86 | (range_expression 87 | (array_literal_expression 88 | (unary_expression 89 | (integer_literal 90 | (decimal_integer_literal)))))))) 91 | (multiplicative_expression 92 | (format_expression 93 | (range_expression 94 | (array_literal_expression 95 | (unary_expression 96 | (integer_literal 97 | (decimal_integer_literal))))))))))) 98 | (command 99 | command_name: (command_name) 100 | command_elements: (command_elements 101 | (command_argument_sep) 102 | (redirection 103 | (file_redirection_operator) 104 | (redirected_file_name 105 | (command_argument_sep) 106 | (generic_token))))))))) 107 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(OS),Windows_NT) 2 | $(error Windows is not supported) 3 | endif 4 | 5 | LANGUAGE_NAME := tree-sitter-powershell 6 | HOMEPAGE_URL := https://github.com/airbus-cert/tree-sitter-powershell 7 | VERSION := 0.25.10 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 := $(filter-out $(PARSER),$(wildcard $(SRC_DIR)/*.c)) 24 | OBJS := $(patsubst %.c,%.o,$(PARSER) $(EXTRAS)) 25 | 26 | # flags 27 | ARFLAGS ?= rcs 28 | override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC 29 | 30 | # ABI versioning 31 | SONAME_MAJOR = $(shell sed -n 's/\#define LANGUAGE_VERSION //p' $(PARSER)) 32 | SONAME_MINOR = $(word 1,$(subst ., ,$(VERSION))) 33 | 34 | # OS-specific bits 35 | ifeq ($(shell uname),Darwin) 36 | SOEXT = dylib 37 | SOEXTVER_MAJOR = $(SONAME_MAJOR).$(SOEXT) 38 | SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT) 39 | LINKSHARED = -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER),-rpath,@executable_path/../Frameworks 40 | else 41 | SOEXT = so 42 | SOEXTVER_MAJOR = $(SOEXT).$(SONAME_MAJOR) 43 | SOEXTVER = $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR) 44 | LINKSHARED = -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER) 45 | endif 46 | ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),) 47 | PCLIBDIR := $(PREFIX)/libdata/pkgconfig 48 | endif 49 | 50 | all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc 51 | 52 | lib$(LANGUAGE_NAME).a: $(OBJS) 53 | $(AR) $(ARFLAGS) $@ $^ 54 | 55 | lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS) 56 | $(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@ 57 | ifneq ($(STRIP),) 58 | $(STRIP) $@ 59 | endif 60 | 61 | $(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in 62 | sed -e 's|@PROJECT_VERSION@|$(VERSION)|' \ 63 | -e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \ 64 | -e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \ 65 | -e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \ 66 | -e 's|@PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \ 67 | -e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@ 68 | 69 | $(PARSER): $(SRC_DIR)/grammar.json 70 | $(TS) generate $^ 71 | 72 | install: all 73 | install -d '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/powershell '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)' 74 | install -m644 bindings/c/tree_sitter/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h 75 | install -m644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 76 | install -m644 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a 77 | install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) 78 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) 79 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) 80 | ifneq ($(wildcard queries/*.scm),) 81 | install -m644 queries/*.scm '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/powershell 82 | endif 83 | 84 | uninstall: 85 | $(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \ 86 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \ 87 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \ 88 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \ 89 | '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \ 90 | '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 91 | $(RM) -r '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/powershell 92 | 93 | clean: 94 | $(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) 95 | 96 | test: 97 | $(TS) test 98 | 99 | .PHONY: all install uninstall clean test 100 | -------------------------------------------------------------------------------- /test/corpus/comments.txt: -------------------------------------------------------------------------------- 1 | === 2 | Single inline comment 3 | === 4 | 5 | $x = 3 6 | 7 | # This is a comment 8 | 9 | Get-ChildItem . 10 | 11 | --- 12 | 13 | (program 14 | (statement_list 15 | (pipeline 16 | (assignment_expression 17 | (left_assignment_expression 18 | (logical_expression 19 | (bitwise_expression 20 | (comparison_expression 21 | (additive_expression 22 | (multiplicative_expression 23 | (format_expression 24 | (range_expression 25 | (array_literal_expression 26 | (unary_expression 27 | (variable))))))))))) 28 | (assignement_operator) 29 | (pipeline 30 | (pipeline_chain 31 | (logical_expression 32 | (bitwise_expression 33 | (comparison_expression 34 | (additive_expression 35 | (multiplicative_expression 36 | (format_expression 37 | (range_expression 38 | (array_literal_expression 39 | (unary_expression 40 | (integer_literal 41 | (decimal_integer_literal))))))))))))))) 42 | (comment) 43 | (pipeline 44 | (pipeline_chain 45 | (command 46 | (command_name) 47 | (command_elements 48 | (command_argument_sep) 49 | (generic_token))))))) 50 | 51 | 52 | === 53 | Single line block comment 54 | === 55 | 56 | $x = 3 57 | 58 | <# Block comment #> 59 | 60 | Get-ChildItem . 61 | 62 | --- 63 | 64 | (program 65 | (statement_list 66 | (pipeline 67 | (assignment_expression 68 | (left_assignment_expression 69 | (logical_expression 70 | (bitwise_expression 71 | (comparison_expression 72 | (additive_expression 73 | (multiplicative_expression 74 | (format_expression 75 | (range_expression 76 | (array_literal_expression 77 | (unary_expression 78 | (variable))))))))))) 79 | (assignement_operator) 80 | (pipeline 81 | (pipeline_chain 82 | (logical_expression 83 | (bitwise_expression 84 | (comparison_expression 85 | (additive_expression 86 | (multiplicative_expression 87 | (format_expression 88 | (range_expression 89 | (array_literal_expression 90 | (unary_expression 91 | (integer_literal 92 | (decimal_integer_literal))))))))))))))) 93 | (comment) 94 | (pipeline 95 | (pipeline_chain 96 | (command 97 | (command_name) 98 | (command_elements 99 | (command_argument_sep) 100 | (generic_token))))))) 101 | 102 | === 103 | Multi-line block comment 104 | === 105 | 106 | $x = 3 107 | 108 | <# 109 | 110 | Here 111 | 112 | is a 113 | 114 | longer 115 | 116 | comment #> 117 | 118 | Get-ChildItem . 119 | 120 | --- 121 | 122 | (program 123 | (statement_list 124 | (pipeline 125 | (assignment_expression 126 | (left_assignment_expression 127 | (logical_expression 128 | (bitwise_expression 129 | (comparison_expression 130 | (additive_expression 131 | (multiplicative_expression 132 | (format_expression 133 | (range_expression 134 | (array_literal_expression 135 | (unary_expression 136 | (variable))))))))))) 137 | (assignement_operator) 138 | (pipeline 139 | (pipeline_chain 140 | (logical_expression 141 | (bitwise_expression 142 | (comparison_expression 143 | (additive_expression 144 | (multiplicative_expression 145 | (format_expression 146 | (range_expression 147 | (array_literal_expression 148 | (unary_expression 149 | (integer_literal 150 | (decimal_integer_literal))))))))))))))) 151 | (comment) 152 | (pipeline 153 | (pipeline_chain 154 | (command 155 | (command_name) 156 | (command_elements 157 | (command_argument_sep) 158 | (generic_token))))))) 159 | 160 | === 161 | Pathological block comment #1 162 | === 163 | 164 | <##> 165 | $a 166 | 167 | --- 168 | 169 | (program 170 | (comment) 171 | (statement_list 172 | (pipeline 173 | (pipeline_chain 174 | (logical_expression 175 | (bitwise_expression 176 | (comparison_expression 177 | (additive_expression 178 | (multiplicative_expression 179 | (format_expression 180 | (range_expression 181 | (array_literal_expression 182 | (unary_expression 183 | (variable)))))))))))))) 184 | 185 | === 186 | Pathological block comment #2 187 | === 188 | 189 | <###> 190 | $a 191 | 192 | 193 | --- 194 | 195 | (program 196 | (comment) 197 | (statement_list 198 | (pipeline 199 | (pipeline_chain 200 | (logical_expression 201 | (bitwise_expression 202 | (comparison_expression 203 | (additive_expression 204 | (multiplicative_expression 205 | (format_expression 206 | (range_expression 207 | (array_literal_expression 208 | (unary_expression 209 | (variable)))))))))))))) 210 | -------------------------------------------------------------------------------- /test/corpus/classes.txt: -------------------------------------------------------------------------------- 1 | === 2 | Class : empty declaration 3 | === 4 | 5 | class MyClass {} 6 | 7 | --- 8 | 9 | (program 10 | (statement_list 11 | (class_statement 12 | (simple_name)))) 13 | 14 | === 15 | Class : string property 16 | === 17 | 18 | class MyClass 19 | { 20 | [string]$Name 21 | } 22 | 23 | --- 24 | 25 | (program 26 | (statement_list 27 | (class_statement 28 | (simple_name) 29 | (class_property_definition 30 | (type_literal 31 | (type_spec 32 | (type_name 33 | (type_identifier)))) 34 | (variable))))) 35 | 36 | 37 | === 38 | Class : string property with attributes 39 | === 40 | 41 | class MyClass 42 | { 43 | static hidden [string]$Name 44 | } 45 | 46 | --- 47 | 48 | (program 49 | (statement_list 50 | (class_statement 51 | (simple_name) 52 | (class_property_definition 53 | (class_attribute) 54 | (class_attribute) 55 | (type_literal 56 | (type_spec 57 | (type_name 58 | (type_identifier)))) 59 | (variable))))) 60 | 61 | === 62 | Class : method declaration 63 | === 64 | 65 | class MyClass 66 | { 67 | [void]SayHi() 68 | { 69 | Write-Host "Hi" 70 | } 71 | } 72 | 73 | --- 74 | 75 | (program 76 | (statement_list 77 | (class_statement 78 | (simple_name) 79 | (class_method_definition 80 | (type_literal 81 | (type_spec 82 | (type_name 83 | (type_identifier)))) 84 | (simple_name) 85 | (script_block 86 | (script_block_body 87 | (statement_list 88 | (pipeline 89 | (pipeline_chain 90 | (command 91 | (command_name) 92 | (command_elements 93 | (command_argument_sep) 94 | (array_literal_expression 95 | (unary_expression 96 | (string_literal 97 | (expandable_string_literal))))))))))))))) 98 | 99 | === 100 | Class : method declaration with parameters 101 | === 102 | 103 | class MyClass 104 | { 105 | hidden static [void]SayHi($Greeting, $Title) 106 | { 107 | Write-Host "$Greeting, $Title" 108 | } 109 | } 110 | 111 | --- 112 | 113 | (program 114 | (statement_list 115 | (class_statement 116 | (simple_name) 117 | (class_method_definition 118 | (class_attribute) 119 | (class_attribute) 120 | (type_literal 121 | (type_spec 122 | (type_name 123 | (type_identifier)))) 124 | (simple_name) 125 | (class_method_parameter_list 126 | (class_method_parameter 127 | (variable)) 128 | (class_method_parameter 129 | (variable))) 130 | (script_block 131 | (script_block_body 132 | (statement_list 133 | (pipeline 134 | (pipeline_chain 135 | (command 136 | (command_name) 137 | (command_elements 138 | (command_argument_sep) 139 | (array_literal_expression 140 | (unary_expression 141 | (string_literal 142 | (expandable_string_literal 143 | (variable) 144 | (variable)))))))))))))))) 145 | 146 | 147 | === 148 | Class : mix method and properties declaration 149 | === 150 | 151 | class MyClass 152 | { 153 | static [string]$Word 154 | 155 | static [void]AnotherMethod() 156 | { 157 | Write-Host "Nothing" 158 | } 159 | 160 | [int]$Number 161 | 162 | [void]SayHi($Greeting, $Title) 163 | { 164 | Write-Host "$Greeting, $Title" 165 | } 166 | 167 | MyClass() { 168 | 169 | } 170 | } 171 | 172 | --- 173 | 174 | (program 175 | (statement_list 176 | (class_statement 177 | (simple_name) 178 | (class_property_definition 179 | (class_attribute) 180 | (type_literal 181 | (type_spec 182 | (type_name 183 | (type_identifier)))) 184 | (variable)) 185 | (class_method_definition 186 | (class_attribute) 187 | (type_literal 188 | (type_spec 189 | (type_name 190 | (type_identifier)))) 191 | (simple_name) 192 | (script_block 193 | (script_block_body 194 | (statement_list 195 | (pipeline 196 | (pipeline_chain 197 | (command 198 | (command_name) 199 | (command_elements 200 | (command_argument_sep) 201 | (array_literal_expression 202 | (unary_expression 203 | (string_literal 204 | (expandable_string_literal)))))))))))) 205 | (class_property_definition 206 | (type_literal 207 | (type_spec 208 | (type_name 209 | (type_identifier)))) 210 | (variable)) 211 | (class_method_definition 212 | (type_literal 213 | (type_spec 214 | (type_name 215 | (type_identifier)))) 216 | (simple_name) 217 | (class_method_parameter_list 218 | (class_method_parameter 219 | (variable)) 220 | (class_method_parameter 221 | (variable))) 222 | (script_block 223 | (script_block_body 224 | (statement_list 225 | (pipeline 226 | (pipeline_chain 227 | (command 228 | (command_name) 229 | (command_elements 230 | (command_argument_sep) 231 | (array_literal_expression 232 | (unary_expression 233 | (string_literal 234 | (expandable_string_literal 235 | (variable) 236 | (variable))))))))))))) 237 | (class_method_definition 238 | (simple_name))))) 239 | -------------------------------------------------------------------------------- /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.43" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" 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.4" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" 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.12.0" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" 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.103" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" 69 | dependencies = [ 70 | "unicode-ident", 71 | ] 72 | 73 | [[package]] 74 | name = "quote" 75 | version = "1.0.41" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" 78 | dependencies = [ 79 | "proc-macro2", 80 | ] 81 | 82 | [[package]] 83 | name = "regex" 84 | version = "1.12.2" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" 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.13" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" 99 | dependencies = [ 100 | "aho-corasick", 101 | "memchr", 102 | "regex-syntax", 103 | ] 104 | 105 | [[package]] 106 | name = "regex-syntax" 107 | version = "0.8.8" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" 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.228" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" 122 | dependencies = [ 123 | "serde_core", 124 | ] 125 | 126 | [[package]] 127 | name = "serde_core" 128 | version = "1.0.228" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" 131 | dependencies = [ 132 | "serde_derive", 133 | ] 134 | 135 | [[package]] 136 | name = "serde_derive" 137 | version = "1.0.228" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" 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.108" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" 177 | dependencies = [ 178 | "proc-macro2", 179 | "quote", 180 | "unicode-ident", 181 | ] 182 | 183 | [[package]] 184 | name = "tree-sitter" 185 | version = "0.25.10" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87" 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-powershell" 205 | version = "0.25.10" 206 | dependencies = [ 207 | "cc", 208 | "tree-sitter", 209 | "tree-sitter-language", 210 | ] 211 | 212 | [[package]] 213 | name = "unicode-ident" 214 | version = "1.0.20" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" 217 | -------------------------------------------------------------------------------- /test/corpus/number.txt: -------------------------------------------------------------------------------- 1 | === 2 | Integer 3 | === 4 | 5 | 239 6 | 7 | --- 8 | 9 | (program 10 | (statement_list 11 | (pipeline 12 | (pipeline_chain 13 | (logical_expression 14 | (bitwise_expression 15 | (comparison_expression 16 | (additive_expression 17 | (multiplicative_expression 18 | (format_expression 19 | (range_expression 20 | (array_literal_expression 21 | (unary_expression 22 | (integer_literal 23 | (decimal_integer_literal))))))))))))))) 24 | 25 | === 26 | Float 27 | === 28 | 29 | 12.9191008 30 | 31 | --- 32 | 33 | (program 34 | (statement_list 35 | (pipeline 36 | (pipeline_chain 37 | (logical_expression 38 | (bitwise_expression 39 | (comparison_expression 40 | (additive_expression 41 | (multiplicative_expression 42 | (format_expression 43 | (range_expression 44 | (array_literal_expression 45 | (unary_expression 46 | (real_literal)))))))))))))) 47 | 48 | === 49 | Scientific notation 50 | === 51 | 52 | 6.022e23 53 | 54 | .12e4 55 | 56 | --- 57 | 58 | (program 59 | (statement_list 60 | (pipeline 61 | (pipeline_chain 62 | (logical_expression 63 | (bitwise_expression 64 | (comparison_expression 65 | (additive_expression 66 | (multiplicative_expression 67 | (format_expression 68 | (range_expression 69 | (array_literal_expression 70 | (unary_expression 71 | (real_literal)))))))))))) 72 | (pipeline 73 | (pipeline_chain 74 | (logical_expression 75 | (bitwise_expression 76 | (comparison_expression 77 | (additive_expression 78 | (multiplicative_expression 79 | (format_expression 80 | (range_expression 81 | (array_literal_expression 82 | (unary_expression 83 | (real_literal)))))))))))))) 84 | 85 | === 86 | Byte size suffix 87 | === 88 | 89 | 12mb 90 | 91 | 12gb 92 | 93 | --- 94 | 95 | (program 96 | (statement_list 97 | (pipeline 98 | (pipeline_chain 99 | (logical_expression 100 | (bitwise_expression 101 | (comparison_expression 102 | (additive_expression 103 | (multiplicative_expression 104 | (format_expression 105 | (range_expression 106 | (array_literal_expression 107 | (unary_expression 108 | (integer_literal 109 | (decimal_integer_literal))))))))))))) 110 | (pipeline 111 | (pipeline_chain 112 | (logical_expression 113 | (bitwise_expression 114 | (comparison_expression 115 | (additive_expression 116 | (multiplicative_expression 117 | (format_expression 118 | (range_expression 119 | (array_literal_expression 120 | (unary_expression 121 | (integer_literal 122 | (decimal_integer_literal))))))))))))))) 123 | 124 | === 125 | Integer operation 126 | === 127 | 128 | 4 + 4 - 8 129 | 130 | --- 131 | 132 | (program 133 | (statement_list 134 | (pipeline 135 | (pipeline_chain 136 | (logical_expression 137 | (bitwise_expression 138 | (comparison_expression 139 | (additive_expression 140 | (additive_expression 141 | (additive_expression 142 | (multiplicative_expression 143 | (format_expression 144 | (range_expression 145 | (array_literal_expression 146 | (unary_expression 147 | (integer_literal 148 | (decimal_integer_literal)))))))) 149 | (multiplicative_expression 150 | (format_expression 151 | (range_expression 152 | (array_literal_expression 153 | (unary_expression 154 | (integer_literal 155 | (decimal_integer_literal)))))))) 156 | (multiplicative_expression 157 | (format_expression 158 | (range_expression 159 | (array_literal_expression 160 | (unary_expression 161 | (integer_literal 162 | (decimal_integer_literal))))))))))))))) 163 | 164 | === 165 | Integer operation with negative 166 | === 167 | 168 | 4 + 4 - -8 169 | 170 | --- 171 | 172 | (program 173 | (statement_list 174 | (pipeline 175 | (pipeline_chain 176 | (logical_expression 177 | (bitwise_expression 178 | (comparison_expression 179 | (additive_expression 180 | (additive_expression 181 | (additive_expression 182 | (multiplicative_expression 183 | (format_expression 184 | (range_expression 185 | (array_literal_expression 186 | (unary_expression 187 | (integer_literal 188 | (decimal_integer_literal)))))))) 189 | (multiplicative_expression 190 | (format_expression 191 | (range_expression 192 | (array_literal_expression 193 | (unary_expression 194 | (integer_literal 195 | (decimal_integer_literal)))))))) 196 | (multiplicative_expression 197 | (format_expression 198 | (range_expression 199 | (array_literal_expression 200 | (unary_expression 201 | (expression_with_unary_operator 202 | (unary_expression 203 | (integer_literal 204 | (decimal_integer_literal))))))))))))))))) 205 | 206 | === 207 | Cast with composed expression 208 | === 209 | 210 | [char]84 + [char]8 211 | 212 | --- 213 | 214 | (program 215 | (statement_list 216 | (pipeline 217 | (pipeline_chain 218 | (logical_expression 219 | (bitwise_expression 220 | (comparison_expression 221 | (additive_expression 222 | (additive_expression 223 | (multiplicative_expression 224 | (format_expression 225 | (range_expression 226 | (array_literal_expression 227 | (unary_expression 228 | (expression_with_unary_operator 229 | (cast_expression 230 | (type_literal 231 | (type_spec 232 | (type_name 233 | (type_identifier)))) 234 | (unary_expression 235 | (integer_literal 236 | (decimal_integer_literal))))))))))) 237 | (multiplicative_expression 238 | (format_expression 239 | (range_expression 240 | (array_literal_expression 241 | (unary_expression 242 | (expression_with_unary_operator 243 | (cast_expression 244 | (type_literal 245 | (type_spec 246 | (type_name 247 | (type_identifier)))) 248 | (unary_expression 249 | (integer_literal 250 | (decimal_integer_literal)))))))))))))))))) 251 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/corpus/type.txt: -------------------------------------------------------------------------------- 1 | === 2 | Simple type expression #1 3 | === 4 | 5 | [string] 6 | 7 | --- 8 | 9 | (program 10 | (statement_list 11 | (pipeline 12 | (pipeline_chain 13 | (logical_expression 14 | (bitwise_expression 15 | (comparison_expression 16 | (additive_expression 17 | (multiplicative_expression 18 | (format_expression 19 | (range_expression 20 | (array_literal_expression 21 | (unary_expression 22 | (type_literal 23 | (type_spec 24 | (type_name 25 | (type_identifier))))))))))))))))) 26 | 27 | === 28 | Simple type expression #2 29 | === 30 | 31 | [System.Collections.ArrayList] 32 | 33 | --- 34 | 35 | (program 36 | (statement_list 37 | (pipeline 38 | (pipeline_chain 39 | (logical_expression 40 | (bitwise_expression 41 | (comparison_expression 42 | (additive_expression 43 | (multiplicative_expression 44 | (format_expression 45 | (range_expression 46 | (array_literal_expression 47 | (unary_expression 48 | (type_literal 49 | (type_spec 50 | (type_name 51 | (type_name 52 | (type_name 53 | (type_identifier)) 54 | (type_identifier)) 55 | (type_identifier))))))))))))))))) 56 | 57 | === 58 | Array type expression #1 59 | === 60 | 61 | [int[]] 62 | 63 | --- 64 | 65 | (program 66 | (statement_list 67 | (pipeline 68 | (pipeline_chain 69 | (logical_expression 70 | (bitwise_expression 71 | (comparison_expression 72 | (additive_expression 73 | (multiplicative_expression 74 | (format_expression 75 | (range_expression 76 | (array_literal_expression 77 | (unary_expression 78 | (type_literal 79 | (type_spec 80 | (array_type_name 81 | (type_name 82 | (type_identifier)))))))))))))))))) 83 | 84 | === 85 | Array type expression #1 86 | === 87 | 88 | [System.DateTime[]] 89 | 90 | --- 91 | 92 | (program 93 | (statement_list 94 | (pipeline 95 | (pipeline_chain 96 | (logical_expression 97 | (bitwise_expression 98 | (comparison_expression 99 | (additive_expression 100 | (multiplicative_expression 101 | (format_expression 102 | (range_expression 103 | (array_literal_expression 104 | (unary_expression 105 | (type_literal 106 | (type_spec 107 | (array_type_name 108 | (type_name 109 | (type_name 110 | (type_identifier)) 111 | (type_identifier)))))))))))))))))) 112 | 113 | === 114 | Generic type expression #1 115 | === 116 | 117 | [MyType[psobject]] 118 | 119 | --- 120 | 121 | (program 122 | (statement_list 123 | (pipeline 124 | (pipeline_chain 125 | (logical_expression 126 | (bitwise_expression 127 | (comparison_expression 128 | (additive_expression 129 | (multiplicative_expression 130 | (format_expression 131 | (range_expression 132 | (array_literal_expression 133 | (unary_expression 134 | (type_literal 135 | (type_spec 136 | (generic_type_name 137 | (type_name 138 | (type_identifier))) 139 | (generic_type_arguments 140 | (type_spec 141 | (type_name 142 | (type_identifier))))))))))))))))))) 143 | 144 | === 145 | Generic type expression #2 146 | === 147 | 148 | [System.Collections.Generic.Dictionary[string, System.IO.FileInfo]] 149 | 150 | --- 151 | 152 | (program 153 | (statement_list 154 | (pipeline 155 | (pipeline_chain 156 | (logical_expression 157 | (bitwise_expression 158 | (comparison_expression 159 | (additive_expression 160 | (multiplicative_expression 161 | (format_expression 162 | (range_expression 163 | (array_literal_expression 164 | (unary_expression 165 | (type_literal 166 | (type_spec 167 | (generic_type_name 168 | (type_name 169 | (type_name 170 | (type_name 171 | (type_name 172 | (type_identifier)) 173 | (type_identifier)) 174 | (type_identifier)) 175 | (type_identifier))) 176 | (generic_type_arguments 177 | (type_spec 178 | (type_name 179 | (type_identifier))) 180 | (type_spec 181 | (type_name 182 | (type_name 183 | (type_name 184 | (type_identifier)) 185 | (type_identifier)) 186 | (type_identifier))))))))))))))))))) 187 | 188 | === 189 | Complex type expression 190 | === 191 | 192 | [System.Collections.Generic.Dictionary[int[], System.Collections.Generic.List[string[]]]] 193 | 194 | --- 195 | 196 | (program 197 | (statement_list 198 | (pipeline 199 | (pipeline_chain 200 | (logical_expression 201 | (bitwise_expression 202 | (comparison_expression 203 | (additive_expression 204 | (multiplicative_expression 205 | (format_expression 206 | (range_expression 207 | (array_literal_expression 208 | (unary_expression 209 | (type_literal 210 | (type_spec 211 | (generic_type_name 212 | (type_name 213 | (type_name 214 | (type_name 215 | (type_name 216 | (type_identifier)) 217 | (type_identifier)) 218 | (type_identifier)) 219 | (type_identifier))) 220 | (generic_type_arguments 221 | (type_spec 222 | (array_type_name 223 | (type_name 224 | (type_identifier)))) 225 | (type_spec 226 | (generic_type_name 227 | (type_name 228 | (type_name 229 | (type_name 230 | (type_name 231 | (type_identifier)) 232 | (type_identifier)) 233 | (type_identifier)) 234 | (type_identifier))) 235 | (generic_type_arguments 236 | (type_spec 237 | (array_type_name 238 | (type_name 239 | (type_identifier)))))))))))))))))))))) 240 | 241 | === 242 | Type-attributed variable 243 | === 244 | 245 | [string]$str 246 | 247 | --- 248 | 249 | (program 250 | (statement_list 251 | (pipeline 252 | (pipeline_chain 253 | (logical_expression 254 | (bitwise_expression 255 | (comparison_expression 256 | (additive_expression 257 | (multiplicative_expression 258 | (format_expression 259 | (range_expression 260 | (array_literal_expression 261 | (unary_expression 262 | (expression_with_unary_operator 263 | (cast_expression 264 | (type_literal 265 | (type_spec 266 | (type_name 267 | (type_identifier)))) 268 | (unary_expression 269 | (variable))))))))))))))))) 270 | -------------------------------------------------------------------------------- /test/corpus/obfuscated.txt: -------------------------------------------------------------------------------- 1 | === 2 | Obfuscated command with eval and format 3 | === 4 | 5 | ${vjOj`Q`gX} = $(&("{0}{1}{2}"-f'w','h','oami')) 6 | 7 | --- 8 | 9 | (program 10 | (statement_list 11 | (pipeline 12 | (assignment_expression 13 | (left_assignment_expression 14 | (logical_expression 15 | (bitwise_expression 16 | (comparison_expression 17 | (additive_expression 18 | (multiplicative_expression 19 | (format_expression 20 | (range_expression 21 | (array_literal_expression 22 | (unary_expression 23 | (variable 24 | (braced_variable)))))))))))) 25 | (assignement_operator) 26 | value: (pipeline 27 | (pipeline_chain 28 | (logical_expression 29 | (bitwise_expression 30 | (comparison_expression 31 | (additive_expression 32 | (multiplicative_expression 33 | (format_expression 34 | (range_expression 35 | (array_literal_expression 36 | (unary_expression 37 | (sub_expression 38 | statements: (statement_list 39 | (pipeline 40 | (pipeline_chain 41 | (command 42 | (command_invokation_operator) 43 | command_name: (command_name_expr 44 | (parenthesized_expression 45 | (pipeline 46 | (pipeline_chain 47 | (logical_expression 48 | (bitwise_expression 49 | (comparison_expression 50 | (additive_expression 51 | (multiplicative_expression 52 | (format_expression 53 | (format_expression 54 | (range_expression 55 | (array_literal_expression 56 | (unary_expression 57 | (string_literal 58 | (expandable_string_literal)))))) 59 | (format_operator) 60 | (range_expression 61 | (array_literal_expression 62 | (unary_expression 63 | (string_literal 64 | (verbatim_string_characters))) 65 | (unary_expression 66 | (string_literal 67 | (verbatim_string_characters))) 68 | (unary_expression 69 | (string_literal 70 | (verbatim_string_characters))))))))))))))))))))))))))))))))))) 71 | 72 | === 73 | Obfuscated decoded using base64 native method 74 | === 75 | 76 | Invoke-Expression ([System.Text.Encoding]::Unicode.GetString(([convert]::FromBase64String('VwByAGkAdABlAC0ATwB1AHQAcAB1AHQAIAAiAFQAcgB5ACAASABhAHIAZABlAHIAIgA=')))) 77 | 78 | --- 79 | 80 | (program 81 | (statement_list 82 | (pipeline 83 | (pipeline_chain 84 | (command 85 | (command_name) 86 | (command_elements 87 | (command_argument_sep) 88 | (array_literal_expression 89 | (unary_expression 90 | (parenthesized_expression 91 | (pipeline 92 | (pipeline_chain 93 | (logical_expression 94 | (bitwise_expression 95 | (comparison_expression 96 | (additive_expression 97 | (multiplicative_expression 98 | (format_expression 99 | (range_expression 100 | (array_literal_expression 101 | (unary_expression 102 | (invokation_expression 103 | (member_access 104 | (type_literal 105 | (type_spec 106 | (type_name 107 | (type_name 108 | (type_name 109 | (type_identifier)) 110 | (type_identifier)) 111 | (type_identifier)))) 112 | (member_name 113 | (simple_name))) 114 | (member_name 115 | (simple_name)) 116 | (argument_list 117 | (argument_expression_list 118 | (argument_expression 119 | (logical_argument_expression 120 | (bitwise_argument_expression 121 | (comparison_argument_expression 122 | (additive_argument_expression 123 | (multiplicative_argument_expression 124 | (format_argument_expression 125 | (range_argument_expression 126 | (unary_expression 127 | (parenthesized_expression 128 | (pipeline 129 | (pipeline_chain 130 | (logical_expression 131 | (bitwise_expression 132 | (comparison_expression 133 | (additive_expression 134 | (multiplicative_expression 135 | (format_expression 136 | (range_expression 137 | (array_literal_expression 138 | (unary_expression 139 | (invokation_expression 140 | (type_literal 141 | (type_spec 142 | (type_name 143 | (type_identifier)))) 144 | (member_name 145 | (simple_name)) 146 | (argument_list 147 | (argument_expression_list 148 | (argument_expression 149 | (logical_argument_expression 150 | (bitwise_argument_expression 151 | (comparison_argument_expression 152 | (additive_argument_expression 153 | (multiplicative_argument_expression 154 | (format_argument_expression 155 | (range_argument_expression 156 | (unary_expression 157 | (string_literal 158 | (verbatim_string_characters)))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 159 | 160 | 161 | === 162 | Obfuscated command 163 | === 164 | 165 | &(Get-Command i????e-rest*) 166 | 167 | --- 168 | 169 | (program 170 | (statement_list 171 | (pipeline 172 | (pipeline_chain 173 | (command 174 | (command_invokation_operator) 175 | (command_name_expr 176 | (parenthesized_expression 177 | (pipeline 178 | (pipeline_chain 179 | (command 180 | (command_name) 181 | (command_elements 182 | (command_argument_sep) 183 | (generic_token)))))))))))) 184 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/corpus/strings.txt: -------------------------------------------------------------------------------- 1 | === 2 | Strings : expandable 3 | === 4 | 5 | "foo" 6 | 7 | --- 8 | 9 | (program 10 | (statement_list 11 | (pipeline 12 | (pipeline_chain 13 | (logical_expression 14 | (bitwise_expression 15 | (comparison_expression 16 | (additive_expression 17 | (multiplicative_expression 18 | (format_expression 19 | (range_expression 20 | (array_literal_expression 21 | (unary_expression 22 | (string_literal 23 | (expandable_string_literal))))))))))))))) 24 | 25 | === 26 | Strings : empty expandable 27 | === 28 | 29 | "" 30 | 31 | --- 32 | 33 | (program 34 | (statement_list 35 | (pipeline 36 | (pipeline_chain 37 | (logical_expression 38 | (bitwise_expression 39 | (comparison_expression 40 | (additive_expression 41 | (multiplicative_expression 42 | (format_expression 43 | (range_expression 44 | (array_literal_expression 45 | (unary_expression 46 | (string_literal 47 | (expandable_string_literal))))))))))))))) 48 | 49 | === 50 | Strings : expandle with braced variable 51 | === 52 | 53 | "foo ${toto}" 54 | 55 | --- 56 | 57 | (program 58 | (statement_list 59 | (pipeline 60 | (pipeline_chain 61 | (logical_expression 62 | (bitwise_expression 63 | (comparison_expression 64 | (additive_expression 65 | (multiplicative_expression 66 | (format_expression 67 | (range_expression 68 | (array_literal_expression 69 | (unary_expression 70 | (string_literal 71 | (expandable_string_literal 72 | (variable 73 | (braced_variable))))))))))))))))) 74 | 75 | === 76 | Strings : expandle with subexpression 77 | === 78 | 79 | "foo $(iex)" 80 | 81 | --- 82 | 83 | (program 84 | (statement_list 85 | (pipeline 86 | (pipeline_chain 87 | (logical_expression 88 | (bitwise_expression 89 | (comparison_expression 90 | (additive_expression 91 | (multiplicative_expression 92 | (format_expression 93 | (range_expression 94 | (array_literal_expression 95 | (unary_expression 96 | (string_literal 97 | (expandable_string_literal 98 | (sub_expression 99 | (statement_list 100 | (pipeline 101 | (pipeline_chain 102 | (command 103 | (command_name))))))))))))))))))))) 104 | 105 | === 106 | Strings : verbatim 107 | === 108 | 109 | 'foo' 110 | 111 | --- 112 | 113 | (program 114 | (statement_list 115 | (pipeline 116 | (pipeline_chain 117 | (logical_expression 118 | (bitwise_expression 119 | (comparison_expression 120 | (additive_expression 121 | (multiplicative_expression 122 | (format_expression 123 | (range_expression 124 | (array_literal_expression 125 | (unary_expression 126 | (string_literal 127 | (verbatim_string_characters))))))))))))))) 128 | 129 | === 130 | Strings : verbatim empty 131 | === 132 | 133 | '' 134 | 135 | --- 136 | 137 | (program 138 | (statement_list 139 | (pipeline 140 | (pipeline_chain 141 | (logical_expression 142 | (bitwise_expression 143 | (comparison_expression 144 | (additive_expression 145 | (multiplicative_expression 146 | (format_expression 147 | (range_expression 148 | (array_literal_expression 149 | (unary_expression 150 | (string_literal 151 | (verbatim_string_characters))))))))))))))) 152 | 153 | === 154 | Strings : verbatim here string 155 | === 156 | 157 | @' 158 | toto 159 | '@ 160 | 161 | --- 162 | 163 | (program 164 | (statement_list 165 | (pipeline 166 | (pipeline_chain 167 | (logical_expression 168 | (bitwise_expression 169 | (comparison_expression 170 | (additive_expression 171 | (multiplicative_expression 172 | (format_expression 173 | (range_expression 174 | (array_literal_expression 175 | (unary_expression 176 | (string_literal 177 | (verbatim_here_string_characters))))))))))))))) 178 | 179 | === 180 | Strings : verbatim here string empty 181 | === 182 | 183 | @' 184 | 185 | '@ 186 | 187 | --- 188 | 189 | (program 190 | (statement_list 191 | (pipeline 192 | (pipeline_chain 193 | (logical_expression 194 | (bitwise_expression 195 | (comparison_expression 196 | (additive_expression 197 | (multiplicative_expression 198 | (format_expression 199 | (range_expression 200 | (array_literal_expression 201 | (unary_expression 202 | (string_literal 203 | (verbatim_here_string_characters))))))))))))))) 204 | 205 | === 206 | Strings : expandle here string 207 | === 208 | 209 | @" 210 | `$toto 211 | "@ 212 | 213 | --- 214 | 215 | (program 216 | (statement_list 217 | (pipeline 218 | (pipeline_chain 219 | (logical_expression 220 | (bitwise_expression 221 | (comparison_expression 222 | (additive_expression 223 | (multiplicative_expression 224 | (format_expression 225 | (range_expression 226 | (array_literal_expression 227 | (unary_expression 228 | (string_literal 229 | (expandable_here_string_literal))))))))))))))) 230 | 231 | === 232 | Strings : expandle here string with var 233 | === 234 | 235 | @" 236 | $toto 237 | "@ 238 | 239 | --- 240 | 241 | (program 242 | (statement_list 243 | (pipeline 244 | (pipeline_chain 245 | (logical_expression 246 | (bitwise_expression 247 | (comparison_expression 248 | (additive_expression 249 | (multiplicative_expression 250 | (format_expression 251 | (range_expression 252 | (array_literal_expression 253 | (unary_expression 254 | (string_literal 255 | (expandable_here_string_literal 256 | (variable)))))))))))))))) 257 | 258 | === 259 | Strings : expandle here string empty 260 | === 261 | 262 | @" 263 | 264 | "@ 265 | 266 | --- 267 | 268 | (program 269 | (statement_list 270 | (pipeline 271 | (pipeline_chain 272 | (logical_expression 273 | (bitwise_expression 274 | (comparison_expression 275 | (additive_expression 276 | (multiplicative_expression 277 | (format_expression 278 | (range_expression 279 | (array_literal_expression 280 | (unary_expression 281 | (string_literal 282 | (expandable_here_string_literal))))))))))))))) 283 | 284 | 285 | === 286 | Strings : escape variable and print dollar 287 | === 288 | 289 | "`$w$ is valid" 290 | 291 | --- 292 | 293 | (program 294 | (statement_list 295 | (pipeline 296 | (pipeline_chain 297 | (logical_expression 298 | (bitwise_expression 299 | (comparison_expression 300 | (additive_expression 301 | (multiplicative_expression 302 | (format_expression 303 | (range_expression 304 | (array_literal_expression 305 | (unary_expression 306 | (string_literal 307 | (expandable_string_literal))))))))))))))) 308 | 309 | 310 | === 311 | Strings : concat var content and dollar 312 | === 313 | 314 | "$w$ is valid" 315 | 316 | --- 317 | 318 | (program 319 | (statement_list 320 | (pipeline 321 | (pipeline_chain 322 | (logical_expression 323 | (bitwise_expression 324 | (comparison_expression 325 | (additive_expression 326 | (multiplicative_expression 327 | (format_expression 328 | (range_expression 329 | (array_literal_expression 330 | (unary_expression 331 | (string_literal 332 | (expandable_string_literal 333 | (variable)))))))))))))))) 334 | 335 | === 336 | Strings : Single-quoted string 337 | === 338 | 339 | 'Hello, &!@#(&)!I_@U!JJ!EN@!' 340 | 341 | --- 342 | 343 | (program 344 | (statement_list 345 | (pipeline 346 | (pipeline_chain 347 | (logical_expression 348 | (bitwise_expression 349 | (comparison_expression 350 | (additive_expression 351 | (multiplicative_expression 352 | (format_expression 353 | (range_expression 354 | (array_literal_expression 355 | (unary_expression 356 | (string_literal 357 | (verbatim_string_characters))))))))))))))) 358 | 359 | === 360 | Strings : Double-quoted string 361 | === 362 | 363 | "Hello friend! !@!_(@FK@L!:D $null 366 | 367 | --- 368 | 369 | (program 370 | (statement_list 371 | (pipeline 372 | (pipeline_chain 373 | (command 374 | (command_name) 375 | (command_elements 376 | (command_argument_sep) 377 | (array_literal_expression 378 | (unary_expression 379 | (variable))) 380 | (command_argument_sep) 381 | (command_parameter) 382 | (command_argument_sep) 383 | (generic_token) 384 | (command_argument_sep) 385 | (command_parameter) 386 | (command_argument_sep) 387 | (command_parameter) 388 | (command_argument_sep) 389 | (array_literal_expression 390 | (unary_expression 391 | (variable))) 392 | (command_argument_sep) 393 | (redirection 394 | (file_redirection_operator) 395 | (redirected_file_name 396 | (command_argument_sep) 397 | (array_literal_expression 398 | (unary_expression 399 | (variable))))))))))) 400 | 401 | === 402 | Diff between argument and array literal 403 | === 404 | 405 | $rih2ymeurlleflu = & "New-Object" "System.Net.Sockets.TCPClient"("127.0.0.1", 4444) 406 | 407 | --- 408 | 409 | (program 410 | (statement_list 411 | (pipeline 412 | (assignment_expression 413 | (left_assignment_expression 414 | (logical_expression 415 | (bitwise_expression 416 | (comparison_expression 417 | (additive_expression 418 | (multiplicative_expression 419 | (format_expression 420 | (range_expression 421 | (array_literal_expression 422 | (unary_expression 423 | (variable))))))))))) 424 | (assignement_operator) 425 | value: (pipeline 426 | (pipeline_chain 427 | (command 428 | (command_invokation_operator) 429 | command_name: (command_name_expr 430 | (string_literal 431 | (expandable_string_literal))) 432 | command_elements: (command_elements 433 | (command_argument_sep) 434 | (array_literal_expression 435 | (unary_expression 436 | (string_literal 437 | (expandable_string_literal)))) 438 | (argument_list 439 | argument_expression_list: (argument_expression_list 440 | (argument_expression 441 | (logical_argument_expression 442 | (bitwise_argument_expression 443 | (comparison_argument_expression 444 | (additive_argument_expression 445 | (multiplicative_argument_expression 446 | (format_argument_expression 447 | (range_argument_expression 448 | (unary_expression 449 | (string_literal 450 | (expandable_string_literal))))))))))) 451 | (argument_expression 452 | (logical_argument_expression 453 | (bitwise_argument_expression 454 | (comparison_argument_expression 455 | (additive_argument_expression 456 | (multiplicative_argument_expression 457 | (format_argument_expression 458 | (range_argument_expression 459 | (unary_expression 460 | (integer_literal 461 | (decimal_integer_literal))))))))))))))))))))) 462 | 463 | === 464 | Cmdlet that start with a keyword 465 | === 466 | 467 | download toto 468 | 469 | --- 470 | 471 | (program 472 | (statement_list 473 | (pipeline 474 | (pipeline_chain 475 | (command 476 | command_name: (command_name) 477 | command_elements: (command_elements 478 | (command_argument_sep) 479 | (generic_token))))))) 480 | 481 | 482 | === 483 | Cmdlet with parenthesized_expression as parameter without any white space 484 | === 485 | 486 | iex("calc.exe") 487 | 488 | --- 489 | 490 | (program 491 | (statement_list 492 | (pipeline 493 | (pipeline_chain 494 | (command 495 | command_name: (command_name) 496 | command_elements: (command_elements 497 | (parenthesized_expression 498 | (pipeline 499 | (pipeline_chain 500 | (logical_expression 501 | (bitwise_expression 502 | (comparison_expression 503 | (additive_expression 504 | (multiplicative_expression 505 | (format_expression 506 | (range_expression 507 | (array_literal_expression 508 | (unary_expression 509 | (string_literal 510 | (expandable_string_literal)))))))))))))))))))) 511 | 512 | === 513 | Cmdlet that start with a keyword 2 514 | === 515 | 516 | Exit-test toto 517 | 518 | --- 519 | 520 | (program 521 | (statement_list 522 | (pipeline 523 | (pipeline_chain 524 | (command 525 | command_name: (command_name) 526 | command_elements: (command_elements 527 | (command_argument_sep) 528 | (generic_token))))))) 529 | -------------------------------------------------------------------------------- /test/corpus/operators.txt: -------------------------------------------------------------------------------- 1 | === 2 | Simple binary operator 1 3 | === 4 | 5 | $a -eq $a 6 | 7 | --- 8 | 9 | (program 10 | (statement_list 11 | (pipeline 12 | (pipeline_chain 13 | (logical_expression 14 | (bitwise_expression 15 | (comparison_expression 16 | (comparison_expression 17 | (additive_expression 18 | (multiplicative_expression 19 | (format_expression 20 | (range_expression 21 | (array_literal_expression 22 | (unary_expression 23 | (variable)))))))) 24 | (comparison_operator) 25 | (additive_expression 26 | (multiplicative_expression 27 | (format_expression 28 | (range_expression 29 | (array_literal_expression 30 | (unary_expression 31 | (variable)))))))))))))) 32 | 33 | === 34 | Simple binary operator 2 35 | === 36 | 37 | $a -ne $a 38 | 39 | --- 40 | 41 | (program 42 | (statement_list 43 | (pipeline 44 | (pipeline_chain 45 | (logical_expression 46 | (bitwise_expression 47 | (comparison_expression 48 | (comparison_expression 49 | (additive_expression 50 | (multiplicative_expression 51 | (format_expression 52 | (range_expression 53 | (array_literal_expression 54 | (unary_expression 55 | (variable)))))))) 56 | (comparison_operator) 57 | (additive_expression 58 | (multiplicative_expression 59 | (format_expression 60 | (range_expression 61 | (array_literal_expression 62 | (unary_expression 63 | (variable)))))))))))))) 64 | 65 | === 66 | Simple binary operator 3 67 | === 68 | 69 | $a -ge $a 70 | 71 | --- 72 | 73 | (program 74 | (statement_list 75 | (pipeline 76 | (pipeline_chain 77 | (logical_expression 78 | (bitwise_expression 79 | (comparison_expression 80 | (comparison_expression 81 | (additive_expression 82 | (multiplicative_expression 83 | (format_expression 84 | (range_expression 85 | (array_literal_expression 86 | (unary_expression 87 | (variable)))))))) 88 | (comparison_operator) 89 | (additive_expression 90 | (multiplicative_expression 91 | (format_expression 92 | (range_expression 93 | (array_literal_expression 94 | (unary_expression 95 | (variable)))))))))))))) 96 | 97 | 98 | === 99 | Simple binary operator 4 100 | === 101 | 102 | $a -gt $a 103 | 104 | --- 105 | 106 | (program 107 | (statement_list 108 | (pipeline 109 | (pipeline_chain 110 | (logical_expression 111 | (bitwise_expression 112 | (comparison_expression 113 | (comparison_expression 114 | (additive_expression 115 | (multiplicative_expression 116 | (format_expression 117 | (range_expression 118 | (array_literal_expression 119 | (unary_expression 120 | (variable)))))))) 121 | (comparison_operator) 122 | (additive_expression 123 | (multiplicative_expression 124 | (format_expression 125 | (range_expression 126 | (array_literal_expression 127 | (unary_expression 128 | (variable)))))))))))))) 129 | 130 | 131 | === 132 | Simple binary operator 5 133 | === 134 | 135 | $a -lt $a 136 | 137 | --- 138 | 139 | (program 140 | (statement_list 141 | (pipeline 142 | (pipeline_chain 143 | (logical_expression 144 | (bitwise_expression 145 | (comparison_expression 146 | (comparison_expression 147 | (additive_expression 148 | (multiplicative_expression 149 | (format_expression 150 | (range_expression 151 | (array_literal_expression 152 | (unary_expression 153 | (variable)))))))) 154 | (comparison_operator) 155 | (additive_expression 156 | (multiplicative_expression 157 | (format_expression 158 | (range_expression 159 | (array_literal_expression 160 | (unary_expression 161 | (variable)))))))))))))) 162 | 163 | 164 | === 165 | Simple binary operator 6 166 | === 167 | 168 | $a -le $a 169 | 170 | --- 171 | 172 | (program 173 | (statement_list 174 | (pipeline 175 | (pipeline_chain 176 | (logical_expression 177 | (bitwise_expression 178 | (comparison_expression 179 | (comparison_expression 180 | (additive_expression 181 | (multiplicative_expression 182 | (format_expression 183 | (range_expression 184 | (array_literal_expression 185 | (unary_expression 186 | (variable)))))))) 187 | (comparison_operator) 188 | (additive_expression 189 | (multiplicative_expression 190 | (format_expression 191 | (range_expression 192 | (array_literal_expression 193 | (unary_expression 194 | (variable)))))))))))))) 195 | 196 | 197 | === 198 | Simple binary operator 7 199 | === 200 | 201 | $a -like $a 202 | 203 | --- 204 | 205 | (program 206 | (statement_list 207 | (pipeline 208 | (pipeline_chain 209 | (logical_expression 210 | (bitwise_expression 211 | (comparison_expression 212 | (comparison_expression 213 | (additive_expression 214 | (multiplicative_expression 215 | (format_expression 216 | (range_expression 217 | (array_literal_expression 218 | (unary_expression 219 | (variable)))))))) 220 | (comparison_operator) 221 | (additive_expression 222 | (multiplicative_expression 223 | (format_expression 224 | (range_expression 225 | (array_literal_expression 226 | (unary_expression 227 | (variable)))))))))))))) 228 | 229 | 230 | === 231 | Simple binary operator 8 232 | === 233 | 234 | $a -notlike $a 235 | 236 | --- 237 | 238 | (program 239 | (statement_list 240 | (pipeline 241 | (pipeline_chain 242 | (logical_expression 243 | (bitwise_expression 244 | (comparison_expression 245 | (comparison_expression 246 | (additive_expression 247 | (multiplicative_expression 248 | (format_expression 249 | (range_expression 250 | (array_literal_expression 251 | (unary_expression 252 | (variable)))))))) 253 | (comparison_operator) 254 | (additive_expression 255 | (multiplicative_expression 256 | (format_expression 257 | (range_expression 258 | (array_literal_expression 259 | (unary_expression 260 | (variable)))))))))))))) 261 | 262 | 263 | === 264 | Simple binary operator 9 265 | === 266 | 267 | $a -match $a 268 | 269 | --- 270 | 271 | (program 272 | (statement_list 273 | (pipeline 274 | (pipeline_chain 275 | (logical_expression 276 | (bitwise_expression 277 | (comparison_expression 278 | (comparison_expression 279 | (additive_expression 280 | (multiplicative_expression 281 | (format_expression 282 | (range_expression 283 | (array_literal_expression 284 | (unary_expression 285 | (variable)))))))) 286 | (comparison_operator) 287 | (additive_expression 288 | (multiplicative_expression 289 | (format_expression 290 | (range_expression 291 | (array_literal_expression 292 | (unary_expression 293 | (variable)))))))))))))) 294 | 295 | 296 | === 297 | Simple binary operator 10 298 | === 299 | 300 | $a -notmatch $a 301 | 302 | --- 303 | 304 | (program 305 | (statement_list 306 | (pipeline 307 | (pipeline_chain 308 | (logical_expression 309 | (bitwise_expression 310 | (comparison_expression 311 | (comparison_expression 312 | (additive_expression 313 | (multiplicative_expression 314 | (format_expression 315 | (range_expression 316 | (array_literal_expression 317 | (unary_expression 318 | (variable)))))))) 319 | (comparison_operator) 320 | (additive_expression 321 | (multiplicative_expression 322 | (format_expression 323 | (range_expression 324 | (array_literal_expression 325 | (unary_expression 326 | (variable)))))))))))))) 327 | 328 | 329 | === 330 | Simple binary operator 11 331 | === 332 | 333 | $a -replace $a 334 | 335 | --- 336 | 337 | (program 338 | (statement_list 339 | (pipeline 340 | (pipeline_chain 341 | (logical_expression 342 | (bitwise_expression 343 | (comparison_expression 344 | (comparison_expression 345 | (additive_expression 346 | (multiplicative_expression 347 | (format_expression 348 | (range_expression 349 | (array_literal_expression 350 | (unary_expression 351 | (variable)))))))) 352 | (comparison_operator) 353 | (additive_expression 354 | (multiplicative_expression 355 | (format_expression 356 | (range_expression 357 | (array_literal_expression 358 | (unary_expression 359 | (variable)))))))))))))) 360 | 361 | 362 | === 363 | Simple binary operator 12 364 | === 365 | 366 | $a -contains $a 367 | 368 | --- 369 | 370 | (program 371 | (statement_list 372 | (pipeline 373 | (pipeline_chain 374 | (logical_expression 375 | (bitwise_expression 376 | (comparison_expression 377 | (comparison_expression 378 | (additive_expression 379 | (multiplicative_expression 380 | (format_expression 381 | (range_expression 382 | (array_literal_expression 383 | (unary_expression 384 | (variable)))))))) 385 | (comparison_operator) 386 | (additive_expression 387 | (multiplicative_expression 388 | (format_expression 389 | (range_expression 390 | (array_literal_expression 391 | (unary_expression 392 | (variable)))))))))))))) 393 | 394 | 395 | === 396 | Simple binary operator 13 397 | === 398 | 399 | $a -notcontains $a 400 | 401 | --- 402 | 403 | (program 404 | (statement_list 405 | (pipeline 406 | (pipeline_chain 407 | (logical_expression 408 | (bitwise_expression 409 | (comparison_expression 410 | (comparison_expression 411 | (additive_expression 412 | (multiplicative_expression 413 | (format_expression 414 | (range_expression 415 | (array_literal_expression 416 | (unary_expression 417 | (variable)))))))) 418 | (comparison_operator) 419 | (additive_expression 420 | (multiplicative_expression 421 | (format_expression 422 | (range_expression 423 | (array_literal_expression 424 | (unary_expression 425 | (variable)))))))))))))) 426 | 427 | 428 | === 429 | Simple binary operator 14 430 | === 431 | 432 | $a -in $a 433 | 434 | --- 435 | 436 | (program 437 | (statement_list 438 | (pipeline 439 | (pipeline_chain 440 | (logical_expression 441 | (bitwise_expression 442 | (comparison_expression 443 | (comparison_expression 444 | (additive_expression 445 | (multiplicative_expression 446 | (format_expression 447 | (range_expression 448 | (array_literal_expression 449 | (unary_expression 450 | (variable)))))))) 451 | (comparison_operator) 452 | (additive_expression 453 | (multiplicative_expression 454 | (format_expression 455 | (range_expression 456 | (array_literal_expression 457 | (unary_expression 458 | (variable)))))))))))))) 459 | 460 | 461 | === 462 | Simple binary operator 15 463 | === 464 | 465 | $a -notin $a 466 | 467 | --- 468 | 469 | (program 470 | (statement_list 471 | (pipeline 472 | (pipeline_chain 473 | (logical_expression 474 | (bitwise_expression 475 | (comparison_expression 476 | (comparison_expression 477 | (additive_expression 478 | (multiplicative_expression 479 | (format_expression 480 | (range_expression 481 | (array_literal_expression 482 | (unary_expression 483 | (variable)))))))) 484 | (comparison_operator) 485 | (additive_expression 486 | (multiplicative_expression 487 | (format_expression 488 | (range_expression 489 | (array_literal_expression 490 | (unary_expression 491 | (variable)))))))))))))) 492 | 493 | 494 | === 495 | Simple binary operator 16 496 | === 497 | 498 | $a -split $a 499 | 500 | --- 501 | 502 | (program 503 | (statement_list 504 | (pipeline 505 | (pipeline_chain 506 | (logical_expression 507 | (bitwise_expression 508 | (comparison_expression 509 | (comparison_expression 510 | (additive_expression 511 | (multiplicative_expression 512 | (format_expression 513 | (range_expression 514 | (array_literal_expression 515 | (unary_expression 516 | (variable)))))))) 517 | (comparison_operator) 518 | (additive_expression 519 | (multiplicative_expression 520 | (format_expression 521 | (range_expression 522 | (array_literal_expression 523 | (unary_expression 524 | (variable)))))))))))))) 525 | 526 | 527 | === 528 | Simple binary operator 17 529 | === 530 | 531 | $a -join $a 532 | 533 | --- 534 | 535 | (program 536 | (statement_list 537 | (pipeline 538 | (pipeline_chain 539 | (logical_expression 540 | (bitwise_expression 541 | (comparison_expression 542 | (comparison_expression 543 | (additive_expression 544 | (multiplicative_expression 545 | (format_expression 546 | (range_expression 547 | (array_literal_expression 548 | (unary_expression 549 | (variable)))))))) 550 | (comparison_operator) 551 | (additive_expression 552 | (multiplicative_expression 553 | (format_expression 554 | (range_expression 555 | (array_literal_expression 556 | (unary_expression 557 | (variable)))))))))))))) 558 | 559 | 560 | === 561 | Simple binary operator 18 562 | === 563 | 564 | $a -is $a 565 | 566 | --- 567 | 568 | (program 569 | (statement_list 570 | (pipeline 571 | (pipeline_chain 572 | (logical_expression 573 | (bitwise_expression 574 | (comparison_expression 575 | (comparison_expression 576 | (additive_expression 577 | (multiplicative_expression 578 | (format_expression 579 | (range_expression 580 | (array_literal_expression 581 | (unary_expression 582 | (variable)))))))) 583 | (comparison_operator) 584 | (additive_expression 585 | (multiplicative_expression 586 | (format_expression 587 | (range_expression 588 | (array_literal_expression 589 | (unary_expression 590 | (variable)))))))))))))) 591 | 592 | 593 | === 594 | Simple binary operator 19 595 | === 596 | 597 | $a -isnot $a 598 | 599 | --- 600 | 601 | (program 602 | (statement_list 603 | (pipeline 604 | (pipeline_chain 605 | (logical_expression 606 | (bitwise_expression 607 | (comparison_expression 608 | (comparison_expression 609 | (additive_expression 610 | (multiplicative_expression 611 | (format_expression 612 | (range_expression 613 | (array_literal_expression 614 | (unary_expression 615 | (variable)))))))) 616 | (comparison_operator) 617 | (additive_expression 618 | (multiplicative_expression 619 | (format_expression 620 | (range_expression 621 | (array_literal_expression 622 | (unary_expression 623 | (variable)))))))))))))) 624 | 625 | 626 | === 627 | Simple binary operator 20 628 | === 629 | 630 | $a -as $a 631 | 632 | --- 633 | 634 | (program 635 | (statement_list 636 | (pipeline 637 | (pipeline_chain 638 | (logical_expression 639 | (bitwise_expression 640 | (comparison_expression 641 | (comparison_expression 642 | (additive_expression 643 | (multiplicative_expression 644 | (format_expression 645 | (range_expression 646 | (array_literal_expression 647 | (unary_expression 648 | (variable)))))))) 649 | (comparison_operator) 650 | (additive_expression 651 | (multiplicative_expression 652 | (format_expression 653 | (range_expression 654 | (array_literal_expression 655 | (unary_expression 656 | (variable)))))))))))))) 657 | -------------------------------------------------------------------------------- /test/corpus/variables.txt: -------------------------------------------------------------------------------- 1 | === 2 | Variable : Direct assignment 3 | === 4 | 5 | $MyVariable = 1, 2, 3 6 | 7 | $Path = "C:\Windows\System32" 8 | 9 | --- 10 | 11 | (program 12 | (statement_list 13 | (pipeline 14 | (assignment_expression 15 | (left_assignment_expression 16 | (logical_expression 17 | (bitwise_expression 18 | (comparison_expression 19 | (additive_expression 20 | (multiplicative_expression 21 | (format_expression 22 | (range_expression 23 | (array_literal_expression 24 | (unary_expression 25 | (variable))))))))))) 26 | (assignement_operator) 27 | (pipeline 28 | (pipeline_chain 29 | (logical_expression 30 | (bitwise_expression 31 | (comparison_expression 32 | (additive_expression 33 | (multiplicative_expression 34 | (format_expression 35 | (range_expression 36 | (array_literal_expression 37 | (unary_expression 38 | (integer_literal 39 | (decimal_integer_literal))) 40 | (unary_expression 41 | (integer_literal 42 | (decimal_integer_literal))) 43 | (unary_expression 44 | (integer_literal 45 | (decimal_integer_literal))))))))))))))) 46 | (pipeline 47 | (assignment_expression 48 | (left_assignment_expression 49 | (logical_expression 50 | (bitwise_expression 51 | (comparison_expression 52 | (additive_expression 53 | (multiplicative_expression 54 | (format_expression 55 | (range_expression 56 | (array_literal_expression 57 | (unary_expression 58 | (variable))))))))))) 59 | (assignement_operator) 60 | (pipeline 61 | (pipeline_chain 62 | (logical_expression 63 | (bitwise_expression 64 | (comparison_expression 65 | (additive_expression 66 | (multiplicative_expression 67 | (format_expression 68 | (range_expression 69 | (array_literal_expression 70 | (unary_expression 71 | (string_literal 72 | (expandable_string_literal))))))))))))))))) 73 | 74 | === 75 | Variable : Command results 76 | === 77 | 78 | $Processes = Get-Process 79 | 80 | $Today = (Get-Date).DateTime 81 | 82 | --- 83 | 84 | (program 85 | (statement_list 86 | (pipeline 87 | (assignment_expression 88 | (left_assignment_expression 89 | (logical_expression 90 | (bitwise_expression 91 | (comparison_expression 92 | (additive_expression 93 | (multiplicative_expression 94 | (format_expression 95 | (range_expression 96 | (array_literal_expression 97 | (unary_expression 98 | (variable))))))))))) 99 | (assignement_operator) 100 | (pipeline 101 | (pipeline_chain 102 | (command 103 | (command_name)))))) 104 | (pipeline 105 | (assignment_expression 106 | (left_assignment_expression 107 | (logical_expression 108 | (bitwise_expression 109 | (comparison_expression 110 | (additive_expression 111 | (multiplicative_expression 112 | (format_expression 113 | (range_expression 114 | (array_literal_expression 115 | (unary_expression 116 | (variable))))))))))) 117 | (assignement_operator) 118 | (pipeline 119 | (pipeline_chain 120 | (logical_expression 121 | (bitwise_expression 122 | (comparison_expression 123 | (additive_expression 124 | (multiplicative_expression 125 | (format_expression 126 | (range_expression 127 | (array_literal_expression 128 | (unary_expression 129 | (member_access 130 | (parenthesized_expression 131 | (pipeline 132 | (pipeline_chain 133 | (command 134 | (command_name))))) 135 | (member_name 136 | (simple_name)))))))))))))))))) 137 | 138 | === 139 | Variable : Multi assignment 140 | === 141 | 142 | $a = $b = $c = 0 143 | 144 | --- 145 | 146 | (program 147 | (statement_list 148 | (pipeline 149 | (assignment_expression 150 | (left_assignment_expression 151 | (logical_expression 152 | (bitwise_expression 153 | (comparison_expression 154 | (additive_expression 155 | (multiplicative_expression 156 | (format_expression 157 | (range_expression 158 | (array_literal_expression 159 | (unary_expression 160 | (variable))))))))))) 161 | (assignement_operator) 162 | (pipeline 163 | (assignment_expression 164 | (left_assignment_expression 165 | (logical_expression 166 | (bitwise_expression 167 | (comparison_expression 168 | (additive_expression 169 | (multiplicative_expression 170 | (format_expression 171 | (range_expression 172 | (array_literal_expression 173 | (unary_expression 174 | (variable))))))))))) 175 | (assignement_operator) 176 | (pipeline 177 | (assignment_expression 178 | (left_assignment_expression 179 | (logical_expression 180 | (bitwise_expression 181 | (comparison_expression 182 | (additive_expression 183 | (multiplicative_expression 184 | (format_expression 185 | (range_expression 186 | (array_literal_expression 187 | (unary_expression 188 | (variable))))))))))) 189 | (assignement_operator) 190 | (pipeline 191 | (pipeline_chain 192 | (logical_expression 193 | (bitwise_expression 194 | (comparison_expression 195 | (additive_expression 196 | (multiplicative_expression 197 | (format_expression 198 | (range_expression 199 | (array_literal_expression 200 | (unary_expression 201 | (integer_literal 202 | (decimal_integer_literal))))))))))))))))))))) 203 | 204 | === 205 | Variable : Multi variables, Multi assignment 206 | === 207 | 208 | $i,$j,$k = 10, "red", $true 209 | $i,$j = 10, "red", $true 210 | 211 | --- 212 | 213 | (program 214 | (statement_list 215 | (pipeline 216 | (assignment_expression 217 | (left_assignment_expression 218 | (logical_expression 219 | (bitwise_expression 220 | (comparison_expression 221 | (additive_expression 222 | (multiplicative_expression 223 | (format_expression 224 | (range_expression 225 | (array_literal_expression 226 | (unary_expression 227 | (variable)) 228 | (unary_expression 229 | (variable)) 230 | (unary_expression 231 | (variable))))))))))) 232 | (assignement_operator) 233 | (pipeline 234 | (pipeline_chain 235 | (logical_expression 236 | (bitwise_expression 237 | (comparison_expression 238 | (additive_expression 239 | (multiplicative_expression 240 | (format_expression 241 | (range_expression 242 | (array_literal_expression 243 | (unary_expression 244 | (integer_literal 245 | (decimal_integer_literal))) 246 | (unary_expression 247 | (string_literal 248 | (expandable_string_literal))) 249 | (unary_expression 250 | (variable)))))))))))))) 251 | (pipeline 252 | (assignment_expression 253 | (left_assignment_expression 254 | (logical_expression 255 | (bitwise_expression 256 | (comparison_expression 257 | (additive_expression 258 | (multiplicative_expression 259 | (format_expression 260 | (range_expression 261 | (array_literal_expression 262 | (unary_expression 263 | (variable)) 264 | (unary_expression 265 | (variable))))))))))) 266 | (assignement_operator) 267 | (pipeline 268 | (pipeline_chain 269 | (logical_expression 270 | (bitwise_expression 271 | (comparison_expression 272 | (additive_expression 273 | (multiplicative_expression 274 | (format_expression 275 | (range_expression 276 | (array_literal_expression 277 | (unary_expression 278 | (integer_literal 279 | (decimal_integer_literal))) 280 | (unary_expression 281 | (string_literal 282 | (expandable_string_literal))) 283 | (unary_expression 284 | (variable)))))))))))))))) 285 | 286 | === 287 | Variable : Typed variables 288 | === 289 | 290 | [string]$words = "Hello" 291 | $words = 2 292 | $words += 10 293 | 294 | --- 295 | 296 | (program 297 | (statement_list 298 | (pipeline 299 | (assignment_expression 300 | (left_assignment_expression 301 | (logical_expression 302 | (bitwise_expression 303 | (comparison_expression 304 | (additive_expression 305 | (multiplicative_expression 306 | (format_expression 307 | (range_expression 308 | (array_literal_expression 309 | (unary_expression 310 | (expression_with_unary_operator 311 | (cast_expression 312 | (type_literal 313 | (type_spec 314 | (type_name 315 | (type_identifier)))) 316 | (unary_expression 317 | (variable)))))))))))))) 318 | (assignement_operator) 319 | (pipeline 320 | (pipeline_chain 321 | (logical_expression 322 | (bitwise_expression 323 | (comparison_expression 324 | (additive_expression 325 | (multiplicative_expression 326 | (format_expression 327 | (range_expression 328 | (array_literal_expression 329 | (unary_expression 330 | (string_literal 331 | (expandable_string_literal))))))))))))))) 332 | (pipeline 333 | (assignment_expression 334 | (left_assignment_expression 335 | (logical_expression 336 | (bitwise_expression 337 | (comparison_expression 338 | (additive_expression 339 | (multiplicative_expression 340 | (format_expression 341 | (range_expression 342 | (array_literal_expression 343 | (unary_expression 344 | (variable))))))))))) 345 | (assignement_operator) 346 | (pipeline 347 | (pipeline_chain 348 | (logical_expression 349 | (bitwise_expression 350 | (comparison_expression 351 | (additive_expression 352 | (multiplicative_expression 353 | (format_expression 354 | (range_expression 355 | (array_literal_expression 356 | (unary_expression 357 | (integer_literal 358 | (decimal_integer_literal))))))))))))))) 359 | (pipeline 360 | (assignment_expression 361 | (left_assignment_expression 362 | (logical_expression 363 | (bitwise_expression 364 | (comparison_expression 365 | (additive_expression 366 | (multiplicative_expression 367 | (format_expression 368 | (range_expression 369 | (array_literal_expression 370 | (unary_expression 371 | (variable))))))))))) 372 | (assignement_operator) 373 | (pipeline 374 | (pipeline_chain 375 | (logical_expression 376 | (bitwise_expression 377 | (comparison_expression 378 | (additive_expression 379 | (multiplicative_expression 380 | (format_expression 381 | (range_expression 382 | (array_literal_expression 383 | (unary_expression 384 | (integer_literal 385 | (decimal_integer_literal))))))))))))))))) 386 | 387 | === 388 | Variable : Simple variable 389 | === 390 | 391 | $aSimpleVariable001 392 | 393 | $91 394 | 395 | $__Z 396 | 397 | $env:PROGRAM_LOCATION 398 | 399 | --- 400 | 401 | (program 402 | (statement_list 403 | (pipeline 404 | (pipeline_chain 405 | (logical_expression 406 | (bitwise_expression 407 | (comparison_expression 408 | (additive_expression 409 | (multiplicative_expression 410 | (format_expression 411 | (range_expression 412 | (array_literal_expression 413 | (unary_expression 414 | (variable)))))))))))) 415 | (pipeline 416 | (pipeline_chain 417 | (logical_expression 418 | (bitwise_expression 419 | (comparison_expression 420 | (additive_expression 421 | (multiplicative_expression 422 | (format_expression 423 | (range_expression 424 | (array_literal_expression 425 | (unary_expression 426 | (variable)))))))))))) 427 | (pipeline 428 | (pipeline_chain 429 | (logical_expression 430 | (bitwise_expression 431 | (comparison_expression 432 | (additive_expression 433 | (multiplicative_expression 434 | (format_expression 435 | (range_expression 436 | (array_literal_expression 437 | (unary_expression 438 | (variable)))))))))))) 439 | (pipeline 440 | (pipeline_chain 441 | (logical_expression 442 | (bitwise_expression 443 | (comparison_expression 444 | (additive_expression 445 | (multiplicative_expression 446 | (format_expression 447 | (range_expression 448 | (array_literal_expression 449 | (unary_expression 450 | (variable)))))))))))))) 451 | 452 | === 453 | Variable : Special variables 454 | === 455 | 456 | $$ 457 | 458 | $^ 459 | 460 | $? 461 | 462 | --- 463 | 464 | (program 465 | (statement_list 466 | (pipeline 467 | (pipeline_chain 468 | (logical_expression 469 | (bitwise_expression 470 | (comparison_expression 471 | (additive_expression 472 | (multiplicative_expression 473 | (format_expression 474 | (range_expression 475 | (array_literal_expression 476 | (unary_expression 477 | (variable)))))))))))) 478 | (pipeline 479 | (pipeline_chain 480 | (logical_expression 481 | (bitwise_expression 482 | (comparison_expression 483 | (additive_expression 484 | (multiplicative_expression 485 | (format_expression 486 | (range_expression 487 | (array_literal_expression 488 | (unary_expression 489 | (variable)))))))))))) 490 | (pipeline 491 | (pipeline_chain 492 | (logical_expression 493 | (bitwise_expression 494 | (comparison_expression 495 | (additive_expression 496 | (multiplicative_expression 497 | (format_expression 498 | (range_expression 499 | (array_literal_expression 500 | (unary_expression 501 | (variable)))))))))))))) 502 | 503 | === 504 | Variable : Brace variable 505 | === 506 | 507 | ${Simple} 508 | 509 | ${More-interestin'} 510 | 511 | ${ 512 | Really && 513 | quite ^ 514 | unusual??? 515 | } 516 | 517 | --- 518 | 519 | (program 520 | (statement_list 521 | (pipeline 522 | (pipeline_chain 523 | (logical_expression 524 | (bitwise_expression 525 | (comparison_expression 526 | (additive_expression 527 | (multiplicative_expression 528 | (format_expression 529 | (range_expression 530 | (array_literal_expression 531 | (unary_expression 532 | (variable 533 | (braced_variable))))))))))))) 534 | (pipeline 535 | (pipeline_chain 536 | (logical_expression 537 | (bitwise_expression 538 | (comparison_expression 539 | (additive_expression 540 | (multiplicative_expression 541 | (format_expression 542 | (range_expression 543 | (array_literal_expression 544 | (unary_expression 545 | (variable 546 | (braced_variable))))))))))))) 547 | (pipeline 548 | (pipeline_chain 549 | (logical_expression 550 | (bitwise_expression 551 | (comparison_expression 552 | (additive_expression 553 | (multiplicative_expression 554 | (format_expression 555 | (range_expression 556 | (array_literal_expression 557 | (unary_expression 558 | (variable 559 | (braced_variable))))))))))))))) 560 | -------------------------------------------------------------------------------- /test/corpus/functions.txt: -------------------------------------------------------------------------------- 1 | === 2 | Basic parameter 3 | === 4 | 5 | function Test 6 | { 7 | param( 8 | $Name 9 | ) 10 | } 11 | 12 | --- 13 | 14 | (program 15 | (statement_list 16 | (function_statement 17 | (function_name) 18 | (script_block 19 | (param_block 20 | (parameter_list 21 | (script_parameter 22 | (variable)))))))) 23 | 24 | === 25 | Basic parameter with type 26 | === 27 | 28 | function Test 29 | { 30 | param( 31 | [String] 32 | $Name 33 | ) 34 | } 35 | 36 | --- 37 | 38 | (program 39 | (statement_list 40 | (function_statement 41 | (function_name) 42 | (script_block 43 | (param_block 44 | (parameter_list 45 | (script_parameter 46 | (attribute_list 47 | (attribute 48 | (type_literal 49 | (type_spec 50 | (type_name 51 | (type_identifier)))))) 52 | (variable)))))))) 53 | 54 | === 55 | Basic parameter with type and default value 56 | === 57 | 58 | function Test 59 | { 60 | param( 61 | [String] 62 | $Name = "" 63 | ) 64 | } 65 | 66 | --- 67 | 68 | (program 69 | (statement_list 70 | (function_statement 71 | (function_name) 72 | (script_block 73 | (param_block 74 | (parameter_list 75 | (script_parameter 76 | (attribute_list 77 | (attribute 78 | (type_literal 79 | (type_spec 80 | (type_name 81 | (type_identifier)))))) 82 | (variable) 83 | (script_parameter_default 84 | (logical_expression 85 | (bitwise_expression 86 | (comparison_expression 87 | (additive_expression 88 | (multiplicative_expression 89 | (format_expression 90 | (range_expression 91 | (array_literal_expression 92 | (unary_expression 93 | (string_literal 94 | (expandable_string_literal))))))))))))))))))) 95 | 96 | === 97 | Basic parameter with output type 98 | === 99 | 100 | function Test 101 | { 102 | [OutputType([Hashtable])] 103 | param( 104 | [String] 105 | $Name 106 | ) 107 | } 108 | 109 | --- 110 | 111 | (program 112 | (statement_list 113 | (function_statement 114 | (function_name) 115 | (script_block 116 | (param_block 117 | (attribute_list 118 | (attribute 119 | (attribute_name 120 | (type_spec 121 | (type_name 122 | (type_identifier)))) 123 | (attribute_arguments 124 | (attribute_argument 125 | (logical_expression 126 | (bitwise_expression 127 | (comparison_expression 128 | (additive_expression 129 | (multiplicative_expression 130 | (format_expression 131 | (range_expression 132 | (array_literal_expression 133 | (unary_expression 134 | (type_literal 135 | (type_spec 136 | (type_name 137 | (type_identifier))))))))))))))))) 138 | (parameter_list 139 | (script_parameter 140 | (attribute_list 141 | (attribute 142 | (type_literal 143 | (type_spec 144 | (type_name 145 | (type_identifier)))))) 146 | (variable)))))))) 147 | 148 | === 149 | Basic parameter with ValidateNotNull 150 | === 151 | 152 | function Test 153 | { 154 | [OutputType([Hashtable])] 155 | param( 156 | [ValidateNotNull()] 157 | [String] 158 | $Name 159 | ) 160 | } 161 | 162 | --- 163 | 164 | (program 165 | (statement_list 166 | (function_statement 167 | (function_name) 168 | (script_block 169 | (param_block 170 | (attribute_list 171 | (attribute 172 | (attribute_name 173 | (type_spec 174 | (type_name 175 | (type_identifier)))) 176 | (attribute_arguments 177 | (attribute_argument 178 | (logical_expression 179 | (bitwise_expression 180 | (comparison_expression 181 | (additive_expression 182 | (multiplicative_expression 183 | (format_expression 184 | (range_expression 185 | (array_literal_expression 186 | (unary_expression 187 | (type_literal 188 | (type_spec 189 | (type_name 190 | (type_identifier))))))))))))))))) 191 | (parameter_list 192 | (script_parameter 193 | (attribute_list 194 | (attribute 195 | (attribute_name 196 | (type_spec 197 | (type_name 198 | (type_identifier))))) 199 | (attribute 200 | (type_literal 201 | (type_spec 202 | (type_name 203 | (type_identifier)))))) 204 | (variable)))))))) 205 | 206 | === 207 | Basic parameter with ValidateScript 208 | === 209 | 210 | function Test 211 | { 212 | [OutputType([Hashtable])] 213 | param( 214 | [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})] 215 | [String] 216 | $Name 217 | ) 218 | } 219 | 220 | --- 221 | 222 | (program 223 | (statement_list 224 | (function_statement 225 | (function_name) 226 | (script_block 227 | (param_block 228 | (attribute_list 229 | (attribute 230 | (attribute_name 231 | (type_spec 232 | (type_name 233 | (type_identifier)))) 234 | (attribute_arguments 235 | (attribute_argument 236 | (logical_expression 237 | (bitwise_expression 238 | (comparison_expression 239 | (additive_expression 240 | (multiplicative_expression 241 | (format_expression 242 | (range_expression 243 | (array_literal_expression 244 | (unary_expression 245 | (type_literal 246 | (type_spec 247 | (type_name 248 | (type_identifier))))))))))))))))) 249 | (parameter_list 250 | (script_parameter 251 | (attribute_list 252 | (attribute 253 | (attribute_name 254 | (type_spec 255 | (type_name 256 | (type_identifier)))) 257 | (attribute_arguments 258 | (attribute_argument 259 | (logical_expression 260 | (bitwise_expression 261 | (comparison_expression 262 | (additive_expression 263 | (multiplicative_expression 264 | (format_expression 265 | (range_expression 266 | (array_literal_expression 267 | (unary_expression 268 | (script_block_expression 269 | (script_block 270 | (script_block_body 271 | (statement_list 272 | (pipeline 273 | (pipeline_chain 274 | (logical_expression 275 | (logical_expression 276 | (bitwise_expression 277 | (comparison_expression 278 | (additive_expression 279 | (multiplicative_expression 280 | (format_expression 281 | (range_expression 282 | (array_literal_expression 283 | (unary_expression 284 | (parenthesized_expression 285 | (pipeline 286 | (pipeline_chain 287 | (logical_expression 288 | (bitwise_expression 289 | (comparison_expression 290 | (comparison_expression 291 | (additive_expression 292 | (multiplicative_expression 293 | (format_expression 294 | (range_expression 295 | (array_literal_expression 296 | (unary_expression 297 | (variable)))))))) 298 | (comparison_operator) 299 | (additive_expression 300 | (multiplicative_expression 301 | (format_expression 302 | (range_expression 303 | (array_literal_expression 304 | (unary_expression 305 | (type_literal 306 | (type_spec 307 | (type_name 308 | (type_name 309 | (type_name 310 | (type_identifier)) 311 | (type_identifier)) 312 | (type_identifier))))))))))))))))))))))))) 313 | (bitwise_expression 314 | (comparison_expression 315 | (additive_expression 316 | (multiplicative_expression 317 | (format_expression 318 | (range_expression 319 | (array_literal_expression 320 | (unary_expression 321 | (parenthesized_expression 322 | (pipeline 323 | (pipeline_chain 324 | (logical_expression 325 | (bitwise_expression 326 | (comparison_expression 327 | (comparison_expression 328 | (additive_expression 329 | (multiplicative_expression 330 | (format_expression 331 | (range_expression 332 | (array_literal_expression 333 | (unary_expression 334 | (variable)))))))) 335 | (comparison_operator) 336 | (additive_expression 337 | (multiplicative_expression 338 | (format_expression 339 | (range_expression 340 | (array_literal_expression 341 | (unary_expression 342 | (type_literal 343 | (type_spec 344 | (type_name 345 | (type_name 346 | (type_identifier)) 347 | (type_identifier))))))))))))))))))))))))))))))))))))))))))) 348 | (attribute 349 | (type_literal 350 | (type_spec 351 | (type_name 352 | (type_identifier)))))) 353 | (variable)))))))) 354 | 355 | === 356 | Basic parameter with Parameter with many paramters 357 | === 358 | 359 | function Test 360 | { 361 | [OutputType([Hashtable])] 362 | param( 363 | [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] 364 | [String] 365 | $Name 366 | ) 367 | } 368 | 369 | --- 370 | 371 | (program 372 | (statement_list 373 | (function_statement 374 | (function_name) 375 | (script_block 376 | (param_block 377 | (attribute_list 378 | (attribute 379 | (attribute_name 380 | (type_spec 381 | (type_name 382 | (type_identifier)))) 383 | (attribute_arguments 384 | (attribute_argument 385 | (logical_expression 386 | (bitwise_expression 387 | (comparison_expression 388 | (additive_expression 389 | (multiplicative_expression 390 | (format_expression 391 | (range_expression 392 | (array_literal_expression 393 | (unary_expression 394 | (type_literal 395 | (type_spec 396 | (type_name 397 | (type_identifier))))))))))))))))) 398 | (parameter_list 399 | (script_parameter 400 | (attribute_list 401 | (attribute 402 | (attribute_name 403 | (type_spec 404 | (type_name 405 | (type_identifier)))) 406 | (attribute_arguments 407 | (attribute_argument 408 | (simple_name) 409 | (logical_expression 410 | (bitwise_expression 411 | (comparison_expression 412 | (additive_expression 413 | (multiplicative_expression 414 | (format_expression 415 | (range_expression 416 | (array_literal_expression 417 | (unary_expression 418 | (variable))))))))))) 419 | (attribute_argument 420 | (simple_name) 421 | (logical_expression 422 | (bitwise_expression 423 | (comparison_expression 424 | (additive_expression 425 | (multiplicative_expression 426 | (format_expression 427 | (range_expression 428 | (array_literal_expression 429 | (unary_expression 430 | (variable))))))))))))) 431 | (attribute 432 | (type_literal 433 | (type_spec 434 | (type_name 435 | (type_identifier)))))) 436 | (variable)))))))) 437 | 438 | === 439 | Named scriptblock_expression 440 | === 441 | 442 | function Test 443 | { 444 | begin 445 | { 446 | 447 | } 448 | process 449 | { 450 | 451 | } 452 | } 453 | 454 | --- 455 | 456 | (program 457 | (statement_list 458 | (function_statement 459 | (function_name) 460 | (script_block 461 | (script_block_body 462 | (named_block_list 463 | (named_block 464 | (block_name) 465 | (statement_block)) 466 | (named_block 467 | (block_name) 468 | (statement_block)))))))) 469 | 470 | === 471 | A complex but valid function name 472 | === 473 | 474 | function 1+1{ 475 | param( 476 | $Name 477 | ) 478 | } 479 | 480 | --- 481 | 482 | (program 483 | (statement_list 484 | (function_statement 485 | (function_name) 486 | (script_block 487 | (param_block 488 | (parameter_list 489 | (script_parameter 490 | (variable)))))))) 491 | 492 | 493 | === 494 | Function name as keyword 495 | === 496 | 497 | function while {} 498 | 499 | --- 500 | 501 | (program 502 | (statement_list 503 | (function_statement 504 | (function_name)))) 505 | --------------------------------------------------------------------------------