Gram Codec
Bidirectional codec between Gram notation (human-readable text format) and Pattern data structures.
Features
- Full Grammar Support: Parses all Gram syntax forms (nodes, relationships, subject patterns, annotations)
- Round-Trip Correctness: Parse → serialize → parse produces structurally equivalent patterns
- Error Recovery: Reports all syntax errors, not just the first
- Value Types: Supports strings, integers, decimals, booleans, arrays, ranges, tagged strings
- Unicode Support: Full Unicode identifier and property value support
- Comprehensive Testing: 139+ tests covering all syntax forms and edge cases
Installation
Add to your Cargo.toml:
[]
= { = "../gram-codec" }
= { = "../pattern-core" }
Quick Start
Parsing Gram Notation
use parse_gram;
// Parse a simple node
let patterns = parse_gram?;
println!;
// Parse a relationship
let patterns = parse_gram?;
println!;
// Parse a subject pattern
let patterns = parse_gram?;
println!;
Serializing Patterns
use ;
use ;
use ;
// Create a pattern
let subject = Subject ;
let pattern = point;
// Serialize a single pattern
let gram_text = to_gram_pattern?;
println!; // Output: (hello)
// Serialize multiple patterns
let multiple = to_gram?;
println!; // Output: (hello)\n(hello)
Round-Trip Correctness
use ;
let original = "(alice:Person {name: \"Alice\"})";
// Parse
let parsed = parse_gram?;
// Serialize
let serialized = to_gram_pattern?;
// Re-parse
let reparsed = parse_gram?;
// Verify structural equivalence
assert_eq!;
Supported Gram Syntax
Node Patterns (0 elements)
() // Empty node
(hello) // Node with identifier
(a:Person) // Node with label
(a:Person {name: "Alice"}) // Node with properties
Relationship Patterns (2 elements)
The grammar accepts multiple visual arrow styles that normalize to 4 semantic arrow kinds:
Right Arrow (right_arrow) - Directed left-to-right
(a)-->(b) // Single-stroke (canonical)
(a)==>(b) // Double-stroke
(a)~~>(b) // Squiggle
(a)-[:KNOWS]->(b) // With label
(a)-[:KNOWS {since: 2020}]->(b) // With properties
Left Arrow (left_arrow) - Directed right-to-left (elements reversed)
(a)<--(b) // Single-stroke (canonical)
(a)<==(b) // Double-stroke
(a)<~~(b) // Squiggle
// Note: (a)<--(b) stores elements as [b, a] (reversed!)
Bidirectional Arrow (bidirectional_arrow) - Mutual connection
(a)<-->(b) // Single-stroke (canonical)
(a)<==>(b) // Double-stroke
Undirected Arrow (undirected_arrow) - No directionality
(a)~~(b) // Squiggle (canonical)
(a)==(b) // Double-stroke
Element Ordering:
- Right arrows: Elements stored as
[left, right](as written) - Left arrows: Elements stored as
[right, left](reversed from visual order!) - Bidirectional/Undirected: Elements stored as
[first, second](as written)
Subject Patterns (N elements)
[team | (alice), (bob)] // Pattern with elements
[outer | [inner | (leaf)]] // Nested patterns
[root:Type {p: 1} | e1, e2] // With identifier, label, properties
Annotated Patterns (1 element)
@type(node) (a) // Annotation on node
@depth(2) [x | y, z] // Annotation on subject pattern
Property Values
{
name: "Alice", // String
age: 30, // Integer
score: 95.5, // Decimal
active: true, // Boolean
tags: ["rust", "wasm"], // Array
range: 1..10 // Range
}
Comments
// This is a line comment
(hello)-->(world) // End-of-line comment
Advanced Usage
Complex Relationships
let gram_text = "(alice:Person {name: \"Alice\", age: 30})-[:KNOWS {since: 2020}]->(bob:Person {name: \"Bob\"})";
let patterns = parse_gram_notation?;
// Access left node
println!;
// Access edge
println!;
// Access right node
println!;
Nested Patterns
let gram_text = "[outer:Group | [inner:Team | (alice), (bob)], (charlie)]";
let patterns = parse_gram_notation?;
println!;
println!;
println!;
Path Patterns
// Chained relationships
let gram_text = "(a)-->(b)-->(c)-->(d)";
let patterns = parse_gram_notation?;
// Creates nested relationship structure
println!;
Unicode Support
// Unicode identifiers must be quoted
let gram_text = "(\"世界\" {greeting: \"こんにちは\"})";
let patterns = parse_gram_notation?;
println!;
Error Handling
use parse_gram_notation;
let invalid_gram = "(unclosed";
match parse_gram_notation
Examples
📚 See
../../examples/gram-codec-README.mdfor complete examples across all platforms!
Run the included examples:
# Basic usage (10 examples)
# Advanced usage (10 examples)
# Interactive Python demo
# Interactive browser demo
# (After building: wasm-pack build --target web . -- --features wasm)
# Open http://localhost:8000/examples/gram-codec-wasm-web/
Testing
Run the comprehensive test suite:
# All tests (159 tests total)
# Specific test suite
Test Coverage
- 159 tests total (158 passing + 1 ignored)
- Unit tests for error handling, parser core, serializer core
- Comprehensive arrow style variant tests (all 10 visual forms documented)
- Integration tests for all gram syntax forms
- Edge case handling (nesting, whitespace, comments, error recovery)
- Round-trip correctness validation
Grammar Authority
This codec uses tree-sitter-gram as the authoritative grammar specification. The pure Rust implementation is validated for 100% conformance with the tree-sitter-gram test corpus.
Architecture
The codec consists of several modules:
parser: Transforms Gram notation text → Pattern structures using a pure Rustnomimplementationserializer: Transforms Pattern structures → Gram notation textast: AST (Abstract Syntax Tree) types for cross-language JSON serializationvalue: Value enum for property types (String, Integer, Decimal, Boolean, Array, Range)error: Error types with location information
Multi-Platform Support
WASM (WebAssembly)
Build for browser and Node.js environments:
# Using wasm-pack
# JavaScript usage
;
);
);
Examples:
../../examples/gram-codec-wasm-web/- Interactive browser demo with UI../../examples/gram-codec-wasm-node/- Node.js command-line examples
Python
Build and install Python bindings:
# Python usage
)
)
Examples:
../../examples/gram-codec-python/demo.py- Interactive demo with REPL mode../../examples/gram-codec-python/quickstart.py- Quick 5-minute introduction../../examples/gram-codec-python/gram_codec.py- Template with 10 example functions
See pyproject.toml for packaging configuration.
Performance
The codec includes comprehensive benchmarks:
# Run all benchmarks
# Specific benchmarks
Benchmarks cover:
- Parsing simple nodes (10, 100, 1000 patterns)
- Parsing relationships and chains
- Parsing subject patterns with many elements
- Serialization (single and multiple patterns)
- Round-trip correctness (parse → serialize → parse)
- Complex patterns with mixed syntax
License
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Contributing
Contributions are welcome! Please ensure:
- All tests pass:
cargo test --package gram-codec - Code is formatted:
cargo fmt --all - No clippy warnings:
cargo clippy --package gram-codec -- -D warnings - Examples run successfully