peruse/
parsers.rs

1use std::rc::Rc;
2
3/////////     TRAITS/TYPES       //////////
4
5/// A Parser is a parser that parses some elements out of the beginning of
6/// a slice and returns a parsed value along with the rest of the unparsed slice
7pub trait Parser  {
8  type I: ?Sized;
9  type O;
10
11  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O>;
12}
13
14/// Combinator methods for slice parsers.  In most cases, these methods copy
15/// the caller into a higher-order parser
16pub trait ParserCombinator : Parser + Clone {
17
18  /// Chain this parser with another parser, creating new parser that returns a
19  /// tuple of their results
20  fn then<P: Parser<I=Self::I>>(&self, p: P) -> ChainedParser<Self,P> {
21    ChainedParser{first: self.clone(), second: p}
22  }
23
24  /// Chain this parser with another parser, but toss the value from this parser
25  fn then_r<P: ParserCombinator<I=Self::I>>(&self, p: P) -> MapParser<Self::I, ChainedParser<Self, P>, P::O> {
26    self.then(p).map(|(_, t)| t)
27  }
28
29  /// Chain this parser with another parser, but toss the value from the other parser
30  fn then_l<P: ParserCombinator<I=Self::I>>(&self, p: P) -> MapParser<Self::I, ChainedParser<Self, P>, Self::O> {
31    self.then(p).map(|(t, _)| t)
32  }
33
34  /// Create a new parser that will repeat this parser until it returns an error
35  fn repeat(&self) -> RepeatParser<Self> {
36    RepeatParser{parser: self.clone()}
37  }
38  
39  /// Map the value of this parser
40  fn map<T, F: 'static + Fn(Self::O) -> T>(&self, f: F) -> MapParser<Self::I, Self, T> {
41    MapParser{parser: self.clone(), mapper: Rc::new(Box::new(f))}
42  }
43
44  /// Create a disjunction with another parser.  If this parser produces an error, the other parser will be used
45  fn or<P: Parser<I=Self::I, O=Self::O>>(&self, p: P) -> OrParser<Self,P> {
46    OrParser{first: self.clone(), second: p}
47  }
48
49
50}
51
52pub type ParseResult<I,O> = Result<(O, I), String>;
53
54/////////     FUNCTIONS     ///////////
55
56/// Create a parser that will return Some if the given parser is successful, None otherwise
57pub fn opt<T: Parser>(t: T) -> OptionParser<T> {
58  OptionParser{parser: t}
59}
60
61/// Create a lazily evaluated parser from a function.  This can be used to generate recursive parsers
62pub fn recursive<I:?Sized,O, F:  Fn() -> Box<Parser<I=I,O=O>>>(f: F) -> RecursiveParser<I,O,F> {
63  RecursiveParser{parser: Rc::new(f)}
64}
65
66
67pub fn repsep<I: ?Sized, A: Parser<I=I>, B: Parser<I=I>>(rep: A, sep: B) -> RepSepParser<A,B> {
68  RepSepParser{rep: rep, sep: sep, min_reps: 1}
69}
70
71pub fn one_of<T: Parser>(t: Vec<T>) -> OneOfParser<T> {
72  OneOfParser{options: t}
73}
74
75pub fn boxed<I: ?Sized,O>(b: Box<Parser<I=I, O=O>>) -> BoxedParser<I,O> {
76  BoxedParser{parser: Rc::new(b)}
77}
78
79
80////////////    STRUCTS     //////////////
81
82
83/// A Chained parser contains two parsers that will be used in sequence to
84/// create a tuple of parsed values
85pub struct ChainedParser<A,B> {
86  first: A,
87  second: B,
88}
89impl<C: ?Sized, A: Parser<I=C>, B: Parser<I=C>> Parser for ChainedParser<A, B> {
90  type I = C;
91  type O = (A::O,B::O);
92
93  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O>{
94    match self.first.parse(data) {
95      Ok((a, d2)) => match self.second.parse(d2) {
96        Ok((b, remain)) => Ok(((a, b), remain)),
97        Err(err) => Err(err)
98      },
99      Err(err) => Err(err)
100    }
101  }
102}
103
104impl<C: ?Sized, A: ParserCombinator<I=C>, B: ParserCombinator<I=C>>  Clone for ChainedParser<A, B> {
105  
106  fn clone(&self) -> Self {
107    ChainedParser{first: self.first.clone(), second: self.second.clone()}
108  }
109}
110
111impl<C: ?Sized, A: ParserCombinator<I=C>, B: ParserCombinator<I=C>>  ParserCombinator for ChainedParser<A, B> {}
112
113
114/// A Parser that repeats the given parser until it encounters an error.  A
115/// vector of the accumulated parsed values is returned
116pub struct RepeatParser<P: Parser> {
117  parser: P
118}
119impl<T: Parser> Parser for RepeatParser<T> {
120  type I = T::I;
121  type O = Vec<T::O>;
122  
123  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O> {
124    let mut remain = data;
125    let mut v: Vec<T::O> = Vec::new();
126    loop {
127      match self.parser.parse(remain.clone()) {
128        Ok((result, rest)) => {
129          v.push(result);
130          remain = rest;
131        }
132        Err(_) => {
133          return Ok((v, remain));
134        }
135      }
136    }
137  }
138}
139
140impl<T: ParserCombinator> ParserCombinator for RepeatParser<T> {}
141
142impl<T: ParserCombinator> Clone for RepeatParser<T> {
143  fn clone(&self) -> Self {
144    RepeatParser{parser: self.parser.clone()}
145  }
146}
147
148
149/// A Parser that uses a closure to map the result of another parser
150pub struct MapParser<I: ?Sized, P: Parser<I=I>, T> {
151  parser: P,
152  mapper: Rc<Box<Fn(P::O) -> T>>,
153}
154
155impl<I: ?Sized, P: Parser<I=I>, T> Parser for MapParser<I,P,T> {
156  type I = P::I;
157  type O = T;
158
159  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O> {
160    self.parser.parse(data).map(|(output, input)| ((self.mapper)(output), input))
161  }
162
163}
164
165impl<I: ?Sized, P: ParserCombinator<I=I>, T> Clone for MapParser<I,P,T> {
166
167  fn clone(&self) -> Self {
168    MapParser{parser: self.parser.clone(), mapper: self.mapper.clone()}
169  }
170}
171
172impl<I: ?Sized, P: ParserCombinator<I=I>, T> ParserCombinator for MapParser<I,P,T> {}
173
174pub struct OrParser<S: Parser,T: Parser> {
175  first: S,
176  second: T,
177}
178
179impl<I:?Sized,O, S: Parser<I=I,O=O>, T: Parser<I=I,O=O>> Parser for OrParser<S,T> {
180  type I = I;
181  type O = O;
182
183  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O> {
184    match self.first.parse(data.clone()) {
185      Ok((a, d2)) => Ok((a, d2)),
186      Err(_) => match self.second.parse(data.clone()) {
187        Ok((b, remain)) => Ok((b, remain)),
188        Err(err) => Err(err)
189      }
190    }
191  }
192}
193
194impl<I:?Sized,O, S: ParserCombinator<I=I,O=O>, T: ParserCombinator<I=I,O=O>> Clone for OrParser<S,T> {
195
196  fn clone(&self) -> Self {
197    OrParser{first: self.first.clone(), second: self.second.clone()}
198  }
199}
200
201impl<I:?Sized,O, S: ParserCombinator<I=I,O=O>, T: ParserCombinator<I=I,O=O>> ParserCombinator for OrParser<S,T> {}
202
203
204#[derive(Clone)]
205pub struct OptionParser<P: Parser> {
206  parser: P 
207}
208impl<P: Parser> Parser for OptionParser<P> {
209  type I = P::I;
210  type O = Option<P::O>;
211
212  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O> {
213    match self.parser.parse(data.clone()) {
214      Ok((result, rest))  => Ok((Some(result), rest)),
215      Err(_)              => Ok((None, data)),
216    }
217  }
218}
219
220impl<P: ParserCombinator> ParserCombinator for OptionParser<P> {}
221
222pub struct RecursiveParser<I: ?Sized, O, F> where F: Fn() -> Box<Parser<I=I,O=O>>{
223  parser: Rc<F>
224}
225
226impl<I:?Sized, O, F> Parser for RecursiveParser<I, O, F> where F: Fn() -> Box<Parser<I=I,O=O>> {
227
228  type I = I;
229  type O = O;
230
231  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O> {
232    (self.parser)().parse(data)
233  }
234
235}
236
237impl<I:?Sized, O, F> ParserCombinator for RecursiveParser<I, O, F> where F: Fn() -> Box<Parser<I=I,O=O>> {}
238
239impl<I: ?Sized, O, F> Clone for RecursiveParser<I, O, F> where F: Fn() -> Box<Parser<I=I,O=O>> {
240  fn clone(&self) -> Self {
241    RecursiveParser{parser: self.parser.clone()}
242  }
243}
244
245
246/// A Parser that will repeatedly parse `rep` and `sep` in sequence until `sep`
247/// returns an error.  The accumulated `rep` results are returned.  If `rep`
248/// returns an error at any time, the error is escelated.
249pub struct RepSepParser<A,B> {
250  pub rep: A,
251  pub sep: B,
252  pub min_reps: usize,
253}
254impl<I: ?Sized, A: Parser<I=I>, B: Parser<I=I>> Parser for RepSepParser<A,B> {
255  type I = I;
256  type O = Vec<A::O>;
257
258  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O> {
259    let mut remain = data;
260    let mut v: Vec<A::O> = Vec::new();
261    loop {
262      match self.rep.parse(remain) {
263        Ok((result, rest)) => {
264          v.push(result);
265          match self.sep.parse(rest.clone()) {
266            Ok((_, rest2)) => {
267              remain = rest2
268            }
269            Err(_) => {
270              if v.len() < self.min_reps {
271                return Err(format!("Not enough reps: required {}, got {}", self.min_reps, v.len()))
272              } else {
273                return Ok((v, rest))
274              }
275            }
276          }
277        }
278        Err(err) => {
279          return Err(format!("Error on rep: {}", err));
280        }
281      }
282    }
283  }
284}
285
286impl<I: ?Sized, A: ParserCombinator<I=I>, B: ParserCombinator<I=I>> ParserCombinator for RepSepParser<A,B> {}
287
288impl<I: ?Sized, A: ParserCombinator<I=I>, B: ParserCombinator<I=I>> Clone for RepSepParser<A,B> {
289  
290  fn clone(&self) -> Self {
291    RepSepParser{rep : self.rep.clone(), sep: self.sep.clone(), min_reps: self.min_reps}
292  }
293
294}
295
296
297/// A Parser that takes a vector of parsers (of the exact same type) and
298/// returns the value from the first parser to return a non-error.  This parser
299/// solely exists because doing a or b or c or d... ends up crushing rustc
300#[derive(Clone)]
301pub struct OneOfParser<T: Parser> {
302  options: Vec<T>
303}
304
305impl<T: Parser> Parser for OneOfParser<T> {
306  type I = T::I;
307  type O = T::O;
308
309  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O> {
310    for p in self.options.iter() {
311      let r = p.parse(data.clone());
312      if r.is_ok() {
313        return r;
314      }
315    }
316    Err(format!("All options failed"))
317  }
318
319}
320
321impl<T: ParserCombinator> ParserCombinator for OneOfParser<T> {}
322
323
324/// this parser solely exists to avoid insanely long compile times in rustc.
325/// When you have a fairly large parser, it's best to box it.  Yes we're
326/// introducing extra dynamic dispatch, but only on a small amount.  In some
327/// cases this is the only way to get rustc to not take (literally) a million
328/// years!
329pub struct BoxedParser<I:?Sized,O> {
330  parser: Rc<Box<Parser<I=I,O=O>>>
331}
332
333impl<I:?Sized, O> Parser for BoxedParser<I, O> {
334
335  type I = I;
336  type O = O;
337
338  fn parse<'a>(&self, data: &'a Self::I) -> ParseResult<&'a Self::I, Self::O> {
339    self.parser.parse(data)
340  }
341
342}
343
344impl<I:?Sized, O> ParserCombinator for BoxedParser<I, O>  {}
345
346impl<I: ?Sized, O> Clone for BoxedParser<I, O>  {
347  fn clone(&self) -> Self {
348    BoxedParser{parser: self.parser.clone()}
349  }
350}