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
156pub 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}