Skip to main content

F5 iRules grammar for tree-sitter

Project description

tree-sitter-irules

CI License: MIT

A tree-sitter parser for F5 iRules — the TCL-derived scripting language used to program traffic management on F5 BIG-IP.

Repository: https://github.com/dekobon/tree-sitter-irules.

iRules are syntactically a dialect of TCL with three additions:

  • Event handlers: when CLIENT_ACCEPTED { ... }, with optional priority N and timing on|off modifiers.
  • Namespace-qualified built-in commands: HTTP::host, IP::client_addr, LB::server, SSL::cert, TCP::respond, etc.
  • Extra expression operators on top of TCL's eq/ne/in/ni: starts_with, ends_with, contains, equals, matches, matches_regex, matches_glob.

This grammar is built as an extension of tree-sitter-tcl by Lewis Russell, redistributed under the MIT license. See LICENSE.

Recognised iRules surface

Names below come from F5's authoritative sources: Commands.html, iRulesReference.html, Operators.html, and when.html. The list reflects what queries/irules/highlights.scm will tag as @function.builtin; commands outside the list still parse, they just fall through to the generic @function capture.

Namespaced commands (<NS>::<command>):

Group Namespaces
Transport / IP IP, TCP, UDP, SCTP, LINK, VLAN, ROUTE, DATAGRAM, DHCP, FLOW, FLOWTABLE, IPFIX, LSN, NSH, PCP
TLS SSL, CLIENTSSL, SERVERSSL, TLS, X509, IKE
HTTP HTTP, HTTP2, HTTP3, WS, WEBSOCKET, CACHE, COMPRESS, REWRITE, STREAM, URI, JSON, XML, HTML, SSE
Other application DNS, SIP, SDP, RTSP, FTP, MQTT, FIX, DIAMETER, RADIUS, ICAP, GTP, TDS, NTLM, MR, GENERICMESSAGE, CONNECTOR, DNSMSG, IMAP, POP3, SIPALG, SMTPS, SOCKS
Load balancing / virtual LB, POOL, NODE, MEMBER, VIRTUAL, SNAT, SNATPOOL, PERSIST, PROFILE, PROXY, ONECONNECT, RATELIMIT, SCRUBBER, GTM, TMM, TMSH, BWC, ISESSION, IVS, L7CHECK
Access / security ACL, ACCESS, ACCESS2, AAA, AUTH, WEBSSO, VDI, WAM, TAP, ASM, BOTDEFENSE, ANTIFRAUD, DOSL7, CATEGORY, CLASSIFICATION, CLASSIFY, CLASS, ADM, APM, ECA, POLICY, PSC
Adaptation / data ADAPT, PEM, AVR, STATS, TABLE, SESSION, EVENT, LOG, LOGGING, MEMORY, RESOLV, RESOLVER, REST, XLAT, NAME, HSL, ILX, QOE, MATRIX, NS, ISTATS, MESSAGE, SIDEBAND
Crypto / encoding CRYPTO, AES, DES, RC4, HMAC, MD5, SHA1, SHA256, SHA384, SHA512, B64, HEX, BIGNUM, ASN1

Global (non-namespaced) iRules commands also tagged as @function.builtin: accumulate, active_members, active_nodes, after, b64decode, b64encode, call, clientside, clone, collect, connect, crc32, decode_uri, discard, domain, drop, event, findclass, findstr, forward, getfield, htonl, htons, listen, matchclass, member, members, node, nodes, ntohl, ntohs, peer, persist, pool, recv, reject, release, send, serverside, session, sharedvar, snat, snatpool, substr, table, virtual.

Event names are intentionally open: anything matching /[A-Z][A-Z0-9_]*/ parses as an event_name. F5 documents 200+ events across protocol families and adds new ones each BIG-IP release; encoding a closed set in the parser would force a regen on every release. Validate event spellings in a linter, not the parser.

TCL baseline

iRules is a TCL 8.4 dialect (per F5 K6091). TCL 8.5 features (dict, lassign, ** operator, expanded lsearch switches) and TCL 8.6 features (try/on error/finally, lmap, throw) are available on BIG-IP 12.x and later when explicitly enabled. The grammar follows the tree-sitter-tcl baseline, so 8.5/8.6 syntax parses fine — but keep in mind that older BIG-IP runtimes will reject those constructs.

