Skip to main content

oni_comb_parser/
parser_ext.rs

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