Skip to main content

sim_shape/grammar/
graph.rs

1//! Codec-neutral grammar graph records.
2
3use sim_kernel::{Diagnostic, Expr, Symbol};
4
5/// A codec-neutral grammar production.
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub enum Production {
8    /// A literal or lexeme class named abstractly; renderers supply concrete
9    /// terminals for the requested codec surface.
10    Terminal(TerminalAtom),
11    /// Ordered child productions.
12    Seq(Vec<Production>),
13    /// One-of-many child productions.
14    Alt(Vec<Production>),
15    /// Repetition of an inner production.
16    Repeat {
17        /// The repeated production.
18        inner: Box<Production>,
19        /// Minimum number of accepted repetitions.
20        at_least: usize,
21    },
22    /// A call-like form with a head and positional argument productions.
23    Call {
24        /// The rendered call head.
25        head: Box<Production>,
26        /// The rendered positional arguments.
27        args: Vec<Production>,
28    },
29    /// Reference to a named production in the graph definitions.
30    Ref(Symbol),
31}
32
33/// Abstract terminal atoms that concrete renderers map to their own syntax.
34#[derive(Clone, Debug, PartialEq, Eq)]
35pub enum TerminalAtom {
36    /// Any value accepted by the target surface.
37    Any,
38    /// A symbol token.
39    Symbol,
40    /// A string token.
41    String,
42    /// A number token.
43    Number,
44    /// A boolean token.
45    Bool,
46    /// The nil/null token.
47    Nil,
48    /// An array/list form.
49    List,
50    /// A map/object form.
51    Map,
52    /// One exact expression literal.
53    Exact(Expr),
54}
55
56/// A named codec-neutral grammar graph.
57#[derive(Clone, Debug, PartialEq, Eq)]
58pub struct GrammarGraph {
59    /// The root production.
60    pub root: Production,
61    /// Named productions referenced by [`Production::Ref`].
62    pub defs: Vec<(Symbol, Production)>,
63    /// Diagnostics emitted during lowering.
64    pub diagnostics: Vec<Diagnostic>,
65}
66
67impl GrammarGraph {
68    /// Builds a graph with `root`, no named definitions, and no diagnostics.
69    pub fn new(root: Production) -> Self {
70        Self {
71            root,
72            defs: Vec::new(),
73            diagnostics: Vec::new(),
74        }
75    }
76}
77
78/// The concrete grammar dialect requested by a renderer.
79#[derive(Clone, Copy, Debug, PartialEq, Eq)]
80pub enum GrammarDialect {
81    /// JSON Schema.
82    JsonSchema,
83    /// GBNF.
84    Gbnf,
85    /// S-expression grammar.
86    SExpr,
87}
88
89/// Output position for a grammar-rendered form.
90#[derive(Clone, Copy, Debug, PartialEq, Eq)]
91pub enum GrammarPosition {
92    /// Evaluation position.
93    Eval,
94    /// Quoted position.
95    Quote,
96    /// Data position.
97    Data,
98    /// Pattern position.
99    Pattern,
100    /// Surface/view position.
101    Surface,
102}
103
104/// Target metadata for one rendered grammar.
105#[derive(Clone, Debug, PartialEq, Eq)]
106pub struct GrammarTarget {
107    /// The codec symbol this grammar targets.
108    pub codec: Symbol,
109    /// The concrete grammar dialect.
110    pub dialect: GrammarDialect,
111    /// The output position interpreted by the codec renderer.
112    pub position: GrammarPosition,
113}
114
115/// Rendered grammar text plus its neutral graph and diagnostics.
116#[derive(Clone, Debug, PartialEq, Eq)]
117pub struct ShapeGrammar {
118    /// Target metadata used to render `text`.
119    pub target: GrammarTarget,
120    /// The source codec-neutral graph.
121    pub graph: GrammarGraph,
122    /// Rendered grammar text.
123    pub text: String,
124    /// Diagnostics emitted during lowering or rendering.
125    pub diagnostics: Vec<Diagnostic>,
126}