Skip to main content

earley_omnitool/
events.rs

1use std::iter::{Zip, Chain};
2use std::slice;
3
4use bit_matrix;
5use cfg::symbol::Symbol;
6
7use forest::Forest;
8use grammar::{ExternalDottedRule, Event};
9use item::Item;
10use recognizer::Recognizer;
11
12type IterPredictionBitfield<'a> = bit_matrix::row::Iter<'a>;
13
14pub struct PredictedSymbols<'a> {
15    pub(in super) iter: IterPredictionBitfield<'a>,
16    pub(in super) idx: usize,
17}
18
19pub struct MedialItems<'a, N: 'a> {
20    pub(in super) iter: slice::Iter<'a, Item<N>>,
21}
22
23pub struct Prediction<'a, T: 'a> {
24    iter: Zip<IterPredictionBitfield<'a>, slice::Iter<'a, T>>,
25    origin: usize,
26}
27
28pub struct Medial<'a, T: 'a, N: 'a> {
29    events: &'a [T],
30    items: MedialItems<'a, N>,
31}
32
33pub struct Events<'a, N: 'a> {
34    iter: Chain<
35        Prediction<'a, Event>,
36        Medial<'a, Event, N>
37    >
38}
39
40pub struct Distances<'a, N: 'a> {
41    iter: Chain<
42        Prediction<'a, Event>,
43        Medial<'a, Event, N>
44    >
45}
46
47pub struct Trace<'a, N: 'a> {
48    iter: Chain<
49        Prediction<'a, Option<ExternalDottedRule>>,
50        Medial<'a, Option<ExternalDottedRule>, N>
51    >
52}
53
54pub struct ExpectedTerminals<'a, N: 'a> {
55    prev_scan_iter: MedialItems<'a, N>,
56    rhs1: &'a [Option<Symbol>],
57}
58
59impl<'a> Iterator for PredictedSymbols<'a> {
60    type Item = Symbol;
61
62    fn next(&mut self) -> Option<Self::Item> {
63        for is_present in &mut self.iter {
64            let symbol = Symbol::from(self.idx);
65            self.idx += 1;
66            if is_present {
67                return Some(symbol);
68            }
69        }
70        None
71    }
72}
73
74impl<'a, N> Iterator for MedialItems<'a, N> {
75    type Item = &'a Item<N>;
76
77    fn next(&mut self) -> Option<Self::Item> {
78        self.iter.next()
79    }
80}
81
82impl<'a, T> Iterator for Prediction<'a, T> {
83    type Item = (&'a T, usize);
84
85    fn next(&mut self) -> Option<Self::Item> {
86        for (is_present, elem) in &mut self.iter {
87            if is_present {
88                return Some((elem, self.origin));
89            }
90        }
91        None
92    }
93}
94
95impl<'a, T, L> Iterator for Medial<'a, T, L> {
96    type Item = (&'a T, usize);
97
98    fn next(&mut self) -> Option<Self::Item> {
99        let events = &self.events;
100        self.items.next().map(|ei| {
101            (&events[ei.dot as usize], ei.origin as usize)
102        })
103    }
104}
105
106impl<'a, L> Iterator for Events<'a, L> {
107    type Item = u32;
108
109    fn next(&mut self) -> Option<u32> {
110        for (&(event_id, _distance), _origin) in &mut self.iter {
111            if event_id.is_some() {
112                return event_id.into();
113            }
114        }
115        None
116    }
117}
118
119impl<'a, L> Iterator for Distances<'a, L> {
120    type Item = u32;
121
122    fn next(&mut self) -> Option<u32> {
123        for (&(_event_id, distance), _origin) in &mut self.iter {
124            if distance.is_some() {
125                return distance.into();
126            }
127        }
128        None
129    }
130}
131
132impl<'a, N> Iterator for Trace<'a, N> {
133    type Item = (ExternalDottedRule, usize);
134
135    fn next(&mut self) -> Option<(ExternalDottedRule, usize)> {
136        for (&external_dr_opt, origin) in &mut self.iter {
137            if let Some(external_dotted_rule) = external_dr_opt {
138                return Some((external_dotted_rule, origin));
139            }
140        }
141        None
142    }
143}
144
145impl<'a, N> Iterator for ExpectedTerminals<'a, N> {
146    type Item = Symbol;
147
148    fn next(&mut self) -> Option<Self::Item> {
149        self.prev_scan_iter.next().map(|item| {
150            self.rhs1[item.dot as usize].unwrap()
151        })
152    }
153}
154
155impl<'g, F> Recognizer<'g, F>
156    where F: Forest,
157{
158    pub fn trace(&self) -> Trace<F::NodeRef> {
159        let trace = self.grammar.trace();
160        let prediction = Prediction {
161            iter: self.predicted_symbols().iter.zip(trace[0].iter()),
162            origin: self.earleme(),
163        };
164        let medial = Medial {
165            events: trace[1],
166            items: self.medial_items(),
167        };
168        Trace {
169            iter: prediction.chain(medial),
170        }
171    }
172
173    pub fn events(&self) -> Events<F::NodeRef> {
174        let (events_predict, events_flat) = self.grammar.events();
175        let prediction = Prediction {
176            iter: self.predicted_symbols().iter.zip(events_predict.iter()),
177            origin: self.earleme(),
178        };
179        let medial = Medial {
180            events: events_flat,
181            items: self.medial_items(),
182        };
183        Events {
184            iter: prediction.chain(medial),
185        }
186    }
187
188    pub fn minimal_distances(&self) -> Distances<F::NodeRef> {
189        Distances {
190            iter: self.events().iter,
191        }
192    }
193
194    pub fn expected_terminals(&self) -> ExpectedTerminals<F::NodeRef> {
195        ExpectedTerminals {
196            prev_scan_iter: self.medial_items(),
197            rhs1: self.grammar.rhs1(),
198        }
199    }
200}
201
202#[test]
203fn test_prediction_events() {
204    use bit_matrix::BitMatrix;
205    let mut bit_m = BitMatrix::new(1, 5);
206    bit_m.set(0, 2, true);
207    let mut row = bit_m.iter_row(0);
208    assert_eq!(row.next(), Some(false));
209    assert_eq!(row.next(), Some(false));
210    assert_eq!(row.next(), Some(true));
211    assert_eq!(row.next(), Some(false));
212    assert_eq!(row.next(), Some(false));
213    assert_eq!(row.next(), None);
214    let ev = [0, 1, 2, 3, 4];
215    let mut pred = Prediction {
216        iter: bit_m.iter_row(0).zip(&ev[0..5]),
217        origin: 123,
218    };
219    assert_eq!(pred.next(), Some((&2, 123)));
220    assert_eq!(pred.next(), None);
221}