1use crate::{
2 builder::Builder, context::Context, input::Input, lexer::Token, location::Location,
3 parser::State,
4};
5use core::fmt::Debug;
6
7pub trait LRBuilder<'i, I, C, S, P, TK>: Builder
12where
13 I: Input + ?Sized,
14 C: Context<'i, I, S, TK>,
15 S: State,
16{
17 fn shift_action(&mut self, context: &C, token: Token<'i, I, TK>);
24
25 fn reduce_action(&mut self, context: &C, prod: P, prod_len: usize);
34}
35
36pub struct TreeBuilder<'i, I, P, TK>
38where
39 I: Input + ?Sized,
40{
41 res_stack: Vec<TreeNode<'i, I, P, TK>>,
42}
43
44impl<I, P, TK> TreeBuilder<'_, I, P, TK>
45where
46 I: Input + ?Sized,
47{
48 pub fn new() -> Self {
49 Self { res_stack: vec![] }
50 }
51}
52
53impl<I, P, TK> Default for TreeBuilder<'_, I, P, TK>
54where
55 I: Input + ?Sized,
56{
57 fn default() -> Self {
58 Self::new()
59 }
60}
61
62impl<'i, I, P, TK> Builder for TreeBuilder<'i, I, P, TK>
63where
64 I: Input + ?Sized,
65{
66 type Output = TreeNode<'i, I, P, TK>;
67
68 fn get_result(&mut self) -> Self::Output {
69 self.res_stack.pop().unwrap()
70 }
71}
72
73impl<'i, I, C, S, P, TK> LRBuilder<'i, I, C, S, P, TK> for TreeBuilder<'i, I, P, TK>
74where
75 I: Input + ?Sized,
76 C: Context<'i, I, S, TK>,
77 S: State,
78{
79 fn shift_action(&mut self, context: &C, token: Token<'i, I, TK>) {
80 self.res_stack.push(TreeNode::TermNode {
81 token,
82 layout: context.layout_ahead(),
83 })
84 }
85
86 fn reduce_action(&mut self, context: &C, prod: P, prod_len: usize) {
87 let children;
88 let layout;
89 if prod_len > 0 {
90 children = self.res_stack.split_off(self.res_stack.len() - prod_len);
91 layout = match children[0] {
92 TreeNode::TermNode { layout, .. } => layout,
93 TreeNode::NonTermNode { layout, .. } => layout,
94 };
95 } else {
96 children = vec![];
97 layout = None;
98 }
99 self.res_stack.push(TreeNode::NonTermNode {
100 children,
101 prod,
102 location: context.location(),
103 layout,
104 });
105 }
106}
107
108#[derive(Debug)]
110pub enum TreeNode<'i, I, P, TK>
111where
112 I: Input + ?Sized,
113{
114 TermNode {
115 token: Token<'i, I, TK>,
116 layout: Option<&'i I>,
117 },
118 NonTermNode {
119 prod: P,
120 location: Location,
121 children: Vec<TreeNode<'i, I, P, TK>>,
122 layout: Option<&'i I>,
123 },
124}
125
126pub struct SliceBuilder<'i, I: ?Sized> {
133 input: &'i I,
134 slice: Option<&'i I>,
135}
136
137impl<'i, I> SliceBuilder<'i, I>
138where
139 I: Input + ?Sized,
140{
141 pub fn new(input: &'i I) -> Self {
142 Self { input, slice: None }
143 }
144}
145
146impl<'i, I> Builder for SliceBuilder<'i, I>
147where
148 I: Input + ?Sized,
149{
150 type Output = Option<&'i I>;
151
152 fn get_result(&mut self) -> Self::Output {
153 self.slice
154 }
155}
156
157impl<'i, I, C, S, P, TK> LRBuilder<'i, I, C, S, P, TK> for SliceBuilder<'i, I>
158where
159 I: Input + ?Sized,
160 C: Context<'i, I, S, TK>,
161 S: State,
162{
163 fn shift_action(&mut self, _context: &C, _token: Token<'i, I, TK>) {
164 }
166
167 fn reduce_action(&mut self, context: &C, _prod: P, _prod_len: usize) {
168 self.slice = Some(&self.input[context.range()]);
170 }
171}