Developer API
Parser API.
The KGL parser converts .kgl files into structured Python dataclasses. It is a single-pass, line-oriented state machine that handles all current KGL syntax. Errors are non-fatal — parsing continues after a bad line.
Public API
from kgl.parser import parse_file, parse_string
# Parse a file on disk
result = parse_file("people/alice.kgl")
# Parse a string directly
result = parse_string("""
@Person Alice Nguyen
joined: 2021-03-15
#backend #python
[mentors] → people/diana.kgl#Diana Park
started: 2023-06
""")
# result.nodes — list[RawNode]
# result.errors — list[ParseError]
Both functions return a ParseResult. If a line cannot be parsed, a ParseError is recorded and parsing continues from the next line.
Data structures
RawNode
Represents one node declaration in a .kgl file.
@dataclass
class RawNode:
source_file: str # path to the file this node was parsed from
types: list[str] # e.g. ["Person", "Contractor"] from @Person|Contractor
name: str # everything after the type(s)
fields: dict[str, str] # key: value pairs
tags: list[str] # #tag tokens (without the leading #)
links: list[RawLink] # all links declared in this node
body: str | None # free-form text after ---
line_number: int # line number of the @Type declaration (for linter)
RawLink
Represents one link declaration within a node.
@dataclass
class RawLink:
link_type: str # "hard" | "soft" | "named"
rel_types: list[str] # e.g. ["depends-on", "replaces"] or [] for bare links
target_file: str # e.g. "people/alice.kgl" (relative path)
target_node: str | None # fragment anchor e.g. "Alice Nguyen", or None
properties: list[RawRelProp] # indented key: value pairs after the link
RawRelProp
@dataclass
class RawRelProp:
key: str
value: str
ParseResult
@dataclass
class ParseResult:
nodes: list[RawNode]
errors: list[ParseError]
ParseError
@dataclass
class ParseError:
file: str
line: int
message: str
Syntax handled
| Syntax | Example |
|---|---|
| Single-type node | @Person Alice Nguyen |
| Multi-type node | @Person|Contractor Alice Nguyen |
| Field | joined: 2021-03-15 |
| Tag | #backend #python |
| Hard link | → projects/search.kgl |
| Hard link (ASCII) | -> projects/search.kgl |
| Soft link | ~> teams/platform.kgl |
| Named relationship | [mentors] → people/diana.kgl#Diana Park |
| Multi-type relationship | [depends-on|replaces] → projects/old.kgl |
| Fragment anchor | → people/diana.kgl#Diana Park |
| Relationship properties | Indented key: value lines after a link |
| Body text | Free-form prose after --- |
| Comment | Lines starting with # (not followed by tag characters) |
Pipeline
The parser is the first stage of the KGL pipeline. Raw parsed output flows through three further stages before reaching an in-memory graph ready for querying:
parse_file / parse_string
↓
ParseResult (list[RawNode])
↓
Loader (Step 3a) — walks directory, calls parse_file on each .kgl file
↓
Resolver (Step 3b) — resolves RawLink targets into concrete Node/Edge pairs
↓
Graph (Step 3c) — immutable container; GraphQuery for traversal
See Graph Model for the Loader and Resolver documentation.