1use std::iter;
2use std::borrow::Borrow;
3
4use bit_vec::BitVec;
5use cfg::symbol::Symbol;
6
7use grammar::InternalGrammar;
8use super::Bocage;
9use super::node::{NodeHandle, Node, Iter, Tag};
10use super::node::Node::*;
11
12pub use self::HandleVariant::*;
13
14impl<G> Bocage<G> {
15 pub fn traverse(&self) -> Traverse<G> {
17 Traverse {
18 bocage: self,
19 graph_iter: self.graph.iter_from(NodeHandle(0)),
20 liveness: &self.gc.liveness,
21 factor_stack: vec![],
22 factor_traversal: vec![],
23 }
24 }
25}
26
27pub struct Traverse<'f, G> {
28 bocage: &'f Bocage<G>,
29 graph_iter: Iter<'f>,
31 liveness: &'f BitVec,
32 factor_stack: Vec<(Symbol, NodeHandle)>,
34 factor_traversal: Vec<NodeHandle>,
36}
37
38impl<'f, G> Traverse<'f, G>
39 where G: Borrow<InternalGrammar>,
40{
41 pub fn next_node<'t>(&'t mut self) -> Option<TraversalHandle<'f, 't, G>> {
42 while let Some(node) = self.graph_iter.peek() {
43 let iter = self.graph_iter;
44 let alive = self.liveness[self.graph_iter.handle.usize()];
45 println!("next_node @{:?} {:?} {}", self.graph_iter.handle, node, alive);
46 self.graph_iter.next();
47 if !alive {
48 continue;
49 }
50 match node {
51 Product { action, .. } => {
52 if self.bocage.is_transparent(action) {
53 continue;
54 }
55 let products = iter.take(1);
56 return Some(TraversalHandle {
57 iter,
58 symbol: self.bocage.grammar.borrow().get_lhs(action),
59 item: SumHandle(Products {
60 products,
61 traverse: self,
62 }),
63 });
64 }
65 Sum { nonterminal: symbol, count } => {
66 let products = self.graph_iter.take(count as usize);
67 for _ in 0..count {
68 let p = self.graph_iter.handle;
69 let n = self.graph_iter.next();
70 println!("next_node product @{:?} {:?}", p, n);
71 }
72 return Some(TraversalHandle {
73 iter,
74 symbol,
75 item: SumHandle(Products {
76 products,
77 traverse: self,
78 }),
79 });
80 }
81 NullingLeaf { symbol } => {
82 return Some(TraversalHandle {
83 iter,
84 symbol,
85 item: NullingHandle,
86 });
87 }
88 Evaluated { symbol, .. } => {
89 return Some(TraversalHandle {
90 iter,
91 symbol,
92 item: LeafHandle,
93 });
94 }
95 }
96 }
97 None
98 }
99
100 fn unfold_factors(&mut self, left: NodeHandle, right: Option<NodeHandle>) {
101 self.factor_stack.clear();
102 self.enqueue_for_unfold(left, right);
103 while let Some(node) = self.pop_for_unfold() {
104 match node {
105 (Product { left_factor, right_factor, .. }, _) => {
106 self.enqueue_for_unfold(left_factor, right_factor);
107 }
108 (Evaluated { symbol }, handle) => {
109 self.factor_stack.push((symbol, handle));
110 }
111 _ => unreachable!()
112 }
113 }
114 }
115
116 fn enqueue_for_unfold(&mut self, left: NodeHandle, right: Option<NodeHandle>) {
117 if let Some(right) = right {
118 self.factor_traversal.push(right);
119 }
120 self.factor_traversal.push(left);
121 }
122
123 fn pop_for_unfold(&mut self) -> Option<(Node, NodeHandle)> {
124 self.factor_traversal.pop().map(|handle| {
125 (self.bocage.graph.get(handle), handle)
126 })
127 }
128}
129
130pub struct TraversalHandle<'f, 't, G> {
131 pub(crate) iter: Iter<'f>,
132 pub symbol: Symbol,
133 pub item: HandleVariant<'f, 't, G>,
134}
135
136pub enum HandleVariant<'f, 't, G> {
137 SumHandle(Products<'f, 't, G>),
138 NullingHandle,
139 LeafHandle,
140}
141
142pub struct Products<'f, 't, G> {
143 products: iter::Take<Iter<'f>>,
144 traverse: &'t mut Traverse<'f, G>,
145}
146
147pub struct ProductHandle<'t> {
148 pub action: u32,
149 pub factors: &'t [(Symbol, NodeHandle)],
150}
151
152impl<'f, 't, G> Products<'f, 't, G>
153 where G: Borrow<InternalGrammar>,
154{
155 pub fn next_product<'p>(&'p mut self) -> Option<ProductHandle> {
156 while let Some(node) = self.products.next() {
157 match node {
158 Product { left_factor, right_factor, action } => {
159 let origin = self.traverse.bocage.grammar.borrow().external_origin(action);
160 if let Some(action) = origin {
161 self.traverse.unfold_factors(left_factor, right_factor);
162 return Some(ProductHandle {
163 action,
164 factors: &self.traverse.factor_stack[..],
165 });
166 }
167 }
168 _ => unreachable!()
169 }
170 }
171 None
172 }
173}
174
175impl<'f, 't, G> TraversalHandle<'f, 't, G> {
176 pub fn end_evaluation(&self) {
177 self.iter.vec[self.iter.handle.usize()].set(Tag::SmallLeafTag.to_u16());
178 }
179
180 pub fn handle(&self) -> NodeHandle {
181 self.iter.handle
182 }
183}