lite_parser/
parser.rs

1#[cfg(not(feature = "std"))]
2pub extern crate alloc;
3
4use crate::impls::{SimpleError, SimplePosition};
5use crate::traits::{Error, Input, Position, ResultOf};
6#[cfg(not(feature = "std"))]
7use alloc::vec::Vec;
8use core::marker::PhantomData;
9
10#[cfg_attr(feature = "std", derive(Debug, PartialEq, Eq))]
11#[derive(Clone)]
12pub struct ParserOptions {
13    pub max_nest_level: Option<u32>,
14}
15
16impl Default for ParserOptions {
17    fn default() -> Self {
18        ParserOptions {
19            max_nest_level: Some(100),
20        }
21    }
22}
23
24#[cfg_attr(feature = "std", derive(Debug, PartialEq, Eq))]
25#[derive(Clone)]
26pub struct ParserContext {
27    nest_level: u32,
28    options: ParserOptions,
29}
30
31impl ParserContext {
32    pub fn new(options: ParserOptions) -> Self {
33        Self {
34            nest_level: 0,
35            options,
36        }
37    }
38
39    pub fn options(&self) -> &ParserOptions {
40        &self.options
41    }
42
43    pub fn nest<I: Input>(&self, input: &I, pos: I::Position) -> Result<Self, I::Error> {
44        if Some(self.nest_level) == self.options.max_nest_level {
45            Err(input.error_at(pos, "Exceeded nest level"))
46        } else {
47            Ok(Self {
48                nest_level: self.nest_level + 1,
49                options: self.options.clone(),
50            })
51        }
52    }
53}
54
55pub trait Parser<I: Input> {
56    type Output;
57    fn parse(input: &I, current: I::Position, context: &ParserContext)
58        -> ResultOf<I, Self::Output>;
59}
60
61pub trait Predicate<T> {
62    fn eval(t: &T) -> bool;
63}
64
65pub struct ExpectChar<P>(PhantomData<P>);
66
67impl<P: Predicate<char>, I: Input> Parser<I> for ExpectChar<P> {
68    type Output = char;
69    fn parse(
70        input: &I,
71        current: I::Position,
72        _context: &ParserContext,
73    ) -> ResultOf<I, Self::Output> {
74        let (c, next) = input
75            .next(current)
76            .map_err(|e| e.add_reason(current, "ExpectChar"))?;
77        if P::eval(&c) {
78            Ok((c, next))
79        } else {
80            Err(input.error_at(current, "ExpectChar"))
81        }
82    }
83}
84
85pub struct Null;
86
87impl<I: Input> Parser<I> for Null {
88    type Output = ();
89    fn parse(
90        _input: &I,
91        current: I::Position,
92        _context: &ParserContext,
93    ) -> ResultOf<I, Self::Output> {
94        Ok(((), current))
95    }
96}
97
98pub struct Concat<P, P2>(PhantomData<(P, P2)>);
99
100impl<I: Input, P: Parser<I>, P2: Parser<I>> Parser<I> for Concat<P, P2> {
101    type Output = (P::Output, P2::Output);
102    fn parse(
103        input: &I,
104        current: I::Position,
105        context: &ParserContext,
106    ) -> ResultOf<I, Self::Output> {
107        let (output1, pos) =
108            P::parse(input, current, context).map_err(|e| e.add_reason(current, "Concat1"))?;
109        let (output2, pos) =
110            P2::parse(input, pos, context).map_err(|e| e.add_reason(current, "Concat2"))?;
111        Ok(((output1, output2), pos))
112    }
113}
114
115pub type Concat3<P, P2, P3> = Concat<P, Concat<P2, P3>>;
116pub type Concat4<P, P2, P3, P4> = Concat<P, Concat<P2, Concat<P3, P4>>>;
117pub type Concat5<P, P2, P3, P4, P5> = Concat<P, Concat<P2, Concat<P3, Concat<P4, P5>>>>;
118
119#[cfg_attr(feature = "std", derive(Debug))]
120pub enum Either<A, B> {
121    A(A),
122    B(B),
123}
124
125pub struct OneOf<P, P2>(PhantomData<(P, P2)>);
126
127impl<I: Input, P: Parser<I>, P2: Parser<I>> Parser<I> for OneOf<P, P2> {
128    type Output = Either<P::Output, P2::Output>;
129    fn parse(
130        input: &I,
131        current: I::Position,
132        context: &ParserContext,
133    ) -> ResultOf<I, Self::Output> {
134        P::parse(input, current, context)
135            .map(|(output, pos)| (Either::A(output), pos))
136            .or_else(|_| {
137                P2::parse(input, current, context).map(|(output, pos)| (Either::B(output), pos))
138            })
139            .map_err(|e| e.add_reason(current, "OneOf"))
140    }
141}
142
143pub type OneOf3<P, P2, P3> = OneOf<P, OneOf<P2, P3>>;
144pub type OneOf4<P, P2, P3, P4> = OneOf<P, OneOf3<P2, P3, P4>>;
145pub type OneOf5<P, P2, P3, P4, P5> = OneOf<P, OneOf4<P2, P3, P4, P5>>;
146pub type OneOf6<P, P2, P3, P4, P5, P6> = OneOf<P, OneOf5<P2, P3, P4, P5, P6>>;
147pub type OneOf7<P, P2, P3, P4, P5, P6, P7> = OneOf<P, OneOf6<P2, P3, P4, P5, P6, P7>>;
148pub type OneOf8<P, P2, P3, P4, P5, P6, P7, P8> = OneOf<P, OneOf7<P2, P3, P4, P5, P6, P7, P8>>;
149pub type OneOf9<P, P2, P3, P4, P5, P6, P7, P8, P9> =
150    OneOf<P, OneOf8<P2, P3, P4, P5, P6, P7, P8, P9>>;
151
152pub type ZeroOrOne<P> = OneOf<P, Null>;
153
154pub type ZeroOrMore<P> = OneOf<OneOrMore<P>, Null>;
155
156//pub type OneOrMore<P> = Concat<P, ZeroOrMore<P>>;
157pub struct OneOrMore<P>(PhantomData<P>);
158
159impl<I: Input, P: Parser<I>> Parser<I> for OneOrMore<P> {
160    type Output = Vec<P::Output>;
161    fn parse(
162        input: &I,
163        current: I::Position,
164        context: &ParserContext,
165    ) -> ResultOf<I, Self::Output> {
166        let mut output_list = Vec::new();
167        let (output, mut pos) =
168            P::parse(input, current, context).map_err(|e| e.add_reason(current, "OneOrMore"))?;
169        output_list.push(output);
170        loop {
171            if let Ok((output, next_pos)) = P::parse(input, pos, context) {
172                pos = next_pos;
173                output_list.push(output);
174            } else {
175                return Ok((output_list, pos));
176            }
177        }
178    }
179}
180
181impl Input for &str {
182    type Position = SimplePosition;
183    type Error = SimpleError;
184
185    fn next(&self, pos: Self::Position) -> Result<(char, Self::Position), Self::Error> {
186        self.chars()
187            .nth(pos.index() as usize)
188            .ok_or_else(|| self.error_at(pos, "Out of bounds"))
189            .map(|c| (c, pos.next(c)))
190    }
191
192    fn next_range(
193        &self,
194        start: Self::Position,
195        counts: u32,
196    ) -> Result<(&str, Self::Position), Self::Error> {
197        let start_index = start.index() as usize;
198        let range = start_index..start_index + counts as usize;
199        self.get(range)
200            .map(|s| {
201                let mut pos = start;
202                for c in s.chars() {
203                    pos = pos.next(c);
204                }
205                (s, pos)
206            })
207            .ok_or_else(|| self.error_at(start, "Out of bounds"))
208    }
209
210    fn error_at(&self, pos: Self::Position, reason: &'static str) -> Self::Error {
211        let mut reasons = Vec::new();
212        reasons.push((pos, reason));
213        SimpleError { reasons }
214    }
215
216    fn is_end(&self, pos: Self::Position) -> bool {
217        pos.index() as usize >= self.len()
218    }
219}
220
221#[macro_export]
222macro_rules! literals {
223    (
224        $(
225            $( #[ $attr:meta ] )*
226            $vis:vis $name:ident => $($($value:literal)..=+)|+;
227        )*
228    ) => {
229        $(
230            $crate::literals!{
231                IMPL
232                $( #[ $attr ] )*
233                $vis $name => $($($value)..=+)|+
234            }
235        )*
236    };
237    (
238        IMPL
239        $( #[ $attr:meta ] )*
240        $vis:vis $name:ident => $($($value:literal)..=+)|+
241    ) => (
242        $crate::paste::item! {
243            $vis struct [< $name Predicate >];
244            impl $crate::parser::Predicate<char> for [< $name Predicate >] {
245                fn eval(c: &char) -> bool {
246                    match *c {
247                        $($($value)..=+)|+ => true,
248                        _ => false
249                    }
250                }
251            }
252
253            $( #[ $attr ] )*
254            $vis type $name = $crate::parser::ExpectChar<[< $name Predicate >]>;
255        }
256    );
257}
258
259#[macro_export]
260macro_rules! parsers {
261    (
262        $(
263            $( #[ $attr:meta ] )*
264            $vis:vis $name:ident = $type:ty, $output_type:ty, ($output:ident) => $body:block;
265        )*
266    ) => {
267        $(
268            $vis struct $name;
269            impl<I: $crate::traits::Input> $crate::parser::Parser<I> for $name {
270                type Output = $output_type;
271                fn parse(input: &I, current: I::Position, context: &ParserContext) -> $crate::traits::ResultOf<I, Self::Output> {
272                    let ($output, pos) = <$type as $crate::parser::Parser<I>>::parse(input, current, context)
273                        .map_err(|e| <I::Error as $crate::traits::Error>::add_reason(e, current, stringify!($name)))?;
274                    let res = $body;
275                    Ok((res, pos))
276                }
277            }
278        )*
279    };
280}