oni_comb_parser_rs/core/
parsers.rs

1use crate::core::ParserFunctor;
2use crate::core::ParserMonad;
3use crate::core::{CommittedStatus, ParseError, Parser};
4use crate::prelude::Element;
5
6/// パーサー関数を提供するトレイト
7pub trait Parsers {
8  type P<'p, I, A>: ParserMonad<'p, Input = I, Output = A>
9  where
10    I: 'p,
11    A: 'p;
12
13  fn parse<'a, 'b, I, A>(parser: &Self::P<'a, I, A>, input: &'b [I]) -> Result<A, ParseError<'a, I>>
14  where
15    A: 'a,
16    'b: 'a;
17
18  fn unit<'a, I>() -> Self::P<'a, I, ()> {
19    Self::successful(())
20  }
21
22  fn successful<'a, I, A>(value: A) -> Self::P<'a, I, A>
23  where
24    A: Clone + 'a;
25
26  fn successful_lazy<'a, I, A, F>(value: F) -> Self::P<'a, I, A>
27  where
28    F: Fn() -> A + 'a,
29    A: 'a;
30
31  fn failed<'a, I, A>(value: ParseError<'a, I>, committed: CommittedStatus) -> Self::P<'a, I, A>
32  where
33    I: Clone + 'a,
34    A: 'a;
35
36  fn failed_lazy<'a, I, A, F>(f: F) -> Self::P<'a, I, A>
37  where
38    F: Fn() -> (ParseError<'a, I>, CommittedStatus) + 'a,
39    I: 'a,
40    A: 'a;
41
42  fn filter<'a, I, A, F>(parser: Self::P<'a, I, A>, f: F) -> Self::P<'a, I, A>
43  where
44    F: Fn(&A) -> bool + 'a,
45    I: Element,
46    A: Clone + 'a;
47
48  fn flat_map<'a, I, A, B, F>(parser: Self::P<'a, I, A>, f: F) -> Self::P<'a, I, B>
49  where
50    F: Fn(A) -> Self::P<'a, I, B> + 'a,
51    A: 'a,
52    B: 'a;
53
54  fn map<'a, I, A, B, F>(parser: Self::P<'a, I, A>, f: F) -> Self::P<'a, I, B>
55  where
56    F: Fn(A) -> B + 'a,
57    A: 'a,
58    B: 'a;
59}
60
61/// 既存のParserを使用するParsers実装
62pub struct ParserParsers;
63
64impl Parsers for ParserParsers {
65  type P<'p, I, A>
66    = Parser<'p, I, A>
67  where
68    I: 'p,
69    A: 'p;
70
71  fn parse<'a, 'b, I, A>(parser: &Self::P<'a, I, A>, input: &'b [I]) -> Result<A, ParseError<'a, I>>
72  where
73    A: 'a,
74    'b: 'a, {
75    use crate::core::parser_runner::ParserRunner;
76    parser
77      .parse(input)
78      .success()
79      .ok_or_else(|| ParseError::of_custom(0, None, "Parse failed".to_string()))
80  }
81
82  fn successful<'a, I, A>(value: A) -> Self::P<'a, I, A>
83  where
84    A: Clone + 'a, {
85    Parser::new(move |_| crate::core::ParseResult::successful(value.clone(), 0))
86  }
87
88  fn successful_lazy<'a, I, A, F>(value: F) -> Self::P<'a, I, A>
89  where
90    F: Fn() -> A + 'a,
91    A: 'a, {
92    Parser::new(move |_| crate::core::ParseResult::successful(value(), 0))
93  }
94
95  fn failed<'a, I, A>(value: ParseError<'a, I>, committed: CommittedStatus) -> Self::P<'a, I, A>
96  where
97    I: Clone + 'a,
98    A: 'a, {
99    Parser::new(move |_| crate::core::ParseResult::failed(value.clone(), committed))
100  }
101
102  fn failed_lazy<'a, I, A, F>(f: F) -> Self::P<'a, I, A>
103  where
104    F: Fn() -> (ParseError<'a, I>, CommittedStatus) + 'a,
105    I: 'a,
106    A: 'a, {
107    Parser::new(move |_| {
108      let (error, committed) = f();
109      crate::core::ParseResult::failed(error, committed)
110    })
111  }
112
113  fn filter<'a, I, A, F>(parser: Self::P<'a, I, A>, f: F) -> Self::P<'a, I, A>
114  where
115    F: Fn(&A) -> bool + 'a,
116    I: Element,
117    A: Clone + 'a, {
118    // 直接実装を使用
119    Self::flat_map(parser, move |a| {
120      if f(&a) {
121        Self::successful(a)
122      } else {
123        Self::failed(
124          ParseError::of_custom(0, None, "Filter predicate failed".to_string()),
125          CommittedStatus::Uncommitted,
126        )
127      }
128    })
129  }
130
131  fn flat_map<'a, I, A, B, F>(parser: Self::P<'a, I, A>, f: F) -> Self::P<'a, I, B>
132  where
133    F: Fn(A) -> Self::P<'a, I, B> + 'a,
134    A: 'a,
135    B: 'a, {
136    parser.flat_map(f)
137  }
138
139  fn map<'a, I, A, B, F>(parser: Self::P<'a, I, A>, f: F) -> Self::P<'a, I, B>
140  where
141    F: Fn(A) -> B + 'a,
142    A: 'a,
143    B: 'a, {
144    parser.map(f)
145  }
146}