1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use super::*;
use yggdrasil_error::Validation;
use yggdrasil_ir::rule::GrammarBody;
pub struct RefineRules {
grammar: GrammarInfo,
}
impl Default for RefineRules {
fn default() -> Self {
Self { grammar: Default::default() }
}
}
impl CodeOptimizer for RefineRules {
fn optimize(&mut self, info: &GrammarInfo) -> Validation<GrammarInfo> {
let mut errors = vec![];
self.grammar = info.clone();
let mut out = info.clone();
for rule in out.rules.values_mut() {
match &mut rule.body {
GrammarBody::Class { term } => match self.refine_node(term) {
Ok(_) => {}
Err(e) => errors.push(e),
},
GrammarBody::Union { branches } => {
for variant in branches.iter_mut() {
match self.refine_node(&mut variant.branch) {
Ok(_) => {}
Err(e) => errors.push(e),
}
}
}
GrammarBody::Climb { .. } => {}
}
}
Validation::Success { value: out, diagnostics: errors }
}
}
impl RefineRules {
fn refine_node(&mut self, node: &mut YggdrasilExpression) -> Result<(), YggdrasilError> {
match &mut node.body {
ExpressionBody::Choice(v) => {
if v.branches.len() == 1 {
let head = v.branches.pop().unwrap();
*node = head;
}
// for child in v.branches.iter_mut() {
// self.refine_node(child)?;
// }
// let (mut head, rest) = v.split();
// for term in rest {
// head |= term.clone();
// }
// *node = head
}
ExpressionBody::Concat(v) => {
if v.sequence.len() == 1 {
let head = v.sequence.pop().unwrap();
*node = head;
}
// for child in v.sequence.iter_mut() {
// self.refine_node(child)?;
// }
// let (mut head, rest) = v.split();
// for term in rest {
// head &= term.clone();
// }
// *node = head
}
ExpressionBody::Unary(v) => {
// TODO: marge operators,
// ** -> *
// ?* -> *
self.refine_node(&mut v.base)?
}
_ => {}
}
Ok(())
}
}