1#[cfg(test)]
7mod tests;
8
9use itertools::Itertools;
10use std::cmp::Ordering;
11use std::collections::HashSet;
12use std::fmt::{Debug, Display};
13use std::marker::PhantomData;
14use unicode_segmentation::UnicodeSegmentation as Uni;
15use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
16
17#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct Located<A> {
23 pub value: A,
24 pub from: Location,
25 pub to: Location,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub struct Location {
39 pub row: usize,
40 pub col: usize,
41}
42
43impl Ord for Location {
44 fn cmp(&self, other: &Self) -> Ordering {
45 self.row
46 .cmp(&other.row)
47 .then_with(|| self.col.cmp(&other.col))
48 }
49}
50
51impl PartialOrd for Location {
52 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
53 Some(self.cmp(other))
54 }
55}
56
57#[derive(Debug, PartialEq, Eq)]
96pub enum ParseResult<'a, Output, State> {
97 Ok {
98 input: &'a str,
99 location: Location,
100 output: Output,
101 state: State,
102 committed: bool,
103 },
104 Err {
105 message: String,
106 from: Location,
107 to: Location,
108 state: State,
109 committed: bool,
110 },
111}
112
113pub struct ParseOk<'a, Output, State> {
114 input: &'a str,
115 output: Output,
116 location: Location,
117 state: State,
118 committed: bool,
119}
120
121pub struct ParseErr<State> {
122 message: String,
123 from: Location,
124 to: Location,
125 state: State,
126 committed: bool,
127}
128
129pub type StdParseResult<'a, A, S> = Result<ParseOk<'a, A, S>, ParseErr<S>>;
130
131impl<'a, A, S> From<ParseResult<'a, A, S>> for StdParseResult<'a, A, S> {
132 fn from(val: ParseResult<'a, A, S>) -> Self {
133 match val {
134 ParseResult::Ok {
135 input,
136 location,
137 output,
138 state,
139 committed,
140 } => Ok(ParseOk {
141 input,
142 location,
143 output,
144 state,
145 committed,
146 }),
147 ParseResult::Err {
148 message,
149 from,
150 to,
151 state,
152 committed,
153 } => Err(ParseErr {
154 message,
155 from,
156 to,
157 state,
158 committed,
159 }),
160 }
161 }
162}
163
164impl<'a, A, S> From<StdParseResult<'a, A, S>> for ParseResult<'a, A, S> {
165 fn from(result: StdParseResult<'a, A, S>) -> ParseResult<'a, A, S> {
166 match result {
167 Ok(ParseOk {
168 input,
169 location,
170 output,
171 state,
172 committed,
173 }) => ParseResult::Ok {
174 input,
175 location,
176 output,
177 state,
178 committed,
179 },
180 Err(ParseErr {
181 message,
182 from,
183 to,
184 state,
185 committed,
186 }) => ParseResult::Err {
187 message,
188 from,
189 to,
190 state,
191 committed,
192 },
193 }
194 }
195}
196
197impl<'a, T, S: Clone + 'a> ParseResult<'a, T, S> {
198 pub fn map<U, F: FnOnce(T) -> U>(self, func: F) -> ParseResult<'a, U, S> {
201 match self {
202 ParseResult::Ok {
203 input,
204 location,
205 output,
206 state,
207 committed,
208 } => ParseResult::Ok {
209 input,
210 location,
211 output: func(output),
212 state,
213 committed,
214 },
215 ParseResult::Err {
216 message,
217 from,
218 to,
219 state,
220 committed,
221 } => ParseResult::Err {
222 message,
223 from,
224 to,
225 state,
226 committed,
227 },
228 }
229 }
230 pub fn map_with_state<U, F: FnOnce(T, S) -> U>(self, func: F) -> ParseResult<'a, U, S> {
235 match self {
236 ParseResult::Ok {
237 input,
238 location,
239 output,
240 state,
241 committed,
242 } => ParseResult::Ok {
243 input,
244 location,
245 output: func(output, state.clone()),
246 state,
247 committed,
248 },
249 ParseResult::Err {
250 message,
251 from,
252 to,
253 state,
254 committed,
255 } => ParseResult::Err {
256 message,
257 from,
258 to,
259 state,
260 committed,
261 },
262 }
263 }
264 pub fn map_err<F: FnOnce(String) -> String>(self, func: F) -> ParseResult<'a, T, S> {
267 match self {
268 ParseResult::Ok {
269 input,
270 location,
271 output,
272 state,
273 committed,
274 } => ParseResult::Ok {
275 input,
276 location,
277 output,
278 state,
279 committed,
280 },
281 ParseResult::Err {
282 message,
283 from,
284 to,
285 state,
286 committed,
287 } => ParseResult::Err {
288 message: func(message),
289 from,
290 to,
291 state,
292 committed,
293 },
294 }
295 }
296 pub fn and_then<U, F: FnOnce(&'a str, T, Location, S) -> ParseResult<'a, U, S>>(
299 self,
300 func: F,
301 ) -> ParseResult<'a, U, S> {
302 match self {
303 ParseResult::Ok {
304 input,
305 output,
306 location,
307 state,
308 committed,
309 } => match func(input, output, location, state) {
310 ParseResult::Ok {
311 input,
312 output,
313 location,
314 state,
315 committed: cur_committed,
316 } => ParseResult::Ok {
317 input,
318 output,
319 location,
320 state,
321 committed: committed || cur_committed,
322 },
323 ParseResult::Err {
324 message,
325 from,
326 to,
327 state,
328 committed: cur_committed,
329 } => ParseResult::Err {
330 message,
331 from,
332 to,
333 state,
334 committed: committed || cur_committed,
335 },
336 },
337 ParseResult::Err {
338 message,
339 from,
340 to,
341 state,
342 committed,
343 } => ParseResult::Err {
344 message,
345 from,
346 to,
347 state,
348 committed,
349 },
350 }
351 }
352
353 pub fn backtrackable(self) -> ParseResult<'a, T, S> {
354 match self {
355 ParseResult::Ok {
356 input,
357 location,
358 output,
359 state,
360 ..
361 } => ParseResult::Ok {
362 input,
363 location,
364 output,
365 state,
366 committed: false,
367 },
368 ParseResult::Err {
369 message,
370 from,
371 to,
372 state,
373 ..
374 } => ParseResult::Err {
375 message,
376 from,
377 to,
378 state,
379 committed: false,
380 },
381 }
382 }
383
384 fn unwrap(self, source: &'a str) -> T {
385 match self {
386 ParseResult::Ok { output, .. } => output,
387 ParseResult::Err {
388 message, from, to, ..
389 } => {
390 println!("{}", display_error(source, message, from, to));
391 panic!();
392 }
393 }
394 }
395 fn unwrap_err(self) -> String
396 where
397 T: Debug + 'a,
398 {
399 match self {
400 ParseResult::Ok { output, .. } => panic!("{:#?}", output),
401 ParseResult::Err { message, .. } => message,
402 }
403 }
404}
405
406#[derive(Clone)]
407pub struct Map<P, F>(P, F);
408
409impl<'a, A: 'a, B: 'a, P: 'a, F: Clone> Parser<'a> for Map<P, F>
410where
411 P: Parser<'a, Output = A>,
412 F: FnOnce(A) -> B,
413{
414 type Output = B;
415
416 type State = P::State;
417
418 fn parse(
419 &mut self,
420 input: &'a str,
421 location: Location,
422 state: Self::State,
423 ) -> ParseResult<'a, B, Self::State> {
424 self.0.parse(input, location, state).map(self.1.clone())
425 }
426}
427
428#[derive(Clone)]
429pub struct MapWithState<P, F>(P, F);
430
431impl<'a, A, B, P, F: Clone> Parser<'a> for MapWithState<P, F>
432where
433 P: Parser<'a, Output = A>,
434 F: FnOnce(A, P::State) -> B,
435{
436 type Output = B;
437
438 type State = P::State;
439
440 fn parse(
441 &mut self,
442 input: &'a str,
443 location: Location,
444 state: Self::State,
445 ) -> ParseResult<'a, B, Self::State> {
446 match self.0.parse(input, location, state) {
447 ParseResult::Ok {
448 input,
449 output,
450 location,
451 state,
452 committed,
453 } => ParseResult::Ok {
454 input,
455 output: self.1.clone()(output, state.clone()),
456 location,
457 state,
458 committed,
459 },
460 ParseResult::Err {
461 message,
462 from,
463 to,
464 state,
465 committed,
466 } => ParseResult::Err {
467 message,
468 from,
469 to,
470 state,
471 committed,
472 },
473 }
474 }
475}
476
477#[derive(Clone)]
478pub struct MapErr<P, F>(P, F);
479
480impl<'a, P: 'a, F: Clone> Parser<'a> for MapErr<P, F>
481where
482 P: Parser<'a>,
483 F: FnOnce(String) -> String,
484{
485 type Output = P::Output;
486
487 type State = P::State;
488
489 fn parse(
490 &mut self,
491 input: &'a str,
492 location: Location,
493 state: Self::State,
494 ) -> ParseResult<'a, Self::Output, Self::State> {
495 self.0.parse(input, location, state).map_err(self.1.clone())
496 }
497}
498
499#[derive(Clone)]
500pub struct AndThen<P1, F>(P1, F);
501
502impl<'a, P1, P2, F: Clone, S: Clone + 'a> Parser<'a> for AndThen<P1, F>
503where
504 P1: Parser<'a, State = S>,
505 P2: Parser<'a, State = S>,
506 F: FnOnce(P1::Output) -> P2,
507{
508 type Output = P2::Output;
509
510 type State = S;
511
512 fn parse(
513 &mut self,
514 input: &'a str,
515 location: Location,
516 state: Self::State,
517 ) -> ParseResult<'a, Self::Output, Self::State> {
518 self.0.parse(input, location, state).and_then(
519 |cur_input, cur_output, cur_location, cur_state| {
520 self.1.clone()(cur_output).parse(cur_input, cur_location, cur_state)
521 },
522 )
523 }
524}
525
526#[derive(Clone)]
527pub struct Pred<'a, P: 'a, F>(P, F, &'a str);
528
529impl<'a, P: 'a, F: 'a, Output: std::fmt::Display> Parser<'a> for Pred<'a, P, F>
530where
531 P: Parser<'a, Output = Output>,
532 F: Fn(&P::Output) -> bool,
533{
534 type Output = P::Output;
535
536 type State = P::State;
537
538 fn parse(
539 &mut self,
540 input: &'a str,
541 location: Location,
542 state: Self::State,
543 ) -> ParseResult<'a, Self::Output, Self::State> {
544 match self.0.parse(input, location, state) {
545 ParseResult::Ok {
546 input: cur_input,
547 output: content,
548 location: cur_location,
549 state: cur_state,
550 committed: cur_committed,
551 } => {
552 if self.1(&content) {
553 ParseResult::Ok {
554 input: cur_input,
555 output: content,
556 location: cur_location,
557 state: cur_state,
558 committed: true,
559 }
560 } else {
561 ParseResult::Err {
562 message: format!(
563 "I'm expecting {} but found {}.",
564 self.2,
565 display_token(content)
566 ),
567 from: location,
568 to: cur_location,
569 state: cur_state,
570 committed: cur_committed,
571 }
572 }
573 }
574 ParseResult::Err {
575 message,
576 from,
577 to,
578 state,
579 ..
580 } => ParseResult::Err {
581 message,
582 from,
583 to,
584 state,
585 committed: false,
586 },
587 }
588 }
589}
590
591#[derive(Clone)]
592pub struct End<P>(P);
593
594impl<'a, P> Parser<'a> for End<P>
595where
596 P: Parser<'a>,
597{
598 type Output = P::Output;
599
600 type State = P::State;
601
602 fn parse(
603 &mut self,
604 input: &'a str,
605 location: Location,
606 state: Self::State,
607 ) -> ParseResult<'a, Self::Output, Self::State> {
608 match self.0.parse(input, location, state) {
609 ParseResult::Ok {
610 input,
611 location,
612 state,
613 output,
614 ..
615 } => {
616 if !input.is_empty() {
617 ParseResult::Err {
618 message: "I'm expecting the end of input.".to_string(),
619 from: location,
620 to: location,
621 state,
622 committed: false,
623 }
624 } else {
625 ParseResult::Ok {
626 input,
627 output,
628 location,
629 state,
630 committed: false,
631 }
632 }
633 }
634 ParseResult::Err {
635 message,
636 from,
637 to,
638 state,
639 committed,
640 } => ParseResult::Err {
641 message,
642 from,
643 to,
644 state,
645 committed,
646 },
647 }
648 }
649}
650
651#[derive(Clone)]
652pub struct UpdateState<P, F>(P, F);
653
654impl<'a, P: 'a, F> Parser<'a> for UpdateState<P, F>
655where
656 P: Parser<'a>,
657 F: Fn(&P::Output, P::State) -> P::State,
658{
659 type Output = P::Output;
660
661 type State = P::State;
662
663 fn parse(
664 &mut self,
665 input: &'a str,
666 location: Location,
667 state: Self::State,
668 ) -> ParseResult<'a, Self::Output, Self::State> {
669 match self.0.parse(input, location, state) {
670 ParseResult::Ok {
671 input: cur_input,
672 location: cur_location,
673 state: cur_state,
674 output,
675 committed,
676 } => {
677 let new_state = self.1(&output, cur_state);
678 ParseResult::Ok {
679 input: cur_input,
680 output,
681 location: cur_location,
682 state: new_state,
683 committed,
684 }
685 }
686 err @ ParseResult::Err { .. } => err,
687 }
688 }
689}
690
691#[derive(Clone)]
692pub struct Update<P, F>(P, F);
693
694impl<'a, P: 'a, A, B, F: Clone> Parser<'a> for Update<P, F>
695where
696 P: Parser<'a, Output = A>,
697 F: FnOnce(&'a str, A, Location, P::State) -> ParseResult<'a, B, P::State>,
698{
699 type Output = B;
700
701 type State = P::State;
702
703 fn parse(
704 &mut self,
705 input: &'a str,
706 location: Location,
707 state: Self::State,
708 ) -> ParseResult<'a, Self::Output, Self::State> {
709 match self.0.parse(input, location, state) {
710 ParseResult::Ok {
711 input: cur_input,
712 location: cur_location,
713 state: cur_state,
714 output,
715 ..
716 } => self.1.clone()(cur_input, output, cur_location, cur_state),
717 ParseResult::Err {
718 message,
719 from,
720 to,
721 state,
722 committed,
723 } => ParseResult::Err {
724 message,
725 from,
726 to,
727 state,
728 committed,
729 },
730 }
731 }
732}
733
734pub struct Ignore<P>(P);
735
736impl<'a, P> Parser<'a> for Ignore<P>
737where
738 P: Parser<'a>,
739{
740 type Output = ();
741
742 type State = P::State;
743
744 fn parse(
745 &mut self,
746 input: &'a str,
747 location: Location,
748 state: Self::State,
749 ) -> ParseResult<'a, Self::Output, Self::State> {
750 match self.0.parse(input, location, state) {
751 ParseResult::Ok {
752 input,
753 location,
754 state,
755 committed,
756 ..
757 } => ParseResult::Ok {
758 input,
759 location,
760 output: (),
761 state,
762 committed,
763 },
764 ParseResult::Err {
765 message,
766 from,
767 to,
768 state,
769 committed,
770 } => ParseResult::Err {
771 message,
772 from,
773 to,
774 state,
775 committed,
776 },
777 }
778 }
779}
780
781pub struct Keep<P1, P2>(P1, P2);
782
783impl<'a, P1, P2, A, B, F, S: Clone + 'a> Parser<'a> for Keep<P1, P2>
784where
785 F: FnOnce(A) -> B,
786 P1: Parser<'a, Output = F, State = S>,
787 P2: Parser<'a, Output = A, State = S>,
788{
789 type Output = B;
790
791 type State = P1::State;
792
793 fn parse(
794 &mut self,
795 input: &'a str,
796 location: Location,
797 state: Self::State,
798 ) -> ParseResult<'a, Self::Output, Self::State> {
799 self.0
800 .parse(input, location, state)
801 .and_then(|cur_input, func, cur_location, cur_state| {
802 self.1.parse(cur_input, cur_location, cur_state).map(func)
803 })
804 }
805}
806
807pub struct Skip<P1, P2>(P1, P2);
808
809impl<'a, P1, P2, S: Clone + 'a> Parser<'a> for Skip<P1, P2>
810where
811 P1: Parser<'a, State = S>,
812 P2: Parser<'a, State = S>,
813{
814 type Output = P1::Output;
815
816 type State = P1::State;
817
818 fn parse(
819 &mut self,
820 input: &'a str,
821 location: Location,
822 state: Self::State,
823 ) -> ParseResult<'a, Self::Output, Self::State> {
824 self.0.parse(input, location, state).and_then(
825 |cur_input, left_output, cur_location, cur_state| {
826 self.1
827 .parse(cur_input, cur_location, cur_state)
828 .map(|_| left_output)
829 },
830 )
831 }
832}
833
834#[derive(Clone)]
835pub struct Backtrackable<P>(P);
836
837impl<'a, P: 'a> Parser<'a> for Backtrackable<P>
838where
839 P: Parser<'a>,
840{
841 type Output = P::Output;
842
843 type State = P::State;
844
845 fn parse(
846 &mut self,
847 input: &'a str,
848 location: Location,
849 state: Self::State,
850 ) -> ParseResult<'a, Self::Output, Self::State> {
851 self.0.parse(input, location, state).backtrackable()
852 }
853}
854
855pub trait Parser<'a> {
856 type Output;
857
858 type State: Clone;
859
860 fn parse(
863 &mut self,
864 input: &'a str,
865 location: Location,
866 state: Self::State,
867 ) -> ParseResult<'a, Self::Output, Self::State>;
868 fn run(
884 &mut self,
885 input: &'a str,
886 state: Self::State,
887 ) -> ParseResult<'a, Self::Output, Self::State> {
888 self.parse(input, Location { row: 1, col: 1 }, state)
889 }
890 fn map<F: 'a, NewOutput: 'a>(self, map_fn: F) -> Map<Self, F>
897 where
898 Self: Sized + 'a,
899 F: Fn(Self::Output) -> NewOutput,
900 {
901 map(self, map_fn)
902 }
903 fn map_with_state<F: 'a, NewOutput: 'a>(self, map_fn: F) -> MapWithState<Self, F>
911 where
912 Self: Sized + 'a,
913 F: Fn(Self::Output, Self::State) -> NewOutput,
914 {
915 map_with_state(self, map_fn)
916 }
917 fn map_err<F>(self, map_fn: F) -> MapErr<Self, F>
924 where
925 Self: Sized + 'a,
926 F: Fn(String) -> String,
927 {
928 map_err(self, map_fn)
929 }
930 fn and_then<F, P2, B>(self, f: F) -> AndThen<Self, F>
937 where
938 Self: Sized + 'a,
939 P2: Parser<'a, Output = B>,
940 F: Fn(Self::Output) -> P2,
941 {
942 and_then(self, f)
943 }
944 fn pred<F>(self, predicate: F, expecting: &'a str) -> Pred<Self, F>
947 where
948 Self: Sized + 'a,
949 F: Fn(&Self::Output) -> bool,
950 {
951 pred(self, predicate, expecting)
952 }
953 fn ignore(self) -> Ignore<Self>
955 where
956 Self: Sized + 'a,
957 {
958 Ignore(self)
959 }
960 fn update_state<F>(self, f: F) -> UpdateState<Self, F>
963 where
964 Self: Sized + 'a,
965 F: Fn(Self::Output, Self::State) -> Self::State,
966 {
967 update_state(self, f)
968 }
969 fn update<B, F: Clone>(self, f: F) -> Update<Self, F>
976 where
977 Self: Sized + 'a,
978 F: FnOnce(&'a str, Self::Output, Location, Self::State) -> ParseResult<'a, B, Self::State>,
979 {
980 update(self, f)
981 }
982 fn end(self) -> End<Self>
997 where
998 Self: Sized + 'a,
999 {
1000 end(self)
1001 }
1002 fn keep<A, B, P2>(self, arg_parser: P2) -> Keep<Self, P2>
1017 where
1018 Self: Sized + 'a,
1019 Self::Output: FnOnce(A) -> B + Clone,
1020 P2: Parser<'a, Output = A>,
1021 {
1022 keep(self, arg_parser)
1023 }
1024 fn skip<P2>(self, ignored_parser: P2) -> Skip<Self, P2>
1039 where
1040 Self: Sized + 'a,
1041 P2: Parser<'a>,
1042 {
1043 Skip(self, ignored_parser)
1044 }
1045
1046 fn backtrackable(self) -> Backtrackable<Self>
1047 where
1048 Self: Sized + 'a,
1049 {
1050 backtrackable(self)
1051 }
1052
1053 fn first_of_two<T2>(self) -> OneOfTwo<Self, T2>
1054 where
1055 Self: Sized + 'a,
1056 T2: Parser<'a, Output = Self::Output, State = Self::State>,
1057 {
1058 OneOfTwo::First(self)
1059 }
1060
1061 fn second_of_two<T1>(self) -> OneOfTwo<T1, Self>
1062 where
1063 Self: Sized + 'a,
1064 T1: Parser<'a, Output = Self::Output, State = Self::State>,
1065 {
1066 OneOfTwo::Second(self)
1067 }
1068
1069 fn first_of_three<T2, T3>(self) -> OneOfThree<Self, T2, T3>
1070 where
1071 Self: Sized + 'a,
1072 T2: Parser<'a, Output = Self::Output, State = Self::State>,
1073 T3: Parser<'a, Output = Self::Output, State = Self::State>,
1074 {
1075 OneOfThree::First(self)
1076 }
1077
1078 fn second_of_three<T1, T3>(self) -> OneOfThree<T1, Self, T3>
1079 where
1080 Self: Sized + 'a,
1081 T1: Parser<'a, Output = Self::Output, State = Self::State>,
1082 T3: Parser<'a, Output = Self::Output, State = Self::State>,
1083 {
1084 OneOfThree::Second(self)
1085 }
1086
1087 fn third_of_three<T1, T2>(self) -> OneOfThree<T1, T2, Self>
1088 where
1089 Self: Sized + 'a,
1090 T1: Parser<'a, Output = Self::Output, State = Self::State>,
1091 T2: Parser<'a, Output = Self::Output, State = Self::State>,
1092 {
1093 OneOfThree::Third(self)
1094 }
1095}
1096
1097fn and_then<'a, P1, P2, F>(parser: P1, f: F) -> AndThen<P1, F>
1098where
1099 P1: Parser<'a>,
1100 P2: Parser<'a>,
1101 F: Fn(P1::Output) -> P2,
1102{
1103 AndThen(parser, f)
1104}
1105
1106pub fn token<'a, S: Clone + 'a>(expected: &'a str) -> impl Parser<Output = &'a str, State = S> {
1110 fn_parser(move |input: &'a str, location: Location, state: S| {
1111 let peek = input.get(0..expected.len());
1112 if peek == Some(expected) {
1113 ParseResult::Ok {
1114 input: &input[expected.len()..],
1115 output: expected,
1116 location: increment_col(unicode_column_width(expected), location),
1117 state,
1118 committed: true,
1119 }
1120 } else {
1121 let expected_len = expected.graphemes(true).count();
1122 let peek_str = &input.graphemes(true).take(expected_len).join("");
1123 ParseResult::Err {
1124 message: format!(
1125 "I'm expecting a `{}` but found {}.",
1126 expected,
1127 display_token(peek_str)
1128 ),
1129 from: location,
1130 to: Location {
1131 col: location.col + unicode_column_width(peek_str),
1132 ..location
1133 },
1134 state,
1135 committed: false,
1136 }
1137 }
1138 })
1139}
1140
1141fn increment_col(additional_col: usize, location: Location) -> Location {
1142 Location {
1143 col: location.col + additional_col,
1144 ..location
1145 }
1146}
1147
1148fn increment_row(additional_row: usize, location: Location) -> Location {
1149 Location {
1150 row: location.row + additional_row,
1151 col: 1,
1152 }
1153}
1154
1155fn display_token<T: Display>(token: T) -> String {
1156 let token_str = &token.to_string();
1157 if unicode_column_width(token_str) == 0 {
1158 "nothing".to_string()
1159 } else {
1160 format!("`{}`", token_str.replace('\n', "\\n"))
1161 }
1162}
1163
1164fn pair<'a, P1: 'a, P2: 'a, R1: Clone + 'a, R2: Clone + 'a, S: Clone + 'a>(
1167 mut parser1: P1,
1168 mut parser2: P2,
1169) -> impl Parser<'a, Output = (R1, R2), State = S>
1170where
1171 P1: Parser<'a, Output = R1, State = S>,
1172 P2: Parser<'a, Output = R2, State = S>,
1173{
1174 fn_parser(move |input, location, state| {
1175 parser1.parse(input, location, state).and_then(
1176 |cur_input, first_output, cur_location, cur_state| {
1177 parser2
1178 .parse(cur_input, cur_location, cur_state)
1179 .map(|second_output| (first_output.clone(), second_output))
1180 },
1181 )
1182 })
1183}
1184
1185fn map<'a, P: 'a, F: 'a, B>(parser: P, map_fn: F) -> Map<P, F>
1186where
1187 P: Parser<'a>,
1188 F: Fn(P::Output) -> B,
1189{
1190 Map(parser, map_fn)
1191}
1192
1193fn map_with_state<'a, P: 'a, F: 'a, A, B>(parser: P, map_fn: F) -> MapWithState<P, F>
1194where
1195 P: Parser<'a, Output = A>,
1196 F: Fn(P::Output, P::State) -> B,
1197{
1198 MapWithState(parser, map_fn)
1199}
1200
1201fn map_err<'a, P: 'a, F>(parser: P, map_fn: F) -> MapErr<P, F>
1202where
1203 P: Parser<'a>,
1204 F: Fn(String) -> String,
1205{
1206 MapErr(parser, map_fn)
1207}
1208
1209fn backtrackable<'a, P>(parser: P) -> Backtrackable<P>
1210where
1211 P: Parser<'a>,
1212{
1213 Backtrackable(parser)
1214}
1215
1216fn left<'a, P1: 'a, P2: 'a, R1: Clone + 'a, R2: Clone + 'a, S: Clone + 'a>(
1218 parser1: P1,
1219 parser2: P2,
1220) -> impl Parser<'a, Output = R1, State = S>
1221where
1222 P1: Parser<'a, Output = R1, State = S>,
1223 P2: Parser<'a, Output = R2, State = S>,
1224{
1225 map(pair(parser1, parser2), |(left, _right)| left)
1226}
1227
1228fn keep<'a, P1, P2, F, A, B>(parser1: P1, parser2: P2) -> Keep<P1, P2>
1229where
1230 F: FnOnce(A) -> B,
1231 P1: Parser<'a, Output = F>,
1232 P2: Parser<'a, Output = A>,
1233{
1234 Keep(parser1, parser2)
1235}
1236
1237pub type BoxedParser<'a, A, S> = Box<dyn FnMut(&'a str, Location, S) -> ParseResult<'a, A, S> + 'a>;
1238
1239impl<'a, A, S: Clone + 'a> Parser<'a> for BoxedParser<'a, A, S> {
1240 type Output = A;
1241 type State = S;
1242
1243 fn parse(&mut self, input: &'a str, location: Location, state: S) -> ParseResult<'a, A, S> {
1244 (*self)(input, location, state)
1245 }
1246}
1247
1248#[derive(Copy, Clone)]
1249pub struct FnParser<F, A, S>(F, PhantomData<A>, PhantomData<S>);
1250
1251pub fn fn_parser<'a, A, S: Clone, F>(f: F) -> FnParser<F, A, S>
1252where
1253 F: FnMut(&'a str, Location, S) -> ParseResult<'a, A, S>,
1254{
1255 FnParser(f, PhantomData, PhantomData)
1256}
1257
1258impl<'a, A, S: Clone, F> Parser<'a> for FnParser<F, A, S>
1259where
1260 F: FnMut(&'a str, Location, S) -> ParseResult<'a, A, S>,
1261{
1262 type Output = A;
1263 type State = S;
1264
1265 fn parse(&mut self, input: &'a str, location: Location, state: S) -> ParseResult<'a, A, S> {
1266 (self.0)(input, location, state)
1267 }
1268}
1269
1270#[doc(hidden)]
1271pub fn succeed_helper<'a, A: Clone + 'a, S: Clone + 'a>(
1272 output: A,
1273) -> impl Parser<'a, Output = A, State = S> {
1274 fn_parser(move |input, location, state: S| ParseResult::Ok {
1275 input,
1276 location,
1277 state,
1278 output: output.clone(),
1279 committed: false,
1280 })
1281}
1282
1283#[macro_export]
1288macro_rules! succeed {
1289 (|$first_arg:ident $(, $arg:ident )*| $function_body:expr) => {
1290 succeed_helper(move |$first_arg| $(move |$arg|)* {
1291 $function_body
1292 })
1293 };
1294 (|$first_arg:ident:$first_arg_type:ty $(, $arg:ident:$arg_type:ty )*| $function_body:expr) => {
1295 succeed_helper(move |$first_arg:$first_arg_type| $(move |$arg:$arg_type|)* {
1296 $function_body
1297 })
1298 };
1299 ($value:expr) => {
1300 succeed_helper($value)
1301 };
1302 () => {
1303 succeed_helper(())
1304 }
1305}
1306
1307fn end<'a, P>(parser: P) -> End<P>
1308where
1309 P: Parser<'a>,
1310{
1311 End(parser)
1312}
1313
1314pub fn problem<'a, F1: 'a, F2: 'a, A: 'a, S: Clone + 'a>(
1318 message: String,
1319 from: F1,
1320 to: F2,
1321) -> impl Parser<'a, Output = A, State = S>
1322where
1323 F1: Fn(Location) -> Location,
1324 F2: Fn(Location) -> Location,
1325{
1326 fn_parser(move |_input, location, state: S| ParseResult::Err {
1327 message: message.clone(),
1328 from: from(location),
1329 to: to(location),
1330 state,
1331 committed: false,
1332 })
1333}
1334
1335fn right<'a, P1: 'a, P2: 'a, R1: Clone + 'a, R2: Clone + 'a, S: Clone + 'a>(
1337 parser1: P1,
1338 parser2: P2,
1339) -> impl Parser<'a, Output = R2, State = S>
1340where
1341 P1: Parser<'a, Output = R1, State = S>,
1342 P2: Parser<'a, Output = R2, State = S>,
1343{
1344 map(pair(parser1, parser2), |(_left, right)| right)
1345}
1346
1347pub fn one_or_more<'a, P: 'a, A: Clone + 'a, S: Clone + 'a>(
1349 mut parser: P,
1350) -> BoxedParser<'a, Vec<A>, S>
1351where
1352 P: Parser<'a, Output = A, State = S>,
1353{
1354 Box::new(move |mut input, mut location, mut state| {
1355 let mut output = Vec::new();
1356 let mut committed = false;
1357
1358 match parser.parse(input, location, state) {
1359 ParseResult::Ok {
1360 input: cur_input,
1361 output: first_item,
1362 location: cur_location,
1363 state: cur_state,
1364 committed: cur_committed,
1365 } => {
1366 input = cur_input;
1367 location = cur_location;
1368 state = cur_state;
1369 committed |= cur_committed;
1370 output.push(first_item);
1371 }
1372 ParseResult::Err {
1373 message,
1374 from,
1375 to,
1376 state,
1377 committed,
1378 } => {
1379 return ParseResult::Err {
1380 message,
1381 from,
1382 to,
1383 state,
1384 committed,
1385 };
1386 }
1387 }
1388
1389 loop {
1390 match parser.parse(input, location, state.clone()) {
1391 ParseResult::Ok {
1392 input: cur_input,
1393 output: cur_item,
1394 location: cur_location,
1395 state: cur_state,
1396 committed: cur_committed,
1397 ..
1398 } => {
1399 input = cur_input;
1400 location = cur_location;
1401 state = cur_state;
1402 committed |= cur_committed;
1403 output.push(cur_item);
1404 }
1405 ParseResult::Err {
1406 message,
1407 from,
1408 to,
1409 state,
1410 committed,
1411 } => {
1412 if committed {
1413 return ParseResult::Err {
1414 message,
1415 from,
1416 to,
1417 state,
1418 committed,
1419 };
1420 } else {
1421 break;
1422 }
1423 }
1424 }
1425 }
1426
1427 ParseResult::Ok {
1428 input,
1429 output,
1430 location,
1431 state,
1432 committed,
1433 }
1434 })
1435}
1436
1437pub fn zero_or_more_until<'a, P: 'a, A: Clone + 'a, E: 'a, B: 'a, S: Clone + 'a>(
1439 item_name: &'static str,
1440 mut parser: P,
1441 end_name: &'static str,
1442 mut end_parser: E,
1443) -> BoxedParser<'a, Vec<A>, S>
1444where
1445 P: Parser<'a, Output = A, State = S>,
1446 E: Parser<'a, Output = B, State = ()>,
1447{
1448 Box::new(move |mut input, mut location, mut state| {
1449 let mut output = Vec::new();
1450 let mut committed = false;
1451
1452 match end_parser.parse(input, location, ()) {
1455 ParseResult::Ok {
1456 committed: cur_committed,
1457 ..
1458 } => {
1459 committed |= cur_committed;
1460 return ParseResult::Ok {
1461 input,
1462 output,
1463 location,
1464 state,
1465 committed,
1466 };
1467 }
1468 ParseResult::Err {
1469 message,
1470 from,
1471 to,
1472 committed,
1473 ..
1474 } => {
1475 if committed {
1476 return ParseResult::Err {
1477 message,
1478 from,
1479 to,
1480 state,
1481 committed,
1482 };
1483 }
1484 } }
1486
1487 match parser.parse(input, location, state) {
1488 ParseResult::Ok {
1489 input: cur_input,
1490 output: first_item,
1491 location: cur_location,
1492 state: cur_state,
1493 committed: cur_committed,
1494 } => {
1495 input = cur_input;
1496 location = cur_location;
1497 state = cur_state;
1498 committed |= cur_committed;
1499 output.push(first_item);
1500 }
1501 ParseResult::Err {
1502 message,
1503 from,
1504 to,
1505 state,
1506 committed: cur_committed,
1507 } => {
1508 committed |= cur_committed;
1509 if input.is_empty() {
1512 return ParseResult::Ok {
1514 input,
1515 output,
1516 location,
1517 state,
1518 committed,
1519 };
1520 } else {
1521 return ParseResult::Err {
1522 message,
1523 from,
1524 to,
1525 state,
1526 committed,
1527 };
1528 }
1529 }
1530 }
1531
1532 loop {
1533 match end_parser.parse(input, location, ()) {
1534 ParseResult::Ok {
1535 committed: cur_committed,
1536 ..
1537 } => {
1538 committed |= cur_committed;
1539 return ParseResult::Ok {
1540 input,
1541 output,
1542 location,
1543 state,
1544 committed,
1545 };
1546 }
1547 ParseResult::Err {
1548 message,
1549 from,
1550 to,
1551 committed: err_committed,
1552 ..
1553 } => {
1554 if err_committed {
1555 return ParseResult::Err {
1556 message,
1557 from,
1558 to,
1559 state,
1560 committed: err_committed,
1561 };
1562 }
1563 match parser.parse(input, location, state.clone()) {
1564 ParseResult::Ok {
1565 input: cur_input,
1566 output: cur_item,
1567 location: cur_location,
1568 state: cur_state,
1569 committed: cur_committed,
1570 } => {
1571 input = cur_input;
1572 location = cur_location;
1573 state = cur_state;
1574 committed |= cur_committed;
1575 output.push(cur_item);
1576 }
1577 ParseResult::Err {
1578 from: end_from,
1579 to: end_to,
1580 committed: cur_committed,
1581 ..
1582 } => {
1583 committed |= cur_committed;
1584 if input.is_empty() {
1585 return ParseResult::Ok {
1587 input,
1588 output,
1589 location,
1590 state,
1591 committed,
1592 };
1593 } else {
1594 return ParseResult::Err {
1595 message: format!("I'm expecting either {} or {}. However, neither was found.", item_name, end_name),
1596 from: end_from,
1597 to: end_to,
1598 state,
1599 committed,
1600 };
1601 }
1602 }
1603 }
1604 }
1605 }
1606 }
1607 })
1608}
1609
1610pub fn one_or_more_until<'a, P: 'a, A: Clone + 'a, E: 'a, B: 'a, S: Clone + 'a>(
1612 item_name: &'static str,
1613 mut parser: P,
1614 end_name: &'static str,
1615 mut end_parser: E,
1616) -> BoxedParser<'a, Vec<A>, S>
1617where
1618 P: Parser<'a, Output = A, State = S>,
1619 E: Parser<'a, Output = B, State = ()>,
1620{
1621 Box::new(move |mut input, mut location, mut state| {
1622 let mut output = Vec::new();
1623 let mut committed = false;
1624
1625 match end_parser.parse(input, location, ()) {
1626 ParseResult::Ok {
1627 location: end_location,
1628 committed: cur_committed,
1629 ..
1630 } => {
1631 committed |= cur_committed;
1632 return ParseResult::Err {
1633 message: format!(
1634 "I'm expecting at least one occurrence of {} but reached {}.",
1635 item_name, end_name
1636 ),
1637 from: location,
1638 to: end_location,
1639 state,
1640 committed,
1641 };
1642 }
1643 ParseResult::Err {
1644 message,
1645 from,
1646 to,
1647 committed: err_committed,
1648 ..
1649 } => {
1650 if err_committed {
1651 return ParseResult::Err {
1652 message,
1653 from,
1654 to,
1655 state,
1656 committed: err_committed,
1657 };
1658 }
1659 match parser.parse(input, location, state) {
1660 ParseResult::Ok {
1661 input: cur_input,
1662 output: first_item,
1663 location: cur_location,
1664 state: cur_state,
1665 committed: cur_committed,
1666 } => {
1667 input = cur_input;
1668 location = cur_location;
1669 state = cur_state;
1670 committed |= cur_committed;
1671 output.push(first_item);
1672 }
1673 ParseResult::Err {
1674 message,
1675 from,
1676 to,
1677 state,
1678 committed: cur_committed,
1679 } => {
1680 committed |= cur_committed;
1681 return ParseResult::Err {
1682 message,
1683 from,
1684 to,
1685 state,
1686 committed,
1687 };
1688 }
1689 }
1690 }
1691 }
1692
1693 loop {
1694 match end_parser.parse(input, location, ()) {
1695 ParseResult::Ok { .. } => {
1696 return ParseResult::Ok {
1697 input,
1698 output,
1699 location,
1700 state,
1701 committed,
1702 };
1703 }
1704 ParseResult::Err {
1705 message,
1706 from,
1707 to,
1708 committed: err_committed,
1709 ..
1710 } => {
1711 if err_committed {
1712 return ParseResult::Err {
1713 message,
1714 from,
1715 to,
1716 state,
1717 committed: err_committed,
1718 };
1719 }
1720 match parser.parse(input, location, state.clone()) {
1721 ParseResult::Ok {
1722 input: cur_input,
1723 output: cur_item,
1724 location: cur_location,
1725 state: cur_state,
1726 committed: cur_committed,
1727 } => {
1728 input = cur_input;
1729 location = cur_location;
1730 state = cur_state;
1731 committed |= cur_committed;
1732 output.push(cur_item);
1733 }
1734 ParseResult::Err {
1735 from: end_from,
1736 to: end_to,
1737 committed: cur_committed,
1738 ..
1739 } => {
1740 committed |= cur_committed;
1741 if input.is_empty() {
1742 return ParseResult::Ok {
1744 input,
1745 output,
1746 location,
1747 state,
1748 committed,
1749 };
1750 } else {
1751 return ParseResult::Err {
1752 message: format!("I'm expecting either {} or {}. However, neither was found.", item_name, end_name),
1753 from: end_from,
1754 to: end_to,
1755 state,
1756 committed,
1757 };
1758 }
1759 }
1760 }
1761 }
1762 }
1763 }
1764 })
1765}
1766
1767pub fn zero_or_more<'a, P: 'a, A: Clone + 'a, S: Clone + 'a>(
1769 mut parser: P,
1770) -> BoxedParser<'a, Vec<A>, S>
1771where
1772 P: Parser<'a, Output = A, State = S>,
1773{
1774 Box::new(move |mut input, mut location, mut state: S| {
1775 let mut output = Vec::new();
1776 let mut committed = false;
1777
1778 loop {
1779 match parser.parse(input, location, state.clone()) {
1780 ParseResult::Ok {
1781 input: cur_input,
1782 output: cur_item,
1783 location: cur_location,
1784 state: cur_state,
1785 committed: cur_committed,
1786 } => {
1787 input = cur_input;
1788 location = cur_location;
1789 state = cur_state;
1790 committed |= cur_committed;
1791 output.push(cur_item);
1792 }
1793 ParseResult::Err {
1794 message,
1795 from,
1796 to,
1797 state,
1798 committed,
1799 } => {
1800 if committed {
1801 return ParseResult::Err {
1802 message,
1803 from,
1804 to,
1805 state,
1806 committed,
1807 };
1808 } else {
1809 break;
1810 }
1811 }
1812 }
1813 }
1814
1815 ParseResult::Ok {
1816 input,
1817 output,
1818 location,
1819 state,
1820 committed,
1821 }
1822 })
1823}
1824
1825fn any_grapheme<'a, S: Clone + 'a>(
1827 expecting: &'a str,
1828) -> impl Parser<'a, Output = &'a str, State = S> {
1829 fn_parser(move |input: &'a str, location: Location, state| {
1830 match Uni::graphemes(input, true).next() {
1831 Some(c) => match c {
1832 "\n" | "\r\n" => ParseResult::Ok {
1833 input: &input[c.len()..],
1834 output: c,
1835 location: increment_row(1, location),
1836 state,
1837 committed: false,
1838 },
1839 _ => ParseResult::Ok {
1840 input: &input[c.len()..],
1841 output: c,
1842 location: increment_col(grapheme_column_width(c), location),
1843 state,
1844 committed: false,
1845 },
1846 },
1847 _ => ParseResult::Err {
1848 message: format!("I'm expecting {} but reached the end of input.", expecting),
1849 from: location,
1850 to: location,
1851 state,
1852 committed: false,
1853 },
1854 }
1855 })
1856}
1857
1858fn any_char<'a, S: Clone + 'a>(expecting: &str) -> impl Parser<'_, Output = char, State = S> {
1860 fn_parser(
1861 move |input: &str, location: Location, state| match input.chars().next() {
1862 Some(c) => match c {
1863 '\n' => ParseResult::Ok {
1864 input: &input[c.len_utf8()..],
1865 output: c,
1866 location: increment_row(1, location),
1867 state,
1868 committed: false,
1869 },
1870 _ => ParseResult::Ok {
1871 input: &input[c.len_utf8()..],
1872 output: c,
1873 location: increment_col(char_column_width(c), location),
1874 state,
1875 committed: false,
1876 },
1877 },
1878 _ => ParseResult::Err {
1879 message: format!("I'm expecting {} but reached the end of input.", expecting),
1880 from: location,
1881 to: location,
1882 state,
1883 committed: false,
1884 },
1885 },
1886 )
1887}
1888
1889pub fn chomp_if<'a, F: 'a, S: Clone + 'a>(
1891 predicate: F,
1892 expecting: &'a str,
1893) -> impl Parser<'_, Output = (), State = S>
1894where
1895 F: Fn(&'a str) -> bool,
1896{
1897 any_grapheme(expecting)
1898 .pred(move |output| predicate(output), expecting)
1899 .ignore()
1900}
1901
1902pub fn chomp_ifc<'a, F: 'a, S: Clone + 'a>(
1904 predicate: F,
1905 expecting: &'a str,
1906) -> impl Parser<'_, Output = (), State = S>
1907where
1908 F: Fn(char) -> bool,
1909{
1910 any_char(expecting)
1911 .pred(move |output| predicate(*output), expecting)
1912 .ignore()
1913}
1914
1915pub fn chomp_while0<'a, F: 'a, S: Clone + 'a>(
1917 predicate: F,
1918 expecting: &'a str,
1919) -> impl Parser<'_, Output = (), State = S>
1920where
1921 F: Fn(&'a str) -> bool,
1922{
1923 zero_or_more(chomp_if(predicate, expecting)).ignore()
1924}
1925
1926pub fn chomp_while0c<'a, F: 'a, S: Clone + 'a>(
1937 predicate: F,
1938 expecting: &'a str,
1939) -> impl Parser<'_, Output = (), State = S>
1940where
1941 F: Fn(char) -> bool,
1942{
1943 zero_or_more(chomp_ifc(predicate, expecting)).ignore()
1944}
1945
1946pub fn chomp_while1<'a, F: 'a, S: Clone + 'a>(
1948 predicate: F,
1949 expecting: &'a str,
1950) -> impl Parser<'_, Output = (), State = S>
1951where
1952 F: Fn(&str) -> bool,
1953{
1954 one_or_more(chomp_if(predicate, expecting)).ignore()
1955}
1956
1957pub fn chomp_while1c<'a, F: 'a, S: Clone + 'a>(
1971 predicate: F,
1972 expecting: &'a str,
1973) -> impl Parser<'_, Output = (), State = S>
1974where
1975 F: Fn(char) -> bool,
1976{
1977 one_or_more(chomp_ifc(predicate, expecting)).ignore()
1978}
1979pub fn take_chomped<'a, P: 'a, S: Clone + 'a>(
1995 mut parser: P,
1996) -> impl Parser<'a, Output = String, State = S>
1997where
1998 P: Parser<'a, State = S>,
1999{
2000 fn_parser(
2001 move |input, location, state| match parser.parse(input, location, state) {
2002 ParseResult::Ok {
2003 input: cur_input,
2004 location: cur_location,
2005 state: cur_state,
2006 committed: cur_committed,
2007 ..
2008 } => ParseResult::Ok {
2009 input: cur_input,
2010 output: get_difference(input, cur_input).to_string(),
2011 location: cur_location,
2012 state: cur_state,
2013 committed: cur_committed,
2014 },
2015 ParseResult::Err {
2016 message,
2017 from,
2018 to,
2019 state,
2020 committed,
2021 } => ParseResult::Err {
2022 message,
2023 from,
2024 to,
2025 state,
2026 committed,
2027 },
2028 },
2029 )
2030}
2031
2032fn get_difference<'a>(whole_str: &'a str, substr: &'a str) -> &'a str {
2033 &whole_str[..whole_str.len() - substr.len()]
2034}
2035
2036fn pred<'a, P: 'a, F>(parser: P, predicate: F, expecting: &'a str) -> Pred<'a, P, F>
2037where
2038 P: Parser<'a>,
2039 F: Fn(&P::Output) -> bool,
2040{
2041 Pred(parser, predicate, expecting)
2042}
2043
2044fn space_char<'a, S: Clone + 'a>() -> impl Parser<'a, Output = (), State = S> {
2046 chomp_if(&(|c: &str| c == " "), "a whitespace")
2047}
2048
2049fn newline_char<'a, S: Clone + 'a>() -> impl Parser<'a, Output = (), State = S> {
2053 fn_parser(move |input, location, state: S| {
2054 let mut cur_input: &str = input;
2055 let mut cur_location: Location = location;
2056 let mut cur_state: S = state.clone();
2057 let result1 =
2058 chomp_ifc(&(|c: char| c == '\r'), "a carriage return").parse(input, location, state);
2059 if let ParseResult::Ok {
2060 input,
2061 location,
2062 state,
2063 ..
2064 } = result1
2065 {
2066 cur_input = input;
2067 cur_location = location;
2068 cur_state = state;
2069 }
2070 let result = chomp_ifc(&(|c: char| c == '\n'), "a newline").parse(
2071 cur_input,
2072 cur_location,
2073 cur_state,
2074 );
2075 match result {
2076 ParseResult::Ok {
2077 input,
2078 output,
2079 location,
2080 state,
2081 committed,
2082 } => ParseResult::Ok {
2083 input,
2084 output,
2085 state,
2086 committed,
2087 location: increment_row(1, location),
2088 },
2089 err @ ParseResult::Err { .. } => err,
2090 }
2091 })
2092}
2093
2094pub fn newline0<'a, P: 'a, S: Clone + 'a>(
2098 indent_parser: P,
2099) -> impl Parser<'a, Output = (), State = S>
2100where
2101 P: Parser<'a, Output = (), State = S>,
2102{
2103 zero_or_more(pair(indent_parser, newline_char())).ignore()
2104}
2105
2106pub fn newline1<'a, P>(indent_parser: P) -> impl Parser<'a, Output = ()>
2110where
2111 P: Parser<'a, Output = ()> + 'a,
2112{
2113 pair(newline_char(), newline0(indent_parser)).ignore()
2114}
2115
2116pub fn space0<'a, S: Clone + 'a>() -> impl Parser<'a, Output = (), State = S> {
2118 zero_or_more(space_char()).ignore()
2119}
2120
2121pub fn space1<'a, S: Clone + 'a>() -> impl Parser<'a, Output = (), State = S> {
2123 one_or_more(space_char()).ignore()
2124}
2125
2126pub fn indent<'a, S: Clone + 'a>(
2128 number_of_spaces: usize,
2129) -> impl Parser<'a, Output = (), State = S> {
2130 repeat(number_of_spaces, space_char())
2131 .ignore()
2132 .map_err(move |_| {
2133 format!(
2134 "I'm expecting an indentation.\nAll indentations should be {} spaces.",
2135 number_of_spaces
2136 )
2137 })
2138}
2139
2140pub fn indents<'a, S: Clone + 'a>(
2142 number_of_spaces: usize,
2143 number_of_indents: usize,
2144) -> impl Parser<'a, Output = (), State = S> {
2145 repeat(number_of_indents, indent(number_of_spaces))
2146 .map_err(move |_| {
2147 format!(
2148 "I'm expecting {} indentation{}.\nAll indentations should be {} spaces.",
2149 number_of_indents,
2150 plural_suffix(number_of_indents),
2151 number_of_spaces,
2152 )
2153 })
2154 .ignore()
2155}
2156
2157fn plural_suffix(count: usize) -> &'static str {
2158 if count > 1 {
2159 "s"
2160 } else {
2161 ""
2162 }
2163}
2164
2165pub fn repeat<'a, A: Clone + 'a, P: 'a, S: Clone + 'a>(
2167 times: usize,
2168 mut parser: P,
2169) -> BoxedParser<'a, Vec<A>, S>
2170where
2171 P: Parser<'a, Output = A, State = S>,
2172{
2173 Box::new(move |mut input, mut location, mut state: S| {
2174 let mut output = Vec::new();
2175 let mut committed = false;
2176
2177 if times == 0 {
2178 return ParseResult::Ok {
2179 input,
2180 location,
2181 output,
2182 state,
2183 committed,
2184 };
2185 }
2186
2187 let mut counter = 0;
2188
2189 while let ParseResult::Ok {
2190 input: cur_input,
2191 output: cur_item,
2192 location: cur_location,
2193 state: cur_state,
2194 committed: cur_committed,
2195 } = parser.parse(input, location, state.clone())
2196 {
2197 if counter >= times {
2198 break;
2199 }
2200 input = cur_input;
2201 location = cur_location;
2202 state = cur_state;
2203 output.push(cur_item);
2204 counter += 1;
2205 committed |= cur_committed;
2206 }
2207
2208 ParseResult::Ok {
2209 input,
2210 output,
2211 location,
2212 state,
2213 committed,
2214 }
2215 })
2216}
2217
2218#[macro_export]
2223macro_rules! one_of {
2224 ($single_parser:expr) => { $single_parser };
2225 ($first_parser:expr, $($parsers:expr),+) => {
2226 either($first_parser, one_of!($($parsers),*))
2227 };
2228}
2229
2230#[doc(hidden)]
2234pub fn either<'a, P1, P2, A: Clone + 'a, S: Clone + 'a>(
2235 mut parser1: P1,
2236 mut parser2: P2,
2237) -> impl Parser<'a, Output = A, State = S>
2238where
2239 P1: Parser<'a, Output = A, State = S> + 'a,
2240 P2: Parser<'a, Output = A, State = S> + 'a,
2241{
2242 fn_parser(move |input, location, state| {
2243 let result = match parser1.parse(input, location, state) {
2244 ok @ ParseResult::Ok { .. } => ok,
2245 ParseResult::Err {
2246 message,
2247 from,
2248 to,
2249 state,
2250 committed,
2251 } => {
2252 if committed {
2253 ParseResult::Err {
2254 message,
2255 from,
2256 to,
2257 state,
2258 committed,
2259 }
2260 } else {
2261 parser2.parse(input, location, state)
2262 }
2263 }
2264 };
2265 result
2266 })
2267}
2268
2269pub fn optional_with_default<'a, A: Clone + 'a, P: 'a, S: Clone + 'a>(
2271 default: A,
2272 mut parser: P,
2273) -> impl Parser<'a, Output = A, State = S>
2274where
2275 P: Parser<'a, Output = A, State = S>,
2276{
2277 fn_parser(move |input, location, state| {
2278 let result = match parser.parse(input, location, state) {
2279 ok @ ParseResult::Ok { .. } => ok,
2280 ParseResult::Err {
2281 message,
2282 from,
2283 to,
2284 state,
2285 committed,
2286 } => {
2287 if committed {
2288 ParseResult::Err {
2289 message,
2290 from,
2291 to,
2292 state,
2293 committed,
2294 }
2295 } else {
2296 ParseResult::Ok {
2297 input,
2298 location,
2299 output: default.clone(),
2300 state,
2301 committed: false,
2302 }
2303 }
2304 }
2305 };
2306 result
2307 })
2308}
2309
2310pub fn optional<'a, A: Clone + 'a, P: 'a, S: Clone + 'a>(
2312 mut parser: P,
2313) -> impl Parser<'a, Output = Option<A>, State = S>
2314where
2315 P: Parser<'a, Output = A, State = S>,
2316{
2317 fn_parser(
2318 move |input, location, state| match parser.parse(input, location, state) {
2319 ok @ ParseResult::Ok { .. } => ok.map(Some),
2320 ParseResult::Err {
2321 message,
2322 from,
2323 to,
2324 state,
2325 committed,
2326 } => {
2327 if committed {
2328 ParseResult::Err {
2329 message,
2330 from,
2331 to,
2332 state,
2333 committed,
2334 }
2335 } else {
2336 ParseResult::Ok {
2337 input,
2338 location,
2339 output: None,
2340 state,
2341 committed: false,
2342 }
2343 }
2344 }
2345 },
2346 )
2347}
2348
2349pub fn newline_with_comment<'a, S: Clone + 'a>(
2351 comment_symbol: &'a str,
2352) -> impl Parser<'_, Output = (), State = S> {
2353 succeed!()
2354 .skip(space0())
2355 .skip(either(newline_char(), line_comment(comment_symbol)))
2356}
2357
2358pub fn line_comment<'a, S: Clone + 'a>(
2360 comment_symbol: &'a str,
2361) -> impl Parser<'_, Output = (), State = S> {
2362 succeed!()
2363 .skip(token(comment_symbol))
2364 .skip(zero_or_more(chomp_ifc(
2365 &(|c: char| c != '\n' && c != '\r'),
2366 "any character",
2367 )))
2368 .skip(newline_char())
2369}
2370
2371pub fn int<'a, S: Clone + 'a>() -> impl Parser<'a, Output = usize, State = S> {
2389 digits("an integer", false).map(|int_str| int_str.parse().unwrap())
2390}
2391
2392pub fn float<'a, S: Clone + 'a>() -> impl Parser<'a, Output = f64, State = S> {
2410 let expecting = "a floating point number";
2411 succeed!(
2412 |whole: String, fraction: Option<String>, exponent: Option<String>| (whole
2413 + &fraction.unwrap_or_default()
2414 + &exponent.unwrap_or_default())
2415 .parse()
2416 .unwrap()
2417 )
2418 .keep(digits(expecting, false))
2419 .keep(optional(
2420 right(token("."), digits(expecting, true)).map(|digits| ".".to_owned() + &digits),
2421 ))
2422 .keep(optional(
2423 succeed!(|sign: Option<&'a str>, exponent: String| "e".to_string()
2424 + sign.unwrap_or_default()
2425 + &exponent)
2426 .skip(either(token("e"), token("E")))
2427 .keep(optional(either(token("+"), token("-"))))
2428 .keep(digits(expecting, false)),
2429 ))
2430}
2431
2432fn digits<'a, S: Clone + 'a>(
2433 name: &'a str,
2434 allow_leading_zeroes: bool,
2435) -> impl Parser<'_, Output = String, State = S> {
2436 take_chomped(chomp_while1c(&(|c: char| c.is_ascii_digit()), name)).update(
2437 move |input, digits: String, location: Location, state: S| {
2438 if !allow_leading_zeroes && digits.starts_with('0') && digits.len() > 1 {
2439 ParseResult::Err {
2440 message: format!("You can't have leading zeroes in {}.", name),
2441 from: Location {
2442 col: location.col - digits.len(),
2443 ..location
2444 },
2445 to: location,
2446 state,
2447 committed: false,
2448 }
2449 } else {
2450 ParseResult::Ok {
2451 input,
2452 output: digits,
2453 location,
2454 state,
2455 committed: true,
2456 }
2457 }
2458 },
2459 )
2460}
2461
2462pub fn variable<'a, S: Clone + 'a, F1: Clone, F2: Clone, F3: Clone>(
2492 start: &'a F1,
2493 inner: &'a F2,
2494 separator: &'a F3,
2495 reserved: &'a HashSet<String>,
2496 expecting: &'a str,
2497) -> impl Parser<'a, Output = String, State = S>
2498where
2499 F1: Fn(char) -> bool,
2500 F2: Fn(char) -> bool,
2501 F3: Fn(char) -> bool,
2502{
2503 take_chomped(pair(
2504 chomp_ifc(start, expecting),
2505 chomp_while0c(move |c: char| inner(c) || separator(c), expecting),
2506 ))
2507 .update(move |input, name, location, state| {
2508 if reserved.contains(&name) {
2509 ParseResult::Err {
2510 message: format!(
2511 "I'm expecting {} but found a reserved word `{}`.",
2512 expecting, name
2513 ),
2514 from: Location {
2515 col: location.col - name.len(),
2516 ..location
2517 },
2518 to: location,
2519 state,
2520 committed: false,
2521 }
2522 } else if name
2523 .chars()
2524 .zip(name[1..].chars())
2525 .any(|(c, next_c)| separator(c) && separator(next_c))
2526 {
2527 ParseResult::Err {
2528 message: format!(
2529 "I'm expecting {} but found `{}` with duplicated separators.",
2530 expecting, name
2531 ),
2532 from: Location {
2533 col: location.col - name.len(),
2534 ..location
2535 },
2536 to: location,
2537 state,
2538 committed: false,
2539 }
2540 } else if separator(name.chars().last().unwrap()) {
2541 ParseResult::Err {
2542 message: format!(
2543 "I'm expecting {} but found `{}` ended with the separator `{}`.",
2544 expecting,
2545 name,
2546 &name.chars().last().unwrap()
2547 ),
2548 from: Location {
2549 col: location.col - name.len(),
2550 ..location
2551 },
2552 to: location,
2553 state,
2554 committed: false,
2555 }
2556 } else {
2557 ParseResult::Ok {
2558 input,
2559 location,
2560 output: name,
2561 state,
2562 committed: true,
2563 }
2564 }
2565 })
2566}
2567
2568#[derive(Copy, Clone)]
2570pub enum Trailing {
2571 Forbidden,
2572 Optional,
2573 Mandatory,
2574}
2575
2576#[derive(Clone)]
2577pub enum OneOfTwo<T1, T2> {
2578 First(T1),
2579 Second(T2),
2580}
2581
2582impl<'a, P1, P2, S: Clone + 'a> Parser<'a> for OneOfTwo<P1, P2>
2583where
2584 P1: Parser<'a, State = S>,
2585 P2: Parser<'a, Output = P1::Output, State = S>,
2586{
2587 type Output = P1::Output;
2588 type State = S;
2589
2590 fn parse(
2591 &mut self,
2592 input: &'a str,
2593 location: Location,
2594 state: Self::State,
2595 ) -> ParseResult<'a, Self::Output, Self::State> {
2596 match self {
2597 OneOfTwo::First(ref mut p) => p.parse(input, location, state),
2598 OneOfTwo::Second(ref mut p) => p.parse(input, location, state),
2599 }
2600 }
2601}
2602
2603#[derive(Clone)]
2604pub enum OneOfThree<T1, T2, T3> {
2605 First(T1),
2606 Second(T2),
2607 Third(T3),
2608}
2609
2610impl<'a, P1, P2, P3, S: Clone + 'a> Parser<'a> for OneOfThree<P1, P2, P3>
2611where
2612 P1: Parser<'a, State = S>,
2613 P2: Parser<'a, Output = P1::Output, State = S>,
2614 P3: Parser<'a, Output = P1::Output, State = S>,
2615{
2616 type Output = P1::Output;
2617 type State = S;
2618
2619 fn parse(
2620 &mut self,
2621 input: &'a str,
2622 location: Location,
2623 state: Self::State,
2624 ) -> ParseResult<'a, Self::Output, Self::State> {
2625 match self {
2626 OneOfThree::First(ref mut p) => p.parse(input, location, state),
2627 OneOfThree::Second(ref mut p) => p.parse(input, location, state),
2628 OneOfThree::Third(ref mut p) => p.parse(input, location, state),
2629 }
2630 }
2631}
2632
2633pub fn sequence<
2665 'a,
2666 A: Clone + 'a,
2667 StartOutput: Clone + 'a,
2668 StartParser: 'a,
2669 ItemParser: 'a,
2670 SepOutput: Clone + 'a,
2671 SepParser: 'a,
2672 SpacesParser: 'a,
2673 EndOutput: Clone + 'a,
2674 EndParser: 'a,
2675 S: Clone + 'a,
2676>(
2677 start: StartParser,
2678 item: impl Fn() -> ItemParser,
2679 separator: impl Fn() -> SepParser,
2680 spaces: impl Fn() -> SpacesParser,
2681 end: EndParser,
2682 trailing: Trailing,
2683) -> impl Parser<'a, Output = Vec<A>, State = S>
2684where
2685 StartParser: Parser<'a, Output = StartOutput, State = S>,
2686 ItemParser: Parser<'a, Output = A, State = S>,
2687 SepParser: Parser<'a, Output = SepOutput, State = S>,
2688 SpacesParser: Parser<'a, Output = (), State = S>,
2689 EndParser: Parser<'a, Output = EndOutput, State = S>,
2690{
2691 wrap(
2692 pair(start, spaces()),
2693 optional(
2694 pair(
2695 item(),
2696 right(
2697 spaces(),
2698 left(
2699 zero_or_more(wrap(
2700 left(separator(), spaces()).backtrackable(),
2701 item(),
2702 spaces(),
2703 )),
2704 match trailing {
2705 Trailing::Forbidden => succeed!().first_of_three(),
2706 Trailing::Optional => {
2707 optional_with_default((), left(separator().ignore(), spaces()))
2708 .second_of_three()
2709 }
2710 Trailing::Mandatory => {
2711 left(separator(), spaces()).ignore().third_of_three()
2712 }
2713 },
2714 ),
2715 ),
2716 )
2717 .map(move |(first_item, mut rest_items)| {
2718 rest_items.insert(0, first_item);
2719 rest_items
2720 }),
2721 )
2722 .map(|items| items.unwrap_or(vec![])),
2723 end,
2724 )
2725}
2726
2727fn wrap<'a, A: Clone + 'a, B: Clone + 'a, C: Clone + 'a, P1: 'a, P2: 'a, P3: 'a, S: Clone + 'a>(
2729 left_delimiter: P1,
2730 wrapped: P2,
2731 right_delimiter: P3,
2732) -> impl Parser<'a, Output = B, State = S>
2733where
2734 P1: Parser<'a, Output = A, State = S>,
2735 P2: Parser<'a, Output = B, State = S>,
2736 P3: Parser<'a, Output = C, State = S>,
2737{
2738 right(left_delimiter, left(wrapped, right_delimiter))
2739}
2740
2741pub fn located<'a, P: 'a, A, S: Clone + 'a>(
2746 mut parser: P,
2747) -> impl Parser<'a, Output = Located<A>, State = S>
2748where
2749 P: Parser<'a, Output = A, State = S>,
2750{
2751 fn_parser(
2752 move |input, location, state| match parser.parse(input, location, state) {
2753 ParseResult::Ok {
2754 input: cur_input,
2755 output,
2756 location: cur_location,
2757 state: cur_state,
2758 committed: cur_committed,
2759 } => ParseResult::Ok {
2760 input: cur_input,
2761 output: Located {
2762 value: output,
2763 from: Location {
2764 row: location.row,
2765 col: location.col,
2766 },
2767 to: Location {
2768 row: cur_location.row,
2769 col: cur_location.col,
2770 },
2771 },
2772 location: cur_location,
2773 state: cur_state,
2774 committed: cur_committed,
2775 },
2776 ParseResult::Err {
2777 message,
2778 from,
2779 to,
2780 state,
2781 committed,
2782 } => ParseResult::Err {
2783 message,
2784 from,
2785 to,
2786 state,
2787 committed,
2788 },
2789 },
2790 )
2791}
2792
2793pub fn display_error(source: &str, error_message: String, from: Location, to: Location) -> String {
2801 let row = from.row;
2802 let col = from.col;
2803 let line = source.lines().nth(row - 1).unwrap();
2804 let error_length = if from.row < to.row {
2805 std::cmp::max(line.len() + 1 - from.col, 1)
2806 } else if to.col == from.col {
2807 1
2808 } else {
2809 to.col - from.col
2810 };
2811 let row_tag = row.to_string();
2812 let row_tag_len = if row < source.lines().count() {
2813 (row + 1).to_string().len()
2814 } else {
2815 row_tag.len()
2816 };
2817 let prev_line = if row > 1 {
2818 format!("{: >width$}", (row - 1).to_string(), width = row_tag_len)
2819 + "| "
2820 + source.lines().nth(row - 2).unwrap()
2821 + "\n"
2822 } else {
2823 String::new()
2824 };
2825 let next_line = if row < source.lines().count() {
2826 (row + 1).to_string() + "| " + source.lines().nth(row).unwrap() + "\n"
2827 } else {
2828 String::new()
2829 };
2830 let error_line = row_tag + "| " + line;
2831 let error_pointer = " ".repeat(col - 1 + row_tag_len + 2) + &"^".repeat(error_length);
2832 prev_line + &error_line + "\n" + &error_pointer + "\n" + &next_line + "⚠️ " + &error_message
2833}
2834
2835fn update_state<'a, P: 'a, F>(parser: P, f: F) -> UpdateState<P, F>
2836where
2837 P: Parser<'a>,
2838 F: Fn(P::Output, P::State) -> P::State,
2839{
2840 UpdateState(parser, f)
2841}
2842
2843fn update<'a, P: 'a, A, B, F: Clone>(parser: P, f: F) -> Update<P, F>
2844where
2845 P: Parser<'a, Output = A>,
2846 F: FnOnce(&'a str, A, Location, P::State) -> ParseResult<'a, B, P::State>,
2847{
2848 Update(parser, f)
2849}
2850
2851#[doc(hidden)]
2852pub fn assert_succeed<'a, P: 'a, A: PartialEq + Debug>(mut parser: P, source: &'a str, expected: A)
2853where
2854 P: Parser<'a, Output = A, State = ()>,
2855{
2856 assert_eq!(
2857 parser
2858 .parse(source, Location { row: 1, col: 1 }, ())
2859 .unwrap(source),
2860 expected
2861 )
2862}
2863
2864#[doc(hidden)]
2865pub fn assert_fail<'a, P: 'a, A: Debug>(mut parser: P, source: &'a str, message: &'a str)
2866where
2867 P: Parser<'a, Output = A, State = ()>,
2868{
2869 assert_eq!(
2870 parser
2871 .parse(source, Location { row: 1, col: 1 }, ())
2872 .unwrap_err(),
2873 message
2874 )
2875}
2876
2877fn unicode_column_width(s: &str) -> usize {
2881 s.graphemes(true).map(grapheme_column_width).sum()
2882}
2883
2884fn grapheme_column_width(s: &str) -> usize {
2888 use xi_unicode::EmojiExt;
2894 for c in s.chars() {
2895 if c.is_emoji_modifier_base() || c.is_emoji_modifier() {
2896 return 2;
2898 }
2899 }
2900 UnicodeWidthStr::width(s)
2901}
2902
2903fn char_column_width(c: char) -> usize {
2904 UnicodeWidthChar::width(c).unwrap_or(0)
2905}