plotnik_compiler/parser/
mod.rs

1//! Parser infrastructure for the query language.
2//!
3//! # Architecture
4//!
5//! This parser produces a lossless concrete syntax tree (CST) via Rowan's green tree builder.
6//! Key design decisions borrowed from rust-analyzer, rnix-parser, and taplo:
7//!
8//! - Zero-copy parsing: tokens carry spans, text sliced only when building tree nodes
9//! - Trivia buffering: whitespace/comments collected, then attached as leading trivia
10//! - Checkpoint-based wrapping: retroactively wrap nodes for quantifiers `*+?`
11//! - Explicit recovery sets: per-production sets determine when to bail vs consume diagnostics
12//!
13//! # Recovery Strategy
14//!
15//! The parser is resilient — it always produces a tree. Recovery follows these rules:
16//!
17//! 1. Unknown tokens get wrapped in `SyntaxKind::Error` nodes and consumed
18//! 2. Missing expected tokens emit a diagnostic but don't consume (parent may handle)
19//! 3. Recovery sets define "synchronization points" per production
20//! 4. On recursion limit, remaining input goes into single Error node
21//!
22//! However, fuel exhaustion (exec_fuel, recursion_fuel) returns an actual error immediately.
23
24pub mod ast;
25mod cst;
26mod lexer;
27
28mod core;
29mod grammar;
30mod invariants;
31
32#[cfg(test)]
33mod ast_tests;
34#[cfg(test)]
35mod cst_tests;
36#[cfg(test)]
37mod lexer_tests;
38#[cfg(test)]
39mod tests;
40
41pub use cst::{SyntaxKind, SyntaxNode, SyntaxToken};
42
43pub use ast::{
44    AltExpr, AltKind, Anchor, AnonymousNode, Branch, CapturedExpr, Def, Expr, FieldExpr, NamedNode,
45    NegatedField, NodePredicate, PredicateOp, PredicateValue, QuantifiedExpr, Ref, RegexLiteral,
46    Root, SeqExpr, SeqItem, Type, is_truly_empty_scope, token_src,
47};
48
49pub use core::{ParseResult, Parser};
50
51pub use lexer::{Token, lex, token_text};