Skip to main content

oni_comb_parser/
parser_ext.rs

1use crate::combinator::attempt::Attempt;
2use crate::combinator::chainl1::ChainL1;
3#[cfg(feature = "alloc")]
4use crate::combinator::chainr1::ChainR1;
5use crate::combinator::context::Context;
6use crate::combinator::cut::Cut;
7use crate::combinator::flat_map::FlatMap;
8#[cfg(feature = "alloc")]
9use crate::combinator::many::Many;
10#[cfg(feature = "alloc")]
11use crate::combinator::many1::Many1;
12use crate::combinator::many1_fold::Many1Fold;
13use crate::combinator::many_fold::ManyFold;
14use crate::combinator::map::Map;
15use crate::combinator::map_res::MapRes;
16use crate::combinator::optional::Optional;
17use crate::combinator::or::Or;
18#[cfg(feature = "alloc")]
19use crate::combinator::sep_by::{SepBy0, SepBy1};
20use crate::combinator::sep_by_fold::{SepByFold0, SepByFold1};
21use crate::combinator::zip::Zip;
22use crate::combinator::zip_left::ZipLeft;
23use crate::combinator::zip_right::ZipRight;
24use crate::input::Input;
25use crate::parser::Parser;
26
27pub trait ParserExt<I: Input>: Parser<I> + Sized {
28  fn map<F, O2>(self, f: F) -> Map<Self, F>
29  where
30    F: FnMut(Self::Output) -> O2, {
31    Map { parser: self, f }
32  }
33
34  fn zip<P2>(self, rhs: P2) -> Zip<Self, P2>
35  where
36    P2: Parser<I, Error = Self::Error>, {
37    Zip {
38      first: self,
39      second: rhs,
40    }
41  }
42
43  /// 両方実行し、左(self)の値だけを返す(= terminated)。
44  fn zip_left<P2>(self, rhs: P2) -> ZipLeft<Self, P2>
45  where
46    P2: Parser<I, Error = Self::Error>, {
47    ZipLeft {
48      first: self,
49      second: rhs,
50    }
51  }
52
53  /// 両方実行し、右(rhs)の値だけを返す(= preceded)。
54  fn zip_right<P2>(self, rhs: P2) -> ZipRight<Self, P2>
55  where
56    P2: Parser<I, Error = Self::Error>, {
57    ZipRight {
58      first: self,
59      second: rhs,
60    }
61  }
62
63  fn or<P2>(self, rhs: P2) -> Or<Self, P2>
64  where
65    Self::Error: crate::error::MergeError,
66    P2: Parser<I, Output = Self::Output, Error = Self::Error>, {
67    Or { left: self, right: rhs }
68  }
69
70  fn attempt(self) -> Attempt<Self> {
71    Attempt { parser: self }
72  }
73
74  fn cut(self) -> Cut<Self> {
75    Cut { parser: self }
76  }
77
78  fn optional(self) -> Optional<Self> {
79    Optional { parser: self }
80  }
81
82  #[cfg(feature = "alloc")]
83  fn many0(self) -> Many<Self> {
84    Many { parser: self }
85  }
86
87  #[cfg(feature = "alloc")]
88  fn many1(self) -> Many1<Self> {
89    Many1 { parser: self }
90  }
91
92  /// ゼロ個以上の要素を畳み込む(ゼロアロケーション)。
93  fn many0_fold<B, F, Acc>(self, init: B, f: F) -> ManyFold<Self, B, F>
94  where
95    B: FnMut() -> Acc,
96    F: FnMut(Acc, Self::Output) -> Acc, {
97    ManyFold { parser: self, init, f }
98  }
99
100  /// 1個以上の要素を畳み込む(ゼロアロケーション)。
101  fn many1_fold<B, F, Acc>(self, init: B, f: F) -> Many1Fold<Self, B, F>
102  where
103    B: FnMut() -> Acc,
104    F: FnMut(Acc, Self::Output) -> Acc, {
105    Many1Fold { parser: self, init, f }
106  }
107
108  /// ゼロ個以上の要素をユーザー指定のコンテナに収集する。
109  fn many0_into<C>(self, container: C) -> ManyFold<Self, impl FnMut() -> C, impl FnMut(C, Self::Output) -> C>
110  where
111    C: Extend<Self::Output> + Clone, {
112    self.many0_fold(
113      move || container.clone(),
114      |mut acc, item| {
115        acc.extend(core::iter::once(item));
116        acc
117      },
118    )
119  }
120
121  /// 1個以上の要素をユーザー指定のコンテナに収集する。
122  fn many1_into<C>(self, container: C) -> Many1Fold<Self, impl FnMut() -> C, impl FnMut(C, Self::Output) -> C>
123  where
124    C: Extend<Self::Output> + Clone, {
125    self.many1_fold(
126      move || container.clone(),
127      |mut acc, item| {
128        acc.extend(core::iter::once(item));
129        acc
130      },
131    )
132  }
133
134  /// エラーにコンテキストラベルを付与する。
135  fn context(self, label: &'static str) -> Context<Self>
136  where
137    Self::Error: crate::error::ContextError, {
138    Context { parser: self, label }
139  }
140
141  /// 区切り付き 0 個以上の繰り返し。
142  #[cfg(feature = "alloc")]
143  fn sep_by0<S>(self, sep: S) -> SepBy0<Self, S>
144  where
145    S: Parser<I, Error = Self::Error>, {
146    SepBy0 { parser: self, sep }
147  }
148
149  /// 区切り付き 1 個以上の繰り返し。
150  #[cfg(feature = "alloc")]
151  fn sep_by1<S>(self, sep: S) -> SepBy1<Self, S>
152  where
153    S: Parser<I, Error = Self::Error>, {
154    SepBy1 { parser: self, sep }
155  }
156
157  /// 区切り付き 0 個以上の要素を畳み込む(ゼロアロケーション)。
158  fn sep_by0_fold<S, B, F, Acc>(self, sep: S, init: B, f: F) -> SepByFold0<Self, S, B, F>
159  where
160    S: Parser<I, Error = Self::Error>,
161    B: FnMut() -> Acc,
162    F: FnMut(Acc, Self::Output) -> Acc, {
163    SepByFold0 {
164      parser: self,
165      sep,
166      init,
167      f,
168    }
169  }
170
171  /// 区切り付き 1 個以上の要素を畳み込む(ゼロアロケーション)。
172  fn sep_by1_fold<S, B, F, Acc>(self, sep: S, init: B, f: F) -> SepByFold1<Self, S, B, F>
173  where
174    S: Parser<I, Error = Self::Error>,
175    B: FnMut() -> Acc,
176    F: FnMut(Acc, Self::Output) -> Acc, {
177    SepByFold1 {
178      parser: self,
179      sep,
180      init,
181      f,
182    }
183  }
184
185  /// 区切り付き 0 個以上の要素をユーザー指定のコンテナに収集する。
186  fn sep_by0_into<S, C>(
187    self,
188    sep: S,
189    container: C,
190  ) -> SepByFold0<Self, S, impl FnMut() -> C, impl FnMut(C, Self::Output) -> C>
191  where
192    S: Parser<I, Error = Self::Error>,
193    C: Extend<Self::Output> + Clone, {
194    self.sep_by0_fold(
195      sep,
196      move || container.clone(),
197      |mut acc, item| {
198        acc.extend(core::iter::once(item));
199        acc
200      },
201    )
202  }
203
204  /// 区切り付き 1 個以上の要素をユーザー指定のコンテナに収集する。
205  fn sep_by1_into<S, C>(
206    self,
207    sep: S,
208    container: C,
209  ) -> SepByFold1<Self, S, impl FnMut() -> C, impl FnMut(C, Self::Output) -> C>
210  where
211    S: Parser<I, Error = Self::Error>,
212    C: Extend<Self::Output> + Clone, {
213    self.sep_by1_fold(
214      sep,
215      move || container.clone(),
216      |mut acc, item| {
217        acc.extend(core::iter::once(item));
218        acc
219      },
220    )
221  }
222
223  /// 左結合の二項演算子チェーン。operand (op operand)* を左から畳む。
224  fn chainl1<Op, F>(self, op: Op) -> ChainL1<Self, Op>
225  where
226    Op: Parser<I, Output = F, Error = Self::Error>,
227    F: FnMut(Self::Output, Self::Output) -> Self::Output, {
228    ChainL1 {
229      operand: self,
230      operator: op,
231    }
232  }
233
234  /// 右結合の二項演算子チェーン。operand (op operand)* を右から畳む。
235  #[cfg(feature = "alloc")]
236  fn chainr1<Op, F>(self, op: Op) -> ChainR1<Self, Op>
237  where
238    Op: Parser<I, Output = F, Error = Self::Error>,
239    F: FnMut(Self::Output, Self::Output) -> Self::Output, {
240    ChainR1 {
241      operand: self,
242      operator: op,
243    }
244  }
245
246  /// パーサーの結果を失敗しうる関数で変換する。
247  fn map_res<F, O2, E2>(self, f: F, label: &'static str) -> MapRes<Self, F>
248  where
249    Self::Error: crate::error::ExpectError,
250    F: FnMut(Self::Output) -> Result<O2, E2>, {
251    MapRes { parser: self, f, label }
252  }
253
254  fn flat_map<F, P2>(self, f: F) -> FlatMap<Self, F>
255  where
256    P2: Parser<I, Error = Self::Error>,
257    F: FnMut(Self::Output) -> P2, {
258    FlatMap { parser: self, f }
259  }
260
261  fn and_then<F, P2>(self, f: F) -> FlatMap<Self, F>
262  where
263    P2: Parser<I, Error = Self::Error>,
264    F: FnMut(Self::Output) -> P2, {
265    FlatMap { parser: self, f }
266  }
267}
268
269impl<I: Input, P: Parser<I> + Sized> ParserExt<I> for P {}