A subset of TCL commands is disabled at runtime in iRules for safety (exec, file, open, socket, and others; see F5's DisabledTclCommands.html). The parser does not enforce the disabled list — disabled commands parse as ordinary TCL commands. Linting/validation is out of scope here.

Known limitations

  • Bare-word operands in expr contexts must be quoted or braced, as in stock TCL. if {$x eq foo} produces an (ERROR ...) node because TCL's own expr rejects unquoted barewords (invalid bareword "foo"); write if {$x eq "foo"} or if {$x eq {foo}}. $var, numbers, booleans, [cmd], and "strings" are all accepted operands.
  • Plain matches operator (no _glob/_regex suffix) is accepted by the grammar but is not documented on F5's Operators page. It is retained for upstream tree-sitter-tcl compatibility; prefer matches_glob or matches_regex.
  • Test-runner hang on certain comment-only headers: if a test/highlight/*.irules file's leading comment block contains both a dot-and-slash heavy URL AND a literal quoted regex token (the combination that occurs naturally when documenting the namespace match predicate), npx tree-sitter test hangs on that file. Each pattern in isolation is harmless. Workaround: keep header comments to a single line in highlight test files.

Status

Early. The grammar parses iRules as TCL plus iRules-specific event handlers and tags iRules namespace commands and globals in queries/irules/highlights.scm.

Building

git clone https://github.com/dekobon/tree-sitter-irules.git
cd tree-sitter-irules
npm install
npx tree-sitter generate
npx tree-sitter test

The committed src/parser.c is generated by the exact tree-sitter-cli version recorded in package-lock.json and CI pins to that same version, so contributors must regenerate parser.c with the locally-installed CLI (npx tree-sitter generate) — never with a globally-installed one — when bumping tree-sitter-cli. See AGENTS.md for the full versioning, commit, and changelog conventions.

Using it

Pick the binding for your toolchain. All bindings expose tree_sitter_irules (or the language-idiomatic equivalent) and resolve to the same src/parser.c + src/scanner.c.

No release has been tagged yet, so all snippets below resolve from the default branch. Once a release vX.Y.Z is cut, swap each snippet to a pinned form: Cargo tag = "vX.Y.Z" (instead of branch = "main"), Go @vX.Y.Z (instead of @latest), npm github:dekobon/tree-sitter-irules#vX.Y.Z, pip git+https://github.com/dekobon/tree-sitter-irules@vX.Y.Z, or the published package version once available on the relevant registry.

# Cargo.toml
[dependencies]
tree-sitter-irules = { git = "https://github.com/dekobon/tree-sitter-irules", branch = "main" }
# Go: resolves to a pseudo-version of the latest commit on main.
go get github.com/dekobon/tree-sitter-irules@latest
// package.json
"dependencies": { "tree-sitter-irules": "github:dekobon/tree-sitter-irules" }
# pyproject.toml
[project]
dependencies = ["tree-sitter-irules @ git+https://github.com/dekobon/tree-sitter-irules"]

Bindings ship the parser only. Editor / runtime integrations also need to load queries/irules/highlights.scm (and optionally folds.scm / indents.scm) for highlighting and structural navigation; consult your editor's tree-sitter integration docs for how to register the queries. The Rust binding additionally re-exports the highlights query as HIGHLIGHTS_QUERY.

Filetype detection

The repo ships ftdetect/irules.lua and ftplugin/irules.lua for Neovim. The ftdetect file maps *.irule and *.irules to filetype irules unconditionally; the ftplugin then calls vim.treesitter.start() for that filetype. Highlighting only renders once the parser binary and queries/irules/highlights.scm are registered with nvim-treesitter (or equivalent) — without that, the start() call is a no-op and the buffer falls back to non-treesitter highlighting.

iRules are also commonly stored with a plain .tcl extension — we deliberately do not claim .tcl globally, since most .tcl files on disk are ordinary TCL. To opt specific .tcl files into the iRules parser, pick one of:

  • Modeline at the top of the file: # vim: set filetype=irules :

  • Per-project autocmd in .nvim.lua (sourced after :cd into the project via Neovim's 'exrc'). Note vim.fn.getcwd() is evaluated when the autocmd is defined, so this snippet belongs in a per-project config, not a global init.lua:

    vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
      pattern = vim.fn.getcwd() .. "/irules/*.tcl",
      callback = function() vim.bo.filetype = "irules" end,
    })
    
  • Content-based detection for files that always start with a when block:

    vim.filetype.add({
      pattern = {
        [".*%.tcl$"] = function(_, bufnr)
          local first = vim.api.nvim_buf_get_lines(bufnr, 0, 1, false)[1] or ""
          if first:match("^%s*when%s+[A-Z][A-Z0-9_]*") then return "irules" end
        end,
      },
    })
    

Other editors follow the same pattern: keep .tcl mapped to TCL by default and override per-directory or via a header comment.

Layout

  • grammar.js — grammar definition (TCL base + iRules when event handler).
  • queries/irules/ — highlight, fold, and indent queries with iRules-aware tags.
  • test/corpus/ — corpus tests (TCL tests inherited; iRules-specific tests in test/corpus/irules.txt).
  • bindings/ — language bindings (C, Go, Node, Python, Rust, Swift).

Contributing

  • Issues and feature requests: https://github.com/dekobon/tree-sitter-irules/issues
  • Pull requests welcome. Read AGENTS.md first — it documents the Conventional Commits / SemVer / Keep-a-Changelog conventions, the validation gates (npx tree-sitter generate, npx tree-sitter test, npm run lint), and the rule that committed src/parser.c must be generated by the tree-sitter-cli version recorded in package-lock.json.

License

MIT. See LICENSE. This grammar is a fork of tree-sitter-tcl by Lewis Russell; original copyright is retained alongside the tree-sitter-irules project copyright.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tree_sitter_irules-0.1.0.tar.gz (66.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

tree_sitter_irules-0.1.0-cp38-abi3-win_amd64.whl (52.9 kB view details)

Uploaded CPython 3.8+Windows x86-64

tree_sitter_irules-0.1.0-cp38-abi3-win32.whl (53.6 kB view details)

Uploaded CPython 3.8+Windows x86

tree_sitter_irules-0.1.0-cp38-abi3-musllinux_1_2_x86_64.whl (60.7 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ x86-64

tree_sitter_irules-0.1.0-cp38-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (60.7 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ x86-64manylinux: glibc 2.5+ x86-64

tree_sitter_irules-0.1.0-cp38-abi3-macosx_11_0_arm64.whl (50.7 kB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

File details

Details for the file tree_sitter_irules-0.1.0.tar.gz.

File metadata

  • Download URL: tree_sitter_irules-0.1.0.tar.gz
  • Upload date:
  • Size: 66.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for tree_sitter_irules-0.1.0.tar.gz
Algorithm Hash digest
SHA256 56eae1f924aae8ab687aa33cda6402616483207abf16421e691bc0dbce0ac1fe
MD5 c9fc7ea01f4d3ab40d296d353d79f5b0
BLAKE2b-256 37cff8591e1b252a56b97b8ec8963381eb44f158ab2dac4d7cc2bcd16562ad46

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_irules-0.1.0.tar.gz:

Publisher: release.yml on dekobon/tree-sitter-irules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_irules-0.1.0-cp38-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for tree_sitter_irules-0.1.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 d6d4dd6912fa647c039489f13e060823d62ef0ec27b29b3886254820dd7aaeb0
MD5 6204b8672f1c2e90fe0f64972dace310
BLAKE2b-256 e07597d5355f28c1173611b136b8e72650492fd30376fef4ed094b74f434465a

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_irules-0.1.0-cp38-abi3-win_amd64.whl:

Publisher: release.yml on dekobon/tree-sitter-irules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_irules-0.1.0-cp38-abi3-win32.whl.

File metadata

File hashes

Hashes for tree_sitter_irules-0.1.0-cp38-abi3-win32.whl
Algorithm Hash digest
SHA256 3adfe3a7b2e53d76b3ca51850e0a5fa3c5bb021ee9f1cece32ca188d39ccca44
MD5 3deb026217356bb5fb426a383d86d678
BLAKE2b-256 2026407b8f9a6f8dd58615d5c49b245f4d152fb7086df07c2f357f0a3c876ed5

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_irules-0.1.0-cp38-abi3-win32.whl:

Publisher: release.yml on dekobon/tree-sitter-irules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_irules-0.1.0-cp38-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_irules-0.1.0-cp38-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ffda119775b125414785cb4b6eaf4d5131feb2a9003bf448fb89f7369ab3a17c
MD5 608ebf291bc5c77f5aabf41192bbda49
BLAKE2b-256 dfba73cdd851f0abedd629ebf3fc11f1f9b6a27d63c99324115108c26a8cc5b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_irules-0.1.0-cp38-abi3-musllinux_1_2_x86_64.whl:

Publisher: release.yml on dekobon/tree-sitter-irules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_irules-0.1.0-cp38-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_irules-0.1.0-cp38-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 d8427bcb0b8ed15203edb6645d1b1cb7b56670a63e8d29b7dfa9729c4cdb1b9e
MD5 f151afa211af1f9f388515b6bbd93783
BLAKE2b-256 93aa378b33ba9b4980e145075117bb812f5d86e79f4eb431e0fd3cfe81e9fe09

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_irules-0.1.0-cp38-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl:

Publisher: release.yml on dekobon/tree-sitter-irules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_irules-0.1.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tree_sitter_irules-0.1.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8d125e732423c6857b19a8608172dce5d27c70e80c3fd57bc8445f2bdc2c8173
MD5 15eff40a5c5e19d46b229041ae916fd0
BLAKE2b-256 b7b690de6651ca8e38fa52439a45b732477ad506e7df69d3867e446bffae8250

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_irules-0.1.0-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on dekobon/tree-sitter-irules

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page