metrale_grammar/grammar/
builder.rs1use std::cell::RefCell;
17use std::collections::HashMap;
18
19use super::data::{GrammarData, Rule};
20use super::expr::{GrammarExpr, GrammarExprType};
21
22#[path = "builder_rules.rs"]
23mod rules;
24#[cfg(test)]
25#[path = "builder_tests.rs"]
26mod tests;
27
28pub use rules::BuilderError;
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub struct CharacterClassElement {
34 pub lower: i32,
36 pub upper: i32,
38}
39
40impl CharacterClassElement {
41 pub fn new(lower: i32, upper: i32) -> Self {
43 Self { lower, upper }
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Default)]
51pub struct TagDispatchSpec {
52 pub tag_rule_pairs: Vec<(String, i32)>,
54 pub stop_eos: bool,
56 pub stop_str: Vec<String>,
58 pub loop_after_dispatch: bool,
60 pub excluded_str: Vec<String>,
62}
63
64#[derive(Debug, Default)]
69pub struct GrammarBuilder {
70 rules: Vec<Rule>,
71 expr_data: Vec<i32>,
72 expr_indptr: Vec<i32>,
73 rule_name_to_id: HashMap<String, i32>,
74 next_cnt_per_hint: RefCell<HashMap<String, i32>>,
84}
85
86impl GrammarBuilder {
87 pub fn new() -> Self {
89 Self::default()
90 }
91
92 pub(super) fn rules_vec(&self) -> &[Rule] {
95 &self.rules
96 }
97 pub(super) fn rules_vec_mut(&mut self) -> &mut Vec<Rule> {
98 &mut self.rules
99 }
100 pub(super) fn rule_name_to_id(&self) -> &HashMap<String, i32> {
101 &self.rule_name_to_id
102 }
103 pub(super) fn rule_name_to_id_mut(&mut self) -> &mut HashMap<String, i32> {
104 &mut self.rule_name_to_id
105 }
106 pub(super) fn next_cnt_per_hint(&self) -> &RefCell<HashMap<String, i32>> {
107 &self.next_cnt_per_hint
108 }
109
110 pub fn get(self, root_rule_name: &str) -> Result<GrammarData, BuilderError> {
115 let root_rule_id = self.get_rule_id(root_rule_name);
116 if root_rule_id == -1 {
117 return Err(BuilderError::RootRuleNotFound(root_rule_name.to_string()));
118 }
119 self.get_by_id(root_rule_id)
120 }
121
122 pub fn get_by_id(self, root_rule_id: i32) -> Result<GrammarData, BuilderError> {
127 if root_rule_id < 0 || root_rule_id >= self.rules.len() as i32 {
128 return Err(BuilderError::RootRuleOutOfBounds(root_rule_id));
129 }
130 Ok(GrammarData::from_parts(
131 self.rules,
132 self.expr_data,
133 self.expr_indptr,
134 root_rule_id,
135 ))
136 }
137
138 pub fn add_grammar_expr(&mut self, kind: GrammarExprType, data: &[i32]) -> i32 {
143 self.expr_indptr.push(self.expr_data.len() as i32);
144 self.expr_data.push(kind as i32);
145 self.expr_data.push(data.len() as i32);
146 self.expr_data.extend_from_slice(data);
147 self.expr_indptr.len() as i32 - 1
148 }
149
150 pub fn add_byte_string_bytes(&mut self, bytes: &[i32]) -> i32 {
152 self.add_grammar_expr(GrammarExprType::ByteString, bytes)
153 }
154
155 pub fn add_byte_string(&mut self, s: &str) -> i32 {
157 let bytes: Vec<i32> = s.bytes().map(|b| b as i32).collect();
158 self.add_grammar_expr(GrammarExprType::ByteString, &bytes)
159 }
160
161 fn char_class_data(elements: &[CharacterClassElement], is_negative: bool) -> Vec<i32> {
164 let mut data = Vec::with_capacity(1 + elements.len() * 2);
165 data.push(is_negative as i32);
166 for r in elements {
167 data.push(r.lower);
168 data.push(r.upper);
169 }
170 data
171 }
172
173 pub fn add_character_class(
175 &mut self,
176 elements: &[CharacterClassElement],
177 is_negative: bool,
178 ) -> i32 {
179 let data = Self::char_class_data(elements, is_negative);
180 self.add_grammar_expr(GrammarExprType::CharacterClass, &data)
181 }
182
183 pub fn add_character_class_star(
185 &mut self,
186 elements: &[CharacterClassElement],
187 is_negative: bool,
188 ) -> i32 {
189 let data = Self::char_class_data(elements, is_negative);
190 self.add_grammar_expr(GrammarExprType::CharacterClassStar, &data)
191 }
192
193 pub fn add_empty_str(&mut self) -> i32 {
195 self.add_grammar_expr(GrammarExprType::EmptyStr, &[])
196 }
197
198 pub fn add_rule_ref(&mut self, rule_id: i32) -> i32 {
200 self.add_grammar_expr(GrammarExprType::RuleRef, &[rule_id])
201 }
202
203 pub fn add_sequence(&mut self, elements: &[i32]) -> i32 {
205 self.add_grammar_expr(GrammarExprType::Sequence, elements)
206 }
207
208 pub fn add_choices(&mut self, choices: &[i32]) -> i32 {
210 self.add_grammar_expr(GrammarExprType::Choices, choices)
211 }
212
213 pub fn add_repeat(&mut self, ref_rule_id: i32, min_repeat: i32, max_repeat: i32) -> i32 {
215 self.add_grammar_expr(
216 GrammarExprType::Repeat,
217 &[ref_rule_id, min_repeat, max_repeat],
218 )
219 }
220
221 pub fn add_tag_dispatch(&mut self, spec: &TagDispatchSpec) -> i32 {
225 let mut data: Vec<i32> = Vec::with_capacity(spec.tag_rule_pairs.len() * 2 + 4);
226 for (tag, rule_id) in &spec.tag_rule_pairs {
227 let tag_expr = self.add_byte_string(tag);
228 data.push(tag_expr);
229 data.push(*rule_id);
230 }
231 data.push(spec.stop_eos as i32);
232 let stop_ids: Vec<i32> = spec
233 .stop_str
234 .iter()
235 .map(|s| self.add_byte_string(s))
236 .collect();
237 data.push(self.add_choices(&stop_ids));
238 data.push(spec.loop_after_dispatch as i32);
239 let excl_ids: Vec<i32> = spec
240 .excluded_str
241 .iter()
242 .map(|s| self.add_byte_string(s))
243 .collect();
244 data.push(self.add_choices(&excl_ids));
245 self.add_grammar_expr(GrammarExprType::TagDispatch, &data)
246 }
247
248 pub fn num_grammar_exprs(&self) -> i32 {
250 self.expr_indptr.len() as i32
251 }
252
253 pub fn get_grammar_expr(&self, expr_id: i32) -> GrammarExpr<'_> {
256 let start = self.expr_indptr[expr_id as usize] as usize;
257 let kind = GrammarExprType::from_i32(self.expr_data[start])
258 .expect("corrupt builder state: unknown GrammarExprType tag");
259 let data_len = self.expr_data[start + 1] as usize;
260 let data = &self.expr_data[start + 2..start + 2 + data_len];
261 GrammarExpr { kind, data }
262 }
263}