brgen (BinaRy encoder/decoder GENerator) is a polyglot code generator that produces
encoder/decoder code for binary formats. It parses .bgn format definitions into a JSON
AST (src2json), then code generators (json2go, json2cpp2, json2rust, json2c,
json2ts, json2kaitai, json2mermaid, json2vm) emit target-language code. AST
manipulation libraries exist for Go, TypeScript, Rust, Python, and C. Many AST library
files (astlib/ast2go/, astlib/ast2ts/, astlib/ast2py/, astlib/ast2rust/) are
auto-generated -- look for // Code generated by gen_ast2...; DO NOT EDIT. headers
and do not manually edit those files.
External dependency: futils (github.com/on-keyday/utils) provides libfutils and is
cloned automatically by script/clone_utils.sh or script/clone_utils.bat.
# Linux/macOS/Windows: configure + build (defaults to Debug)
python build.py native Debug
# Build only (after configure)
ninja -C built/native/Debug
ninja -C built/native/Debug installRequires: CMake >= 3.26, Ninja, Clang (C++20), libfutils from futils repo.
Build output goes to built/native/<Debug|Release>/tool/.
# Build a single Go tool directly
go build -o tool/json2go ./src/tool/json2go
# Run Go tests
go test ./src/tool/s2jgo/
go test ./...Module: github.com/on-keyday/brgen, Go 1.24.
# Build json2rust
cargo build --manifest-path src/tool/json2rust/Cargo.toml
# Build cmptest
cargo build --manifest-path src/tool/cmptest/Cargo.toml
# Run Rust tests
cargo test --manifest-path astlib/ast2rust/Cargo.toml# ast2ts library
cd astlib/ast2ts && npm install && npm run build
# LSP extension
cd lsp && npm install && npm run compile
# Web playground
cd web/dev && npm install && tsc && webpack# Run all C++ tests
CTEST_OUTPUT_ON_FAILURE=1 ninja -C built/native/Debug test
# Run a single C++ test by name
ctest --test-dir built/native/Debug -R lexer_test
ctest --test-dir built/native/Debug -R ast_test
# Run test executable directly
./built/native/Debug/test/lexer_test
./built/native/Debug/test/ast_testAvailable test names: lexer_test, ast_test, typing_test, middle_test,
from_json_test, section_writer_test, type_attribute, derive_test, ctype_test,
deep_copy_test.
# Run all Go tests
go test ./...
# Run a single Go test
go test ./src/tool/s2jgo/ -run TestName
# Fuzz testing
go test -fuzz ./src/test/test_tool/cargo test --manifest-path astlib/ast2rust/Cargo.toml
cargo test --manifest-path src/tool/json2rust/Cargo.tomltool/cmptest -f ignore/example/test_info.json -c testkit/cmptest.json --expected-test-total 8 --debug- clang-format with config in
.clang-format(Google-based, 4-space indent, no column limit, no include sorting) - clang-tidy enabled via VS Code settings
- Format on save is enabled in
.vscode/settings.json - Run manually:
clang-format -i <file>
- Standard
gofmt/goimports. Code generators usego/formatto auto-format output. - Run:
gofmt -w <file>orgoimports -w <file>
- Standard
rustfmt. Run:cargo fmt --manifest-path <path>/Cargo.toml
- mypy is used for type checking (
.mypy_cache/present)
- Standard: C++20. Heavy use of
constexpr,auto&&, templates. - License: Every file starts with
/*license*/on the first line. - Includes: Angle brackets for external/framework (
<core/ast/json.h>), quotes for relative ("../common/print.h"). Include sorting is disabled. - Namespaces: Top-level
brgen::, sub-namespaces likebrgen::ast,brgen::lexer. All namespace content is indented (per.clang-format). - Types:
PascalCasefor structs/classes (Context,BitFieldMeta). - Functions:
PascalCasefor top-level entry points (Main),snake_casefor methods. - Variables/fields:
snake_case(no_color,use_error). Booleans often prefixed withis_,use_,add_,enable_. - Error handling: No exceptions. Return
futils::error::Error<>{}or check validity. Print tocerrfor user-facing errors. - Headers: Use
#pragma once. - Braces: Same-line opening brace,
elseon new line after closing brace. - Indent: 4 spaces, no tabs.
- Imports: Standard library first, blank line, then third-party/project imports. Use named imports when needed (e.g.,
ast2go "github.com/on-keyday/brgen/astlib/ast2go/ast"). - Types:
PascalCasefor exported,camelCasefor unexported. - Functions:
PascalCaseexported,camelCaseunexported. - Error handling: Standard
if err != nilpattern, wrap withfmt.Errorf("...: %w", err). - Flags: Use the standard
flagpackage (not cobra). - TODO tags: Use
// TODO(on-keyday):format.
- Types/Structs:
PascalCase. Functions/methods:snake_case. Constants:SCREAMING_SNAKE_CASE. - Error handling:
anyhow::Resultwith?propagation. Useeprintln!+ExitCode::FAILUREinmain. - CLI args:
clapwith derive macros (#[derive(Parser)]). - Serialization:
serde/serde_jsonfor AST deserialization. - Smart pointers:
Rc<RefCell<T>>aliased asSharedPtr<T>.
- Variables/functions:
camelCase. Classes/interfaces:PascalCase. - Error handling:
async/awaitwithtry/catch,reject(new Error(...)). - Imports: Named imports (
import { ... } from "...").
- Types:
PascalCase. Functions:snake_case. Enum members:SCREAMING_SNAKE_CASE. - Type hints: Use
from __future__ import annotationsandtypingmodule. - Note: Most Python AST code is auto-generated -- do not edit manually.
- Pipeline:
.bgnsource ->src2json(C++ parser) -> JSON AST ->json2*generators -> target code. - Auto-generated files: AST libraries in
astlib/are generated bygen_ast2*tools insrc/tool/gen/. Regenerate with the correspondinggen_ast2*binary, do not edit by hand. - WASM support: C++ uses
#ifdef __EMSCRIPTEN__, Go uses//go:build !js || !wasm, Rust useswasm_bindgen. The web playground runs these tools in-browser. - Cross-platform: CI builds for Linux (x86+ARM), macOS, Windows, Android, and WASM.
- Comments are sparse across all languages -- the codebase favors self-documenting code. When adding comments, use
//style and keep them concise. - Binary format definitions (
.bgnfiles) live inexample/with ~100+ real-world protocol/format examples (UDP, TCP, DNS, TLS, ZIP, ELF, etc.).