Skip to main content

cfml grammar for tree-sitter

Project description

tree-sitter-cfml

npm crates.io "Buy Me A Coffee"

Tree-sitter grammars for ColdFusion Markup Language (CFML).

There are three grammars: two for CFML in .cfc/.cfm and .cfs files, and one for SQL inside <cfquery> (embedded dialect).

Grammar Scope File types Description
cfml source.cfml .cfc, .cfm ColdFusion components and template files - CFScript, tag-based components, and HTML with embedded CF tags
cfscript source.cfscript .cfs Pure CFScript files
cfquery source.cfquery (embedded) SQL inside <cfquery> bodies (including QueryExecute-style usage), with #hash# interpolation and CF tags in the body

Playground

Browser demo: cfmleditor.github.io/tree-sitter-cfml

Installation

Node.js

npm install @cfmleditor/tree-sitter-cfml
const {
  cfml,
  cfscript,
  cfquery,
} = require("@cfmleditor/tree-sitter-cfml");
const Parser = require("tree-sitter");

const parser = new Parser();
parser.setLanguage(cfml.language);

const tree = parser.parse("<cfif condition>#value#</cfif>");
console.log(tree.rootNode.toString());

Rust

[dependencies]
tree-sitter = "0.25"
tree-sitter-cfml = "0.26.30"

The tree-sitter crate should be 0.25+ so the ABI matches the generated parsers (see LANGUAGE_VERSION in cf*/src/parser.c).

use tree_sitter_cfml::LANGUAGE_CFML;

let mut parser = tree_sitter::Parser::new();
parser.set_language(&LANGUAGE_CFML.into())
    .expect("Error loading CFML grammar");
// LANGUAGE_CFSCRIPT, LANGUAGE_CFQUERY load the same way.

Python

pip install tree-sitter-cfml
import tree_sitter_cfml as ts_cfml
from tree_sitter import Language, Parser

# cfml for .cfc and .cfm files
parser = Parser(Language(ts_cfml.language_cfml()))
tree = parser.parse(b'<cfif x GT 0>#x#</cfif>')

# cfscript for .cfs pure script files
parser = Parser(Language(ts_cfml.language_cfscript()))

# cfquery SQL dialect (embedded)
parser = Parser(Language(ts_cfml.language_cfquery()))

Go

import (
    tree_sitter_cfml "github.com/cfmleditor/tree-sitter-cfml/bindings/go"
    sitter "github.com/tree-sitter/go-tree-sitter"
)

// cfml for .cfc and .cfm files
parser := sitter.NewParser()
parser.SetLanguage(sitter.NewLanguage(tree_sitter_cfml.LanguageCfml()))

// cfscript for .cfs pure script files
parser.SetLanguage(sitter.NewLanguage(tree_sitter_cfml.LanguageCfscript()))

// cfquery SQL dialect (embedded)
parser.SetLanguage(sitter.NewLanguage(tree_sitter_cfml.LanguageCfquery()))

Development

Each dialect has grammar.js, generated C under src/, corpus tests under test/corpus/, and queries under queries/. Shared scanner code is under common/. The multi-grammar CLI and playground config is tree-sitter.json. Upstream docs: Creating parsers, CLI.

Setup

git clone https://github.com/cfmleditor/tree-sitter-cfml.git
cd tree-sitter-cfml

Use Node >=18 and <24 (package.json engines). Optional: .nvmrc with nvm / fnm (nvm use).

npm install

That installs dependencies, builds the Node native addon (node-gyp-build), and runs postinstall, which downloads the tree-sitter CLI binary into node_modules/tree-sitter-cli/ when needed. Repo npm scripts do not require a global tree-sitter on PATH.

npm test          # all three grammars
npm run lint      # ESLint
npm run build     # regenerate parsers + rebuild native addon (after grammar edits)

Windows

Put GCC from MinGW-w64 on your PATH (gcc / g++). This repo uses GCC for npm test (tree-sitter compile), the Node native binding, Python extension builds, and Go CGO — not MSVC.

Standalone toolchain (recommended): install WinLibs with winget, then add the extracted mingw64\bin directory (contains gcc.exe) to your user PATH, open a new terminal, and verify:

gcc --version

Example package (UCRT, POSIX threads):

winget install BrechtSanders.WinLibs.POSIX.UCRT

The installer path varies by machine; locate mingw64\bin under the WinLibs folder (or under %LOCALAPPDATA%\Microsoft\WinGet\Packages\ after install) and add that bin to PATH.

