# @willbooster/tree-sitter-cpp
[](https://www.npmjs.com/package/@willbooster/tree-sitter-cpp)
[](https://www.npmjs.com/package/@willbooster/tree-sitter-cpp)
[](https://github.com/WillBooster/tree-sitter-cpp/actions/workflows/test.yml)
[](https://github.com/WillBooster/tree-sitter-cpp/actions/workflows/test-rust.yml)
[](https://github.com/semantic-release/semantic-release)
[](https://github.com/WillBooster/shared/tree/main/packages/wbfy)
[](https://crates.io/crates/willbooster-tree-sitter-cpp)
C++ grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter), forked from
[tree-sitter/tree-sitter-cpp](https://github.com/tree-sitter/tree-sitter-cpp). We are grateful
to its authors and contributors. This is not an official release of that project.
This fork fixes parsing bugs and raises conformance with the ISO C++ standard ([working draft](https://eel.is/c++draft/)).
## Usage
The npm package ships `tree-sitter-cpp.wasm` for
[@willbooster/web-tree-sitter](https://www.npmjs.com/package/@willbooster/web-tree-sitter), which runs in Node.js, Bun,
browsers, and Cloudflare Workers. Install both:
```sh
npm install @willbooster/tree-sitter-cpp @willbooster/web-tree-sitter
```
In Node.js and Bun, load the `.wasm` file from its path:
```js
import { fileURLToPath } from 'node:url';
import { Language, Parser } from '@willbooster/web-tree-sitter';
await Parser.init();
const parser = new Parser();
const wasmPath = fileURLToPath(import.meta.resolve('@willbooster/tree-sitter-cpp/tree-sitter-cpp.wasm'));
parser.setLanguage(await Language.load(wasmPath));
const tree = parser.parse('int main() {}\n');
```
In browsers, serve both `.wasm` files and load them by URL. With Vite:
```js
import { Language, Parser } from '@willbooster/web-tree-sitter';
import runtimeUrl from '@willbooster/web-tree-sitter/web-tree-sitter.wasm?url';
import cppUrl from '@willbooster/tree-sitter-cpp/tree-sitter-cpp.wasm?url';
await Parser.init({ locateFile: () => runtimeUrl });
const parser = new Parser();
parser.setLanguage(await Language.load(cppUrl));
```
In Cloudflare Workers, which do not allow compiling Wasm at run time, import both `.wasm` files as modules:
```js
import { Language, Parser } from '@willbooster/web-tree-sitter';
import runtime from '@willbooster/web-tree-sitter/web-tree-sitter.wasm';
import cpp from '@willbooster/tree-sitter-cpp/tree-sitter-cpp.wasm';
await Parser.init({ wasmModule: runtime });
const parser = new Parser();
parser.setLanguage(await Language.load(cpp));
```
The package also ships the node types in `src/node-types.json`.
In Rust, depend on the [crate](https://crates.io/crates/willbooster-tree-sitter-cpp) and on
[willbooster-tree-sitter](https://crates.io/crates/willbooster-tree-sitter), the runtime this package is tested and
fuzzed with (the grammar also loads in the upstream `tree-sitter` crate 0.27, whose error recovery never ends on some
malformed input):
```toml
[dependencies]
tree-sitter = { package = "willbooster-tree-sitter", version = "1" }
tree-sitter-cpp = { package = "willbooster-tree-sitter-cpp", version = "1" }
```
```rust
let mut parser = tree_sitter::Parser::new();
parser.set_language(&tree_sitter_cpp::LANGUAGE.into())?;
```
## Development
```sh
mise install
bun install --frozen-lockfile
bun run build/ci
bun run test
script/parse-examples
cargo test --locked
```
`bun run test` runs:
- the corpus in `test/corpus`, with the native build and with the Wasm build (the first run downloads the WASI SDK);
- an incremental-parsing check (`test/unit/incremental.test.ts`): `tree-sitter fuzz` edits each corpus case at random,
reparses it, undoes the edits, and reparses again. `TREE_SITTER_SEED`, `TREE_SITTER_ITERATIONS`, and
`TREE_SITTER_EDITS` run other or more edits;
- a check that the real-world C++ files in `examples/`, the checked-in ones and those of the cloned repositories,
fail to parse exactly as listed in `script/known-failures.txt`. The first run clones the repositories. The example repositories are pinned to commits in
`script/parse-examples`. After a grammar change or a moved pin alters that list, `script/parse-examples` rewrites
it; review its diff before committing;
- a performance check (`test/unit/performance.test.ts`) that recovering from an error on each of 10,000 lines takes
linear time, since consumers parse files while they are being edited. It loads the Wasm build through
@willbooster/web-tree-sitter, which `bun run build/ci` rebuilds after regenerating the parser;
- checks that the Wasm build parses in Chromium (`test/unit/browser/`) and in Cloudflare Workers with and without
Node.js compatibility (`test/unit/workers.test.ts`). Run `bun run test/ci-setup` once to install Chromium.
CI also runs these tests on Linux arm64 and macOS, where the parser and scanner are compiled natively against each platform's C library, and fuzzes the parser with libFuzzer and sanitizers
(`.github/workflows/robustness.yml`).
### References
- [Hyperlinked C++ BNF Grammar](http://www.nongnu.org/hcb/)
- [EBNF Syntax: C++](http://www.externsoft.ch/download/cpp-iso.html)