1use super::expr::{GrammarExpr, GrammarExprType};
13use crate::fsm::{CompactFsm, CompactFsmWithStartEnd};
14
15#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct Rule {
19 pub name: String,
21 pub body_expr_id: i32,
23 pub lookahead_assertion_id: i32,
26 pub is_exact_lookahead: bool,
28}
29
30impl Rule {
31 pub fn new(name: impl Into<String>, body_expr_id: i32) -> Self {
33 Self {
34 name: name.into(),
35 body_expr_id,
36 lookahead_assertion_id: -1,
37 is_exact_lookahead: false,
38 }
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct TagDispatch {
46 pub tag_rule_pairs: Vec<(String, i32)>,
48 pub stop_eos: bool,
50 pub stop_str: Vec<String>,
52 pub loop_after_dispatch: bool,
54 pub excluded_str: Vec<String>,
56}
57
58const TAG_DISPATCH_EXTRA: usize = 4;
62
63#[derive(Debug, Clone, Default)]
70pub struct GrammarData {
71 rules: Vec<Rule>,
73 expr_data: Vec<i32>,
75 expr_indptr: Vec<i32>,
77 root_rule_id: i32,
79 pub allow_empty_rule_ids: Vec<i32>,
81 pub optimized: bool,
83 pub complete_fsm: CompactFsm,
86 pub per_rule_fsms: Vec<Option<CompactFsmWithStartEnd>>,
89 pub per_rule_fsm_hashes: Vec<Option<u64>>,
92 pub per_rule_fsm_new_state_ids: Vec<Vec<(i32, i32)>>,
95}
96
97impl GrammarData {
98 pub fn new() -> Self {
100 Self {
101 root_rule_id: -1,
102 ..Default::default()
103 }
104 }
105
106 pub fn from_parts(
109 rules: Vec<Rule>,
110 expr_data: Vec<i32>,
111 expr_indptr: Vec<i32>,
112 root_rule_id: i32,
113 ) -> Self {
114 Self {
115 rules,
116 expr_data,
117 expr_indptr,
118 root_rule_id,
119 ..Default::default()
120 }
121 }
122
123 pub fn set_rule_name(&mut self, rule_id: i32, name: impl Into<String>) {
125 self.rules[rule_id as usize].name = name.into();
126 }
127
128 pub fn set_expr_data(&mut self, expr_id: i32, index: usize, value: i32) {
131 let start = self.expr_indptr[expr_id as usize] as usize;
132 self.expr_data[start + 2 + index] = value;
133 }
134
135 pub fn num_rules(&self) -> i32 {
137 self.rules.len() as i32
138 }
139
140 pub fn rule(&self, rule_id: i32) -> &Rule {
143 &self.rules[rule_id as usize]
144 }
145
146 pub fn rule_mut(&mut self, rule_id: i32) -> &mut Rule {
148 &mut self.rules[rule_id as usize]
149 }
150
151 pub fn rules(&self) -> &[Rule] {
153 &self.rules
154 }
155
156 pub fn root_rule_id(&self) -> i32 {
158 self.root_rule_id
159 }
160
161 pub fn set_root_rule_id(&mut self, id: i32) {
163 self.root_rule_id = id;
164 }
165
166 pub fn root_rule(&self) -> &Rule {
168 &self.rules[self.root_rule_id as usize]
169 }
170
171 pub fn num_exprs(&self) -> i32 {
173 self.expr_indptr.len() as i32
174 }
175
176 pub fn append_expr(&mut self, kind: GrammarExprType, data: &[i32]) -> i32 {
180 self.expr_indptr.push(self.expr_data.len() as i32);
181 self.expr_data.push(kind as i32);
182 self.expr_data.push(data.len() as i32);
183 self.expr_data.extend_from_slice(data);
184 self.expr_indptr.len() as i32 - 1
185 }
186
187 pub fn expr(&self, expr_id: i32) -> GrammarExpr<'_> {
190 let start = self.expr_indptr[expr_id as usize] as usize;
191 let kind = GrammarExprType::from_i32(self.expr_data[start])
192 .expect("corrupt grammar: unknown GrammarExprType tag");
193 let data_len = self.expr_data[start + 1] as usize;
194 let data = &self.expr_data[start + 2..start + 2 + data_len];
195 GrammarExpr { kind, data }
196 }
197
198 pub fn byte_string(&self, expr_id: i32) -> String {
200 let e = self.expr(expr_id);
201 e.data.iter().map(|&b| (b as u8) as char).collect()
202 }
203
204 pub fn tag_dispatch(&self, expr_id: i32) -> TagDispatch {
207 let e = self.expr(expr_id);
208 assert_eq!(
209 e.kind,
210 GrammarExprType::TagDispatch,
211 "expr {expr_id} is not a TagDispatch"
212 );
213 let n = e.len();
214 assert!(n >= TAG_DISPATCH_EXTRA, "TagDispatch payload too short");
215 let pair_end = n - TAG_DISPATCH_EXTRA;
216
217 let mut tag_rule_pairs = Vec::with_capacity(pair_end / 2);
218 let mut i = 0;
219 while i < pair_end {
220 let tag = self.byte_string(e[i]);
221 let rule_id = e[i + 1];
222 tag_rule_pairs.push((tag, rule_id));
223 i += 2;
224 }
225
226 let stop_eos = e[pair_end] != 0;
227 let stop_str = self.choices_of_byte_strings(e[pair_end + 1]);
228 let loop_after_dispatch = e[pair_end + 2] != 0;
229 let excluded_str = self.choices_of_byte_strings(e[pair_end + 3]);
230
231 TagDispatch {
232 tag_rule_pairs,
233 stop_eos,
234 stop_str,
235 loop_after_dispatch,
236 excluded_str,
237 }
238 }
239
240 fn choices_of_byte_strings(&self, expr_id: i32) -> Vec<String> {
243 let e = self.expr(expr_id);
244 assert_eq!(e.kind, GrammarExprType::Choices, "expected a Choices expr");
245 e.data.iter().map(|&id| self.byte_string(id)).collect()
246 }
247}
248
249#[cfg(test)]
250mod tests {
251 use super::*;
252
253 fn byte_string_grammar() -> GrammarData {
256 let expr_data = vec![
257 GrammarExprType::ByteString as i32,
258 2,
259 b'a' as i32,
260 b'b' as i32,
261 ];
262 let expr_indptr = vec![0];
263 let rules = vec![Rule::new("root", 0)];
264 GrammarData::from_parts(rules, expr_data, expr_indptr, 0)
265 }
266
267 #[test]
268 fn expr_view_decodes_csr() {
269 let g = byte_string_grammar();
270 assert_eq!(g.num_rules(), 1);
271 assert_eq!(g.num_exprs(), 1);
272 let e = g.expr(0);
273 assert_eq!(e.kind, GrammarExprType::ByteString);
274 assert_eq!(e.data, &[b'a' as i32, b'b' as i32]);
275 }
276
277 #[test]
278 fn byte_string_decodes() {
279 assert_eq!(byte_string_grammar().byte_string(0), "ab");
280 }
281
282 #[test]
283 fn root_rule_resolves() {
284 let g = byte_string_grammar();
285 assert_eq!(g.root_rule_id(), 0);
286 assert_eq!(g.root_rule().name, "root");
287 assert_eq!(g.root_rule().body_expr_id, 0);
288 }
289}