Alternatively: MSYS2 with pacman -S mingw-w64-x86_64-gcc, then prepend msys64\mingw64\bin to PATH (or develop from an MSYS2 MinGW64 shell).

If node-gyp still picks Visual Studio instead of MinGW, set CC / CXX to your MinGW gcc / g++ for npm install / npm rebuild, or keep MinGW’s bin before MSVC entries on PATH.

macOS

Install the Xcode command-line tools:

xcode-select --install
Homebrew
brew install gcc

Linux

Install a C/C++ toolchain (for example build-essential on Debian/Ubuntu, gcc / clang plus development headers on other distributions).

CI

CI (.github/workflows/ci.yml): npm install, npm test, npm run lint on Ubuntu, macOS, and Windows. It does not run npm run build; generated cf*/src/ files are committed.

Tree-sitter CLI

Scripts use scripts/tree-sitter-cli.cjs (node node_modules/tree-sitter-cli/cli.js). A global tree-sitter-cli install is optional. If the binary is missing after install:

node scripts/ensure-tree-sitter-cli-binary.js

From a dialect directory (after npm install at repo root):

cd cfml
node ../node_modules/tree-sitter-cli/cli.js test
node ../node_modules/tree-sitter-cli/cli.js generate
node ../node_modules/tree-sitter-cli/cli.js parse path/to/file.cfc

Dependency versions

Pinned in package.json / tree-sitter.json; approximate roles:

Role Package Version
Native binding (peer / dev) tree-sitter 0.25.0
Parser CLI tree-sitter-cli 0.26.8
Native addon node-addon-api ^8.3.0
Native addon node-gyp-build ^4.8.4
Prebuild prebuildify ^6.0.1
Runtime Node.js >=18 <24

CFML engines

Corpus and behavior are checked mainly against Lucee. Overlapping Adobe ColdFusion syntax should still parse in a reasonable way. Avoid Adobe-only or Lucee-only assumptions in examples or grammar design where portable CFML is enough.

Building

After changing common/define-grammar.js or a grammar.js:

npm run build

On Unix, make generate at the repo root works if tree-sitter is on your PATH; otherwise use npm run build.

tree-sitter generate may warn about “unnecessary conflicts” (expressions vs _property_name, cfscript declaration / primary_expression, cfquery hash rules, etc.). Those come from common/define-grammar.js. If npm run build and npm test succeed, the warnings can be ignored.

Testing and helpers

See Setup for npm test, npm run lint, and npm run build.

npm run testbindings  # Node binding smoke test

One grammar only: run test via the CLI from that dialect’s directory (above), or npm test for all three.

Parse a file: from the dialect folder (e.g. cfml for .cfc), use the parse subcommand with the same node ../node_modules/.../cli.js pattern.

Playground / WebAssembly (WASM)

  • npm start — playground at repo root (tree-sitter.json). Run npm run prestart first if WASM is stale.
  • npm run prestarttree-sitter build --wasm
  • npm run playground — playground in each of cfml/, cfscript/, cfquery/
  • npm run docswasm — writes docs/tree-sitter-{cfml,cfscript,cfquery}.wasm for docs/ (e.g. GitHub Pages)

Releasing

npm run release -- 0.26.18
npm run release -- 0.26.18 --user=ghedwards  # optional: switch gh auth before push

The release script (scripts/release.js) will:

  1. Validate version format and ensure it's greater than current
  2. Ensure the working tree is clean and local branch is not behind remote
  3. Verify tag v<version> doesn't already exist
  4. Verify CHANGELOG.md has a ## [<version>] or ## [Unreleased] entry with notes
  5. Update the version in package.json and Cargo.toml
  6. Run npm run build (regenerate parsers)
  7. Run npm run lint (ESLint)
  8. Run npm test (all three grammars)
  9. Run npm run docswasm (rebuild playground WASM)
  10. Run npm run install (rebuild native addon)
  11. Commit all changes and create a v<version> tag (prompted)
  12. Push commit and tag (prompted)

Once the tag is pushed, the GitHub Release workflow (.github/workflows/release.yml) will automatically publish to npm, crates.io, and create a GitHub Release with the changelog notes.

Grammar structure

Shared rules: common/define-grammar.js. External scanner: common/scanner.h (implicit end tags, CF tag names, hash expressions, raw text).

common/
  define-grammar.js
  scanner.h
  tag.h

cfml/          # .cfc, .cfm
  grammar.js
  src/         # generated
  queries/

