| name | gram-lint |
| description | Validates gram notation files (*.gram) using the gram-lint CLI tool. Use when creating, editing, or reviewing any *.gram file, when a gram parse error is suspected, or when asked to validate graph data files in this project. |
gram-lint
When to Use
Run gram-lint after every write to a *.gram file. If a gram file fails to
parse, fix the syntax error before committing.
Usage
gram-lint path/to/file.gram
gram-lint **/*.gram
gram-lint $(find . -name "*.gram" -not -path "*/node_modules/*")
gram-lint -e '(alice:Person {name: "Alice"})-[:KNOWS]->(bob:Person)'
gram-lint --tree path/to/file.gram
Exit code 0 = valid. Non-zero = parse error; stderr contains the location and
description.
Gram Syntax Quick Reference
// Document header (optional, must be first)
{ kind: "data", version: "1.0" }
// Node
(alice:Person {name: "Alice Hoffman", title: "Staff Engineer"})
// Relationship
(alice)-[r1:KNOWS {since: 2023}]->(bob)
// Anonymous relationship
(alice)-[:KNOWS]->(bob)
// Annotation (metadata wrapper, does not change the node)
@color("#4A90D9") @pos({x: 120, y: 200}) (alice:Person {name: "Alice"})
// Subgraph / grouping
[team:Team {name: "Engineering"} | alice, bob, carol]
// Metadata wrapper on a relationship
[{curve: 0.2} | r1]
// Multi-hop path
(alice)-[:KNOWS]->(bob)-[:KNOWS]->(carol)
// Comment
// this is a comment
Common Syntax Rules
- Node identities start with a letter or
_; may contain digits, ., -, @.
- Labels follow a
: after the identity: (n:Person), (n:Person:Employee).
- Properties use
{key: value} โ values may be strings, numbers, booleans,
arrays of scalars, or maps of scalars.
[] is not a valid empty array โ { tags: [] } is a parse error.
- Each identity may only be defined once per file; subsequent uses are references.
- Forward references (using an identity before its definition) are allowed.
- Arrow families
--, ==, ~~ are semantically equivalent; choose one per file.
:: label separator is stylistically equivalent to : (use for schema files).
Value Types
| Syntax | Type |
|---|
42, -7 | Integer |
3.14 | Decimal |
0xFF | Hexadecimal |
true / false | Boolean |
"text", 'text', `text` | String |
5m, 10kg | Measurement (unit suffix, no space) |
1..10, 1..., ...10 | Range |
[1, 2, 3] | Array (scalars only, non-empty) |
{k: "v"} | Map (scalars only) |
Fixing Common Errors
| Error | Likely cause | Fix |
|---|
Unexpected token at [] | Empty array literal | Use a non-empty array or omit the property |
| Duplicate identity | Same id defined twice | Rename one, or use a bare reference for the second occurrence |
Unexpected ) | Mismatched brackets | Check that every ( has a matching ) and every [ has ] |
| Invalid property value | Nested map/array too deep | Maps may only contain scalar values; arrays may only contain scalars |
File Conventions in This Project
- Data files:
*.gram
- Schema files:
*.schema.gram (use :: labels and == arrows by convention)
- All gram files MUST pass
gram-lint before commit.