pa_rs/
slow_parser.rs

1use core::fmt::Display;
2use std::{
3    collections::VecDeque,
4    ops::{BitAnd, BitOr, Shl, Shr},
5};
6use Either::*;
7
8pub enum Either<T, U> {
9    Left(T),
10    Right(U),
11}
12
13type PString = VecDeque<char>;
14
15type ParseResult<T> = Result<T, String>;
16
17type _ParseResult<T> = (PString, ParseResult<T>);
18
19pub struct Parser<T> {
20    run_parser: Box<dyn FnMut(PString) -> _ParseResult<T>>,
21}
22
23// Constructors
24impl<T> Parser<T> {
25    pub fn new<F>(f: F) -> Parser<T>
26    where
27        F: FnMut(PString) -> _ParseResult<T> + 'static,
28    {
29        Parser {
30            run_parser: Box::new(f),
31        }
32    }
33}
34
35impl<T: Default> Parser<T> {
36    pub fn empty() -> Parser<T> {
37        Parser::new(|input| (input, Ok(T::default())))
38    }
39}
40
41impl<T> Parser<T> {
42    pub fn failed() -> Parser<T> {
43        Parser::new(|input| (input, Err("Failed parser".into())))
44    }
45}
46
47// Runners
48impl<T> Parser<T> {
49    pub fn _run(&mut self, input: PString) -> _ParseResult<T> {
50        (self.run_parser)(input)
51    }
52
53    pub fn run<S: Display>(&mut self, input: S) -> ParseResult<T> {
54        self._run(input.to_string().chars().collect()).1
55    }
56
57    pub fn drun<S: Display>(&mut self, input: S) -> ParseResult<T> {
58        println!("Input: {}", input);
59        let (input, result) = self._run(input.to_string().chars().collect());
60        println!("Remaining: {:?}", input);
61        result
62    }
63}
64
65// Parser with Predicate
66impl Parser<String> {
67    pub fn parse_until<F>(mut p: F) -> Parser<String>
68    where
69        F: FnMut(char) -> bool + 'static,
70    {
71        Parser::new(move |mut input| {
72            let mut string = String::new();
73            loop {
74                let item = input.front().cloned();
75                match item {
76                    Some(ch) if p(ch) => {
77                        string.push(ch);
78                        input.pop_front();
79                    }
80                    _ => break (input, Ok(string)),
81                }
82            }
83        })
84    }
85}
86
87// Mapper
88impl<T: 'static> Parser<T> {
89    pub fn map<U, F>(mut self, mut f: F) -> Parser<U>
90    where
91        F: FnMut(T) -> U + 'static,
92    {
93        Parser::new(move |input| {
94            let (input, result) = self._run(input);
95            (input, result.map(|result| f(result)))
96        })
97    }
98}
99
100// Bind
101impl<T: 'static> Parser<T> {
102    pub fn bind<U, F>(mut self, mut f: F) -> Parser<U>
103    where
104        F: FnMut(T) -> Parser<U> + 'static,
105    {
106        Parser::new(move |input| {
107            let (input, result) = self._run(input);
108            match result {
109                Ok(t) => f(t)._run(input),
110                Err(err) => (input, Err(err)),
111            }
112        })
113    }
114}
115
116// Combinators
117impl<T: 'static> Parser<T> {
118    fn _and<U: 'static>(mut self, mut other: Parser<U>) -> Parser<(T, U)> {
119        Parser::new(move |input| {
120            let (input1, r1) = self._run(input.clone());
121            match r1 {
122                Ok(t) => {
123                    let (input2, r2) = other._run(input1);
124                    match r2 {
125                        Ok(u) => (input2, Ok((t, u))),
126                        Err(err) => (input, Err(err)),
127                    }
128                }
129                Err(err) => (input1, Err(err)),
130            }
131        })
132    }
133
134    fn _or<U: 'static>(mut self, mut other: Parser<U>) -> Parser<Either<T, U>> {
135        Parser::new(move |input| {
136            let (input, r1) = self._run(input);
137            match r1 {
138                Ok(t) => (input, Ok(Left(t))),
139                Err(_) => {
140                    let (input, r2) = other._run(input);
141                    (
142                        input,
143                        match r2 {
144                            Ok(u) => Ok(Right(u)),
145                            Err(err) => Err(err),
146                        },
147                    )
148                }
149            }
150        })
151    }
152
153    fn _drop_fst<U: 'static>(mut self, mut other: Parser<U>) -> Parser<U> {
154        Parser::new(move |input| {
155            let (input1, r1) = self._run(input.clone());
156            match r1 {
157                Ok(_) => {
158                    let (input2, r2) = other._run(input1);
159                    match r2 {
160                        Ok(u) => (input2, Ok(u)),
161                        Err(err) => (input, Err(err)),
162                    }
163                }
164                Err(err) => (input1, Err(err)),
165            }
166        })
167    }
168
169    fn _drop_snd<U: 'static>(mut self, mut other: Parser<U>) -> Parser<T> {
170        Parser::new(move |input| {
171            let (input1, r1) = self._run(input.clone());
172            match r1 {
173                Ok(t) => {
174                    let (input2, r2) = other._run(input1);
175                    match r2 {
176                        Ok(_) => (input2, Ok(t)),
177                        Err(err) => (input, Err(err)),
178                    }
179                }
180                Err(err) => (input1, Err(err)),
181            }
182        })
183    }
184}
185
186impl<T: 'static, U: 'static> BitAnd<Parser<U>> for Parser<T> {
187    type Output = Parser<(T, U)>;
188
189    fn bitand(self, rhs: Parser<U>) -> Self::Output {
190        self._and(rhs)
191    }
192}
193
194impl<T: 'static, U: 'static> BitOr<Parser<U>> for Parser<T> {
195    type Output = Parser<Either<T, U>>;
196
197    fn bitor(self, rhs: Parser<U>) -> Self::Output {
198        self._or(rhs)
199    }
200}
201
202impl<T: 'static, U: 'static> Shr<Parser<U>> for Parser<T> {
203    type Output = Parser<U>;
204
205    fn shr(self, rhs: Parser<U>) -> Self::Output {
206        self._drop_fst(rhs)
207    }
208}
209
210impl<T: 'static, U: 'static> Shl<Parser<U>> for Parser<T> {
211    type Output = Parser<T>;
212
213    fn shl(self, rhs: Parser<U>) -> Self::Output {
214        self._drop_snd(rhs)
215    }
216}
217
218// Parsers
219pub fn parse_char(ch: char) -> Parser<char> {
220    Parser::new(move |mut input| {
221        let front = input.front().cloned();
222        match front {
223            Some(x) if x == ch => {
224                input.pop_front();
225                (input, Ok(ch))
226            }
227            Some(y) => (input, Err(format!("Expected {ch:?} got {y}"))),
228            None => (input, Err(format!("Expected {ch:?} got empty string"))),
229        }
230    })
231}
232
233pub fn parse_str(string: &str) -> Parser<String> {
234    parse_all_of(string.chars().map(|ch| parse_char(ch)))
235}
236
237pub fn parse_bool() -> Parser<bool> {
238    parse_one_of([parse_str("true"), parse_str("false")]).map(|x| match x.as_str() {
239        "true" => true,
240        "false" => false,
241        _ => panic!("Bool cannot be other than true and false"),
242    })
243}
244
245pub fn parse_one_of<T: 'static, I: IntoIterator<Item = Parser<T>>>(list: I) -> Parser<T> {
246    list.into_iter()
247        .reduce(|p1, p2| {
248            (p1 | p2).map(|r| match r {
249                Left(v1) => v1,
250                Right(v2) => v2,
251            })
252        })
253        .unwrap_or(Parser::failed())
254}
255
256pub fn parse_all_of<T: 'static, I: IntoIterator<Item = Parser<T>>, C: FromIterator<T>>(
257    list: I,
258) -> Parser<C> {
259    list.into_iter()
260        .fold(Parser::empty(), |p1: Parser<Vec<T>>, p2| {
261            (p1 & p2).map(|(mut c, t)| {
262                c.push(t);
263                c
264            })
265        })
266        .map(|c| c.into_iter().collect())
267}
268
269pub fn parse_while_true<F>(f: F) -> Parser<String>
270where
271    F: FnMut(char) -> bool + 'static,
272{
273    Parser::parse_until(f)
274}
275
276pub fn parse_uints() -> Parser<String> {
277    parse_while_true(|ch| ch.is_digit(10)).bind(|x| {
278        Parser::new(move |input| {
279            if x.is_empty() {
280                (input, Err(format!("Expected digit got {x:?}")))
281            } else {
282                (input, Ok(x.clone()))
283            }
284        })
285    })
286}
287
288pub fn parse_uint() -> Parser<usize> {
289    parse_uints().map(|x| x.parse().expect("u64: This will never fail!"))
290}
291
292pub fn parse_ints() -> Parser<String> {
293    parse_one_of([parse_all_of([parse_str("-"), parse_uints()]), parse_uints()])
294}
295
296pub fn parse_int() -> Parser<i64> {
297    parse_ints().map(|x| x.parse().expect("i64: This will never fail!"))
298}
299
300pub fn parse_float() -> Parser<f64> {
301    parse_one_of([
302        parse_all_of([
303            parse_ints(),
304            parse_str("."),
305            parse_one_of([parse_uints(), parse_white_space()]),
306        ]),
307        parse_ints(),
308    ])
309    .map(|x: String| x.parse().expect("f64: This will never fail!"))
310}
311
312pub fn parse_string() -> Parser<String> {
313    parse_char('"') >> parse_while_true(|ch| ch != '"') << parse_char('"')
314}
315
316pub fn parse_white_space() -> Parser<String> {
317    parse_while_true(|ch| ch.is_whitespace())
318}
319
320pub fn parse_zero_or_more<T: 'static>(mut p: Parser<T>) -> Parser<Vec<T>> {
321    Parser::new(move |mut input| {
322        let mut r;
323        let mut list = Vec::new();
324        loop {
325            (input, r) = p._run(input);
326            if let Ok(t) = r {
327                list.push(t);
328            } else {
329                break (input, Ok(list));
330            }
331        }
332    })
333}
334
335pub fn parse_sbws<T: 'static>(p: Parser<T>) -> Parser<T> {
336    parse_white_space() >> p << parse_white_space()
337}
338
339pub fn parse_list_of<T: 'static, F>(mut p: F) -> Parser<Vec<T>>
340where
341    F: FnMut() -> Parser<T>,
342{
343    parse_char('[')
344        >> (parse_one_of([
345            (parse_zero_or_more(parse_sbws(p()) << parse_char(',')) & parse_sbws(p())).map(
346                |(mut v, a)| {
347                    v.push(a);
348                    v
349                },
350            ),
351            parse_white_space().map(|_| vec![]),
352        ]))
353        << parse_char(']')
354}