tree-sitter-batch
Windows Batch/CMD grammar for tree-sitter.
Parses .bat and .cmd files into a concrete syntax tree for syntax highlighting, code navigation, and analysis.
Features
- Control flow —
IF/ELSE(EXIST, DEFINED, ERRORLEVEL, comparison with NOT),FOR(/D /R /L /F),GOTO,CALL,EXIT /B - Variables —
SET(plain,/Aarithmetic,/Pprompt, display-only without=),%VAR%,!VAR!,%%i,%~dp0,%VAR:old=new%, subscripted delayed expansion!ARR[%%i]!, for-variable modifiers%%~dpnxf%%~zS%%~$PATH:F, escaped forms%%VAR%%%%%%i - Echo — free-form text with literal
()!%, inline strings, and variable references - Operators — pipes
|, redirects>>><2>2>&1(fds 0-9, including variable handles>&%FD%/<&%FD%), conditional&&||, separator& - Line continuation — trailing caret
^joins the current line with the next (e.g."%JAVACMD%" ^followed by indented arguments) - Commands — bare names, variable references as command, and quoted paths (
"C:\path\app.exe" args,call "%SCRIPT%" %*) - Structure — labels
:name, commentsREM::, parenthesized blocks (including@(...)),@ECHO OFF, macro invocations, DosTips idioms(call,)/(call;)/(call)for ERRORLEVEL manipulation - Scope —
SETLOCAL/ENDLOCALwithENABLEDELAYEDEXPANSION - Polyglot headers — tolerates batch/PowerShell
<# ... #>header lines and batch/VBScript lines marked with a trailing'VBSso SysToolsLib-style dual-language scripts parse cleanly - Case-insensitive — all keywords match regardless of casing
Example
@echo off
REM Build script
setlocal enabledelayedexpansion
set "PROJECT=MyApp"
set /a VERSION=1
if not exist "dist" (
mkdir dist
)
for %%f in (src\*.txt) do (
copy "%%f" "dist\"
)
if %ERRORLEVEL% == 0 (
echo Build successful
) else (
echo Build failed
exit /b 1
)
exit /b 0
Parsed tree:
(program
(echo_off)
(comment)
(setlocal_stmt)
(variable_assignment
(set_keyword) (variable_name) (assignment_value))
(variable_assignment
(set_keyword) (arithmetic_assignment (set_option) (arithmetic_expression)))
(if_stmt
(string)
(parenthesized
(cmd (command_name) (argument_list (argument_value)))))
(for_stmt
(for_variable)
(for_set (for_set_literal))
(parenthesized
(cmd (command_name) (argument_list (string) (string)))))
(if_stmt
(variable_reference)
(comparison_op)
(argument_value)
(parenthesized
(cmd (command_name) (argument_list (argument_value) (argument_value))))
(else_clause
(parenthesized
(cmd (command_name) (argument_list (argument_value) (argument_value)))
(exit_stmt (integer)))))
(exit_stmt (integer)))
Installation
npm
Cargo
PyPI
Go
import tree_sitter_batch "github.com/wharflab/tree-sitter-batch/bindings/go"
The root package also exports the bundled queries/highlights.scm via go:embed:
import batch "github.com/wharflab/tree-sitter-batch"
lang := batch.GetLanguage()
query, _ := batch.GetHighlightsQuery()
// or access the raw .scm source:
// raw := batch.HighlightsQuery
Usage
Node.js
import Parser from "tree-sitter";
import Batch from "tree-sitter-batch";
const parser = ;
parser.;
const tree = parser.;
console.log;
Rust
let mut parser = new;
let language = LANGUAGE;
parser.set_language.unwrap;
let tree = parser.parse.unwrap;
println!;
Python
=
=
Syntax Highlighting
The grammar ships with a queries/highlights.scm file for use in editors that support tree-sitter highlighting (Neovim, Helix, Zed, etc.).
References
- Grammar informed by Blinter batch file linter (159 rules)
- SS64 CMD reference
- Microsoft CMD documentation