parol_runtime/parser_common/
parse_tree_stack.rs1use std::fmt::{Display, Error, Formatter};
2
3use log::trace;
4
5#[derive(Debug, Default)]
7pub struct ParseTreeStack<T: Display> {
8 pub stack: Vec<T>,
10}
11
12impl<T: Display> ParseTreeStack<T> {
13 pub fn new() -> Self {
15 Self { stack: Vec::new() }
16 }
17
18 pub fn push(&mut self, node: T) {
20 trace!("ParseTreeStack: Pushing node: {node}");
21 self.stack.push(node);
22 }
23
24 pub fn pop(&mut self) -> Option<T> {
26 let node = self.stack.pop();
27 node.inspect(|n| {
28 trace!("LRParseTreeStack: Popping node: {n}");
29 })
30 }
31
32 pub fn last(&self) -> Option<&T> {
34 self.stack.last()
35 }
36
37 pub fn split_off(&mut self, at: usize) -> Vec<T> {
39 self.stack.split_off(at)
40 }
41
42 pub fn pop_n(&mut self, n: usize, f: impl Fn(&T) -> bool) -> Vec<T> {
47 let mut len = 0;
49 let mut i = 0;
51 while i < n && len < self.stack.len() {
52 if f(&self.stack[self.stack.len() - 1 - len]) {
55 i += 1;
57 }
58 len += 1;
60 }
61 if len > self.stack.len() {
63 len = self.stack.len();
64 }
65 self.split_off(self.stack.len() - len)
67 }
68
69 pub fn len(&self) -> usize {
71 self.stack.len()
72 }
73
74 pub fn is_empty(&self) -> bool {
76 self.stack.is_empty()
77 }
78
79 pub(crate) fn pop_all(&mut self) -> Vec<T> {
81 let mut stack = Vec::new();
83 std::mem::swap(&mut stack, &mut self.stack);
84 stack
85 }
86}
87
88impl<T: Display> Display for ParseTreeStack<T> {
89 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
90 self.stack
91 .iter()
92 .rev()
93 .enumerate()
94 .try_for_each(|(i, e)| writeln!(f, "{i} - {e}"))
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 fn init() {
103 let _ = env_logger::builder().is_test(true).try_init();
104 }
105
106 #[test]
107 fn test_push_pop() {
108 init();
109 let mut stack = ParseTreeStack::new();
110 stack.push("a");
111 stack.push("b");
112 stack.push("c");
113 assert_eq!(stack.pop(), Some("c"));
114 assert_eq!(stack.pop(), Some("b"));
115 assert_eq!(stack.pop(), Some("a"));
116 assert_eq!(stack.pop(), None);
117 }
118
119 #[test]
120 fn test_split_off() {
121 init();
122 let mut stack = ParseTreeStack::new();
123 stack.push("a");
124 stack.push("b");
125 stack.push("c");
126 stack.push("d");
127 stack.push("e");
128 let split = stack.split_off(2);
129 assert_eq!(split, vec!["c", "d", "e"]);
130 assert_eq!(stack.stack, vec!["a", "b"]);
131 }
132
133 #[test]
134 fn test_pop_3() {
135 init();
136 let mut stack = ParseTreeStack::new();
137 stack.push("a");
138 stack.push("b");
139 stack.push("c");
140 stack.push("d");
141 stack.push("e");
142 let split = stack.pop_n(3, |_| true);
143 assert_eq!(split, vec!["c", "d", "e"]);
144 assert_eq!(stack.stack, vec!["a", "b"]);
145 }
146
147 #[test]
148 fn test_pop_5() {
149 init();
150 let mut stack = ParseTreeStack::new();
151 stack.push("a");
152 stack.push("b");
153 stack.push("c");
154 stack.push("d");
155 stack.push("e");
156 let split = stack.pop_n(3, |_| false);
157 assert_eq!(split, vec!["a", "b", "c", "d", "e"]);
158 assert_eq!(stack.stack, Vec::<&str>::new());
159 }
160
161 #[test]
162 fn test_pop_n() {
163 init();
164 let mut stack = ParseTreeStack::new();
165 stack.push("a");
166 stack.push("b");
167 stack.push("c");
168 stack.push("d");
169 stack.push("e");
170 let split = stack.pop_n(3, |n| *n != "d");
172 assert_eq!(split, vec!["b", "c", "d", "e"]);
174 assert_eq!(stack.stack, vec!["a"]);
175 }
176}