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