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}