metrale_grammar/grammar/functor/
mutator.rs1use crate::grammar::builder::GrammarBuilder;
14use crate::grammar::data::{GrammarData, TagDispatch};
15use crate::grammar::expr::GrammarExprType;
16
17pub struct MutatorState {
20 pub base: GrammarData,
22 pub builder: GrammarBuilder,
24 pub cur_rule_name: String,
26}
27
28impl MutatorState {
29 pub fn new(grammar: GrammarData) -> Self {
31 Self {
32 base: grammar,
33 builder: GrammarBuilder::new(),
34 cur_rule_name: String::new(),
35 }
36 }
37}
38
39pub fn rebuild_tag_dispatch(builder: &mut GrammarBuilder, td: &TagDispatch) -> i32 {
42 use crate::grammar::builder::TagDispatchSpec;
43 let spec = TagDispatchSpec {
44 tag_rule_pairs: td.tag_rule_pairs.clone(),
45 stop_eos: td.stop_eos,
46 stop_str: td.stop_str.clone(),
47 loop_after_dispatch: td.loop_after_dispatch,
48 excluded_str: td.excluded_str.clone(),
49 };
50 builder.add_tag_dispatch(&spec)
51}
52
53pub trait GrammarMutator {
57 fn state(&mut self) -> &mut MutatorState;
59
60 fn apply(&mut self, grammar: GrammarData) -> GrammarData {
62 *self.state() = MutatorState::new(grammar);
63 let num_rules = self.state().base.num_rules();
64 for i in 0..num_rules {
65 let name = self.state().base.rule(i).name.clone();
66 self.state()
67 .builder
68 .add_empty_rule(name)
69 .expect("duplicate rule name");
70 }
71 for i in 0..num_rules {
72 let rule = self.state().base.rule(i).clone();
73 self.state().cur_rule_name = rule.name.clone();
74 let new_body = self.visit_expr_id(rule.body_expr_id);
75 self.state()
76 .builder
77 .update_rule_body(i, new_body)
78 .expect("rule id out of range");
79 let new_la = self.visit_lookahead(rule.lookahead_assertion_id);
80 self.state()
81 .builder
82 .update_lookahead_assertion(i, new_la)
83 .expect("rule id out of range");
84 }
85 let root_name = self.state().base.root_rule().name.clone();
86 let builder = std::mem::take(&mut self.state().builder);
87 builder.get(&root_name).expect("root rule not found")
88 }
89
90 fn visit_lookahead(&mut self, id: i32) -> i32 {
92 if id == -1 {
93 return -1;
94 }
95 self.visit_expr_id(id)
96 }
97
98 fn visit_expr_id(&mut self, id: i32) -> i32 {
100 let expr = self.state().base.owned_expr(id);
101 self.visit_expr(&expr)
102 }
103
104 fn visit_expr(&mut self, e: &OwnedExpr) -> i32 {
106 match e.kind {
107 GrammarExprType::Sequence => self.visit_sequence(e),
108 GrammarExprType::Choices => self.visit_choices(e),
109 GrammarExprType::EmptyStr => self.visit_empty_str(e),
110 GrammarExprType::ByteString => self.visit_byte_string(e),
111 GrammarExprType::CharacterClass => self.visit_character_class(e),
112 GrammarExprType::CharacterClassStar => self.visit_character_class_star(e),
113 GrammarExprType::RuleRef => self.visit_rule_ref(e),
114 GrammarExprType::TagDispatch => self.visit_tag_dispatch(e),
115 GrammarExprType::Repeat => self.visit_repeat(e),
116 }
117 }
118
119 fn visit_choices(&mut self, e: &OwnedExpr) -> i32 {
121 let ids: Vec<i32> = e.data.iter().map(|&c| self.visit_expr_id(c)).collect();
122 self.state().builder.add_choices(&ids)
123 }
124
125 fn visit_sequence(&mut self, e: &OwnedExpr) -> i32 {
127 let ids: Vec<i32> = e.data.iter().map(|&c| self.visit_expr_id(c)).collect();
128 self.state().builder.add_sequence(&ids)
129 }
130
131 fn visit_tag_dispatch(&mut self, e: &OwnedExpr) -> i32 {
133 let td = e.tag_dispatch.clone().expect("tag dispatch payload");
134 rebuild_tag_dispatch(&mut self.state().builder, &td)
135 }
136
137 fn visit_element(&mut self, e: &OwnedExpr) -> i32 {
139 self.state().builder.add_grammar_expr(e.kind, &e.data)
140 }
141
142 fn visit_empty_str(&mut self, e: &OwnedExpr) -> i32 {
144 self.visit_element(e)
145 }
146 fn visit_byte_string(&mut self, e: &OwnedExpr) -> i32 {
148 self.visit_element(e)
149 }
150 fn visit_character_class(&mut self, e: &OwnedExpr) -> i32 {
152 self.visit_element(e)
153 }
154 fn visit_character_class_star(&mut self, e: &OwnedExpr) -> i32 {
156 self.visit_element(e)
157 }
158 fn visit_rule_ref(&mut self, e: &OwnedExpr) -> i32 {
160 self.visit_element(e)
161 }
162 fn visit_repeat(&mut self, e: &OwnedExpr) -> i32 {
164 self.visit_element(e)
165 }
166}
167
168#[derive(Debug, Clone)]
171pub struct OwnedExpr {
172 pub kind: GrammarExprType,
174 pub data: Vec<i32>,
176 pub tag_dispatch: Option<TagDispatch>,
178}
179
180impl GrammarData {
181 pub(crate) fn owned_expr(&self, expr_id: i32) -> OwnedExpr {
183 let e = self.expr(expr_id);
184 let tag_dispatch = if e.kind == GrammarExprType::TagDispatch {
185 Some(self.tag_dispatch(expr_id))
186 } else {
187 None
188 };
189 OwnedExpr {
190 kind: e.kind,
191 data: e.data.to_vec(),
192 tag_dispatch,
193 }
194 }
195}