cfscript/      # .cfs
  grammar.js
  src/
  queries/

cfquery/       # embedded SQL
  grammar.js
  src/
  queries/

Queries

Grammar Highlights Indents Injections Tags
cfml yes yes yes yes
cfscript yes no no yes
cfquery yes no no yes

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md.

Agent and AI assistant guidance

See AGENTS.md.

License

MIT

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_cfml-0.26.30.tar.gz (1.5 MB view details)

Uploaded Source

Built Distributions

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

tree_sitter_cfml-0.26.30-cp310-abi3-win_amd64.whl (559.1 kB view details)

Uploaded CPython 3.10+Windows x86-64

tree_sitter_cfml-0.26.30-cp310-abi3-win32.whl (557.5 kB view details)

Uploaded CPython 3.10+Windows x86

tree_sitter_cfml-0.26.30-cp310-abi3-musllinux_1_2_x86_64.whl (678.5 kB view details)

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

tree_sitter_cfml-0.26.30-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (681.3 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

tree_sitter_cfml-0.26.30-cp310-abi3-macosx_11_0_arm64.whl (601.1 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file tree_sitter_cfml-0.26.30.tar.gz.

File metadata

  • Download URL: tree_sitter_cfml-0.26.30.tar.gz
  • Upload date:
  • Size: 1.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tree_sitter_cfml-0.26.30.tar.gz
Algorithm Hash digest
SHA256 c510f5839406bbf39873ce8fe83ce96091825be21ad2d8b97e472b60d597431d
MD5 173a38468841b8a68d572df4ec570407
BLAKE2b-256 a8619f3a95e26fd50012863a061dc1dc968f843d53e26f920ad1470b13059496

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_cfml-0.26.30.tar.gz:

Publisher: release.yml on cfmleditor/tree-sitter-cfml

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_cfml-0.26.30-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for tree_sitter_cfml-0.26.30-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 6fa9069b4ef0f380c82425c2501cc4b75ecdf6b0e687278dcea314aa3290e5ba
MD5 95e7f5183d9781ff9a9d87ceb442f2a0
BLAKE2b-256 1fdeab65511efd042358fc1aed4f9a6c964dae92f07c79da4b62ed402909f30c

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_cfml-0.26.30-cp310-abi3-win_amd64.whl:

Publisher: release.yml on cfmleditor/tree-sitter-cfml

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_cfml-0.26.30-cp310-abi3-win32.whl.

File metadata

File hashes

Hashes for tree_sitter_cfml-0.26.30-cp310-abi3-win32.whl
Algorithm Hash digest
SHA256 b693eb01de46183e834edb83ecf26afca16bcf4232efb8600c3fa2655414ecee
MD5 c49e25b6805267877dbe0132a6fcb3b0
BLAKE2b-256 7736bd64e791721da3f328f9da48ecfa14fec7c6be5322ea8f19637ff337aa14

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_cfml-0.26.30-cp310-abi3-win32.whl:

Publisher: release.yml on cfmleditor/tree-sitter-cfml

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_cfml-0.26.30-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_cfml-0.26.30-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 cea1522f1282a9c28314ec5e2eac495c7c63ecb684be7db691acd82ddfe9c721
MD5 fd7ddf0a6245be9dc4982edc2ca8cfea
BLAKE2b-256 c30e423f4d5ac62cf0d587f4f85141fa757f8d8bac3eedb1bc81e13d9e530bea

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_cfml-0.26.30-cp310-abi3-musllinux_1_2_x86_64.whl:

Publisher: release.yml on cfmleditor/tree-sitter-cfml

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_cfml-0.26.30-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_cfml-0.26.30-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3693c3967f2abd0bb329b949412c1b31c03b481c3966b4c0c84dde7bd9278be2
MD5 010f271b57a0b4212811144c1c0bff1a
BLAKE2b-256 b9bd0377e01f69b6c329c8d584ccdc511498756ee2b5a40d21fe475467403356

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_cfml-0.26.30-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on cfmleditor/tree-sitter-cfml

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_cfml-0.26.30-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tree_sitter_cfml-0.26.30-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 571968884fd00e9340e6b438ef8a29d536e95052e3e1c7ab183707f7b44df2ad
MD5 d5678b9c296df721840daab4a4726ab1
BLAKE2b-256 655fe3abdb3efe8e85c7eb44e775ccc48ed14ccbbeba4fb71775ca3f2413f704

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_cfml-0.26.30-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on cfmleditor/tree-sitter-cfml

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