Skip to content

Commit 12e3f29

Browse files
committed
feat: Decouple Parser from ParseError
The `ParseError` type is specific to the QBasic errors. Decouple the `Parser` trait from it, as that is part of the generic parser combinator framework.
1 parent d17e478 commit 12e3f29

81 files changed

Lines changed: 740 additions & 531 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

rusty_parser/src/pc/and.rs

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::error::ParseError;
21
use crate::pc::{ParseResult, Parser, ToOption};
32

43
//
@@ -12,40 +11,50 @@ where
1211
{
1312
/// Parses both the left and the right side.
1413
/// If the right side fails with a non fatal error, parsing of the left side is undone.
15-
fn and<R, F, O>(self, right: R, combiner: F) -> impl Parser<I, Output = O>
14+
fn and<R, F, O>(self, right: R, combiner: F) -> impl Parser<I, Output = O, Error = Self::Error>
1615
where
17-
R: Parser<I>,
16+
R: Parser<I, Error = Self::Error>,
1817
F: Fn(Self::Output, R::Output) -> O,
1918
{
2019
AndParser::new(self, right, combiner)
2120
}
2221

23-
fn and_tuple<R>(self, right: R) -> impl Parser<I, Output = (Self::Output, R::Output)>
22+
fn and_tuple<R>(
23+
self,
24+
right: R,
25+
) -> impl Parser<I, Output = (Self::Output, R::Output), Error = Self::Error>
2426
where
25-
R: Parser<I>,
27+
R: Parser<I, Error = Self::Error>,
2628
{
2729
self.and(right, |l, r| (l, r))
2830
}
2931

30-
fn and_keep_left<R>(self, right: R) -> impl Parser<I, Output = Self::Output>
32+
fn and_keep_left<R>(
33+
self,
34+
right: R,
35+
) -> impl Parser<I, Output = Self::Output, Error = Self::Error>
3136
where
32-
R: Parser<I>,
37+
R: Parser<I, Error = Self::Error>,
3338
{
3439
self.and(right, |l, _| l)
3540
}
3641

37-
fn and_keep_right<R>(self, right: R) -> impl Parser<I, Output = R::Output>
42+
fn and_keep_right<R>(self, right: R) -> impl Parser<I, Output = R::Output, Error = Self::Error>
3843
where
39-
R: Parser<I>,
44+
R: Parser<I, Error = Self::Error>,
4045
{
4146
self.and(right, |_, r| r)
4247
}
4348

4449
/// Parses the left side and optionally the right side.
4550
/// The combiner function maps the left and (optional) right output to the final result.
46-
fn and_opt<R, F, O>(self, right: R, combiner: F) -> impl Parser<I, Output = O>
51+
fn and_opt<R, F, O>(
52+
self,
53+
right: R,
54+
combiner: F,
55+
) -> impl Parser<I, Output = O, Error = Self::Error>
4756
where
48-
R: Parser<I>,
57+
R: Parser<I, Error = Self::Error>,
4958
F: Fn(Self::Output, Option<R::Output>) -> O,
5059
{
5160
self.and(right.to_option(), combiner)
@@ -56,35 +65,45 @@ where
5665
fn and_opt_tuple<R>(
5766
self,
5867
right: R,
59-
) -> impl Parser<I, Output = (Self::Output, Option<R::Output>)>
68+
) -> impl Parser<I, Output = (Self::Output, Option<R::Output>), Error = Self::Error>
6069
where
61-
R: Parser<I>,
70+
R: Parser<I, Error = Self::Error>,
6271
{
6372
self.and_opt(right, |l, r| (l, r))
6473
}
6574

6675
/// Parses the left side and optionally the right side.
6776
/// The result is only the left side's output.
68-
fn and_opt_keep_left<R>(self, right: R) -> impl Parser<I, Output = Self::Output>
77+
fn and_opt_keep_left<R>(
78+
self,
79+
right: R,
80+
) -> impl Parser<I, Output = Self::Output, Error = Self::Error>
6981
where
70-
R: Parser<I>,
82+
R: Parser<I, Error = Self::Error>,
7183
{
7284
self.and_opt(right, |l, _| l)
7385
}
7486

7587
/// Parses the left side and optionally the right side.
7688
/// The result is only the right side's output.
77-
fn and_opt_keep_right<R>(self, right: R) -> impl Parser<I, Output = Option<R::Output>>
89+
fn and_opt_keep_right<R>(
90+
self,
91+
right: R,
92+
) -> impl Parser<I, Output = Option<R::Output>, Error = Self::Error>
7893
where
79-
R: Parser<I>,
94+
R: Parser<I, Error = Self::Error>,
8095
{
8196
self.and_opt(right, |_, r| r)
8297
}
8398

84-
fn surround<L, R>(self, left: L, right: R) -> impl Parser<I, Output = Self::Output>
99+
fn surround<L, R>(
100+
self,
101+
left: L,
102+
right: R,
103+
) -> impl Parser<I, Output = Self::Output, Error = Self::Error>
85104
where
86-
L: Parser<I>,
87-
R: Parser<I>,
105+
L: Parser<I, Error = Self::Error>,
106+
R: Parser<I, Error = Self::Error>,
88107
{
89108
left.and_keep_right(self).and_keep_left(right)
90109
}
@@ -120,11 +139,13 @@ impl<I, L, R, F, O> Parser<I> for AndParser<L, R, F>
120139
where
121140
I: Clone,
122141
L: Parser<I>,
123-
R: Parser<I>,
142+
R: Parser<I, Error = L::Error>,
124143
F: Fn(L::Output, R::Output) -> O,
125144
{
126145
type Output = O;
127-
fn parse(&self, tokenizer: I) -> ParseResult<I, Self::Output, ParseError> {
146+
type Error = L::Error;
147+
148+
fn parse(&self, tokenizer: I) -> ParseResult<I, Self::Output, Self::Error> {
128149
match self.left.parse(tokenizer.clone()) {
129150
Ok((input, left)) => {
130151
match self.right.parse(input) {
@@ -142,11 +163,11 @@ where
142163
/// Parses the left side optionally and then the right side.
143164
/// If the right side fails, the left side is reverted too.
144165
/// The combiner function is used to create the final result.
145-
pub fn opt_and<I, L, R, F, O>(
146-
left: impl Parser<I, Output = L>,
147-
right: impl Parser<I, Output = R>,
166+
pub fn opt_and<I, L, R, E, F, O>(
167+
left: impl Parser<I, Output = L, Error = E>,
168+
right: impl Parser<I, Output = R, Error = E>,
148169
combiner: F,
149-
) -> impl Parser<I, Output = O>
170+
) -> impl Parser<I, Output = O, Error = E>
150171
where
151172
I: Clone,
152173
F: Fn(Option<L>, R) -> O,
@@ -157,10 +178,10 @@ where
157178
/// Parses the left side optionally and then the right side.
158179
/// If the right side fails, the left side is reverted too.
159180
/// The result is a tuple of the (optional) left side and the right side.
160-
pub fn opt_and_tuple<I, L, R>(
161-
left: impl Parser<I, Output = L>,
162-
right: impl Parser<I, Output = R>,
163-
) -> impl Parser<I, Output = (Option<L>, R)>
181+
pub fn opt_and_tuple<I, L, R, E>(
182+
left: impl Parser<I, Output = L, Error = E>,
183+
right: impl Parser<I, Output = R, Error = E>,
184+
) -> impl Parser<I, Output = (Option<L>, R), Error = E>
164185
where
165186
I: Clone,
166187
{
@@ -170,10 +191,10 @@ where
170191
/// Parses the left side optionally and then the right side.
171192
/// If the right side fails, the left side is reverted too.
172193
/// The result is the right side only, the left is discarded.
173-
pub fn opt_and_keep_right<I, L, R>(
174-
left: impl Parser<I, Output = L>,
175-
right: impl Parser<I, Output = R>,
176-
) -> impl Parser<I, Output = R>
194+
pub fn opt_and_keep_right<I, L, R, E>(
195+
left: impl Parser<I, Output = L, Error = E>,
196+
right: impl Parser<I, Output = R, Error = E>,
197+
) -> impl Parser<I, Output = R, Error = E>
177198
where
178199
I: Clone,
179200
{

rusty_parser/src/pc/boxed.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
use crate::error::ParseError;
21
use crate::pc::Parser;
32

4-
pub fn boxed<I, O>(parser: impl Parser<I, Output = O> + 'static) -> BoxedParser<I, O> {
3+
pub fn boxed<I, O, E>(
4+
parser: impl Parser<I, Output = O, Error = E> + 'static,
5+
) -> BoxedParser<I, O, E> {
56
BoxedParser {
67
parser: Box::new(parser),
78
}
89
}
910

10-
pub struct BoxedParser<I, O> {
11-
parser: Box<dyn Parser<I, Output = O>>,
11+
pub struct BoxedParser<I, O, E> {
12+
parser: Box<dyn Parser<I, Output = O, Error = E>>,
1213
}
1314

14-
impl<I, O> Parser<I> for BoxedParser<I, O> {
15+
impl<I, O, E> Parser<I> for BoxedParser<I, O, E> {
1516
type Output = O;
17+
type Error = E;
1618

17-
fn parse(&self, input: I) -> super::ParseResult<I, Self::Output, ParseError> {
19+
fn parse(&self, input: I) -> super::ParseResult<I, Self::Output, Self::Error> {
1820
self.parser.parse(input)
1921
}
2022
}

rusty_parser/src/pc/delimited.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::error::ParseError;
21
use crate::pc::*;
32

43
/// Represents a value that has is followed by optional delimiter.
@@ -34,11 +33,15 @@ impl<L, R> Delimited<L> for (L, Option<R>) {
3433
}
3534

3635
/// Gets a list of items separated by a delimiter.
37-
pub fn delimited_by<I: Clone, P: Parser<I>, D: Parser<I>>(
36+
pub fn delimited_by<I, P: Parser<I>, D: Parser<I, Error = P::Error>>(
3837
parser: P,
3938
delimiter: D,
40-
trailing_error: ParseError,
41-
) -> impl Parser<I, Output = Vec<P::Output>> {
39+
trailing_error: P::Error,
40+
) -> impl Parser<I, Output = Vec<P::Output>, Error = P::Error>
41+
where
42+
I: Clone,
43+
P::Error: Clone + Default,
44+
{
4245
parse_delimited_to_items(parser.and_opt_tuple(delimiter), trailing_error)
4346
}
4447

@@ -47,22 +50,19 @@ pub fn delimited_by<I: Clone, P: Parser<I>, D: Parser<I>>(
4750
/// Public because needed by built_ins to implement csv_allow_missing.
4851
pub fn parse_delimited_to_items<I: Clone, P, L>(
4952
parser: P,
50-
trailing_error: ParseError,
51-
) -> impl Parser<I, Output = Vec<L>>
53+
trailing_error: P::Error,
54+
) -> impl Parser<I, Output = Vec<L>, Error = P::Error>
5255
where
5356
P: Parser<I>,
5457
P::Output: Delimited<L>,
58+
P::Error: Clone + Default,
5559
{
5660
parser
5761
.loop_while(Delimited::has_delimiter)
5862
.flat_map(move |input, items| map_items(input, items, trailing_error.clone()))
5963
}
6064

61-
fn map_items<I, P, T>(
62-
input: I,
63-
items: Vec<P>,
64-
trailing_error: ParseError,
65-
) -> ParseResult<I, Vec<T>, ParseError>
65+
fn map_items<I, P, T, E>(input: I, items: Vec<P>, trailing_error: E) -> ParseResult<I, Vec<T>, E>
6666
where
6767
P: Delimited<T>,
6868
{

rusty_parser/src/pc/filter.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
use crate::error::ParseError;
21
use crate::pc::{default_parse_error, ParseResult, Parser};
32

43
pub trait Filter<I>: Parser<I>
54
where
65
Self: Sized,
76
I: Clone,
87
{
9-
fn filter<F>(self, predicate: F) -> impl Parser<I, Output = Self::Output>
8+
fn filter<F>(self, predicate: F) -> impl Parser<I, Output = Self::Output, Error = Self::Error>
109
where
1110
F: Fn(&Self::Output) -> bool,
11+
Self::Error: Default,
1212
{
1313
FilterParser(self, predicate)
1414
}
@@ -27,11 +27,13 @@ impl<I, P, F> Parser<I> for FilterParser<P, F>
2727
where
2828
I: Clone,
2929
P: Parser<I>,
30+
P::Error: Default,
3031
F: Fn(&P::Output) -> bool,
3132
{
3233
type Output = P::Output;
34+
type Error = P::Error;
3335

34-
fn parse(&self, tokenizer: I) -> ParseResult<I, Self::Output, ParseError> {
36+
fn parse(&self, tokenizer: I) -> ParseResult<I, Self::Output, Self::Error> {
3537
match self.0.parse(tokenizer.clone()) {
3638
Ok((input, value)) => {
3739
if (self.1)(&value) {

rusty_parser/src/pc/filter_map.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
use crate::error::ParseError;
21
use crate::pc::{default_parse_error, ParseResult, ParseResultTrait, Parser};
32

43
pub trait FilterMap<I>: Parser<I>
54
where
65
Self: Sized,
6+
Self::Error: Default,
77
I: Clone,
88
{
9-
fn filter_map<F, U>(self, predicate_mapper: F) -> impl Parser<I, Output = U>
9+
fn filter_map<F, U>(
10+
self,
11+
predicate_mapper: F,
12+
) -> impl Parser<I, Output = U, Error = Self::Error>
1013
where
1114
F: Fn(&Self::Output) -> Option<U>,
1215
{
@@ -18,6 +21,7 @@ impl<I, P> FilterMap<I> for P
1821
where
1922
I: Clone,
2023
P: Parser<I>,
24+
P::Error: Default,
2125
{
2226
}
2327

@@ -26,12 +30,13 @@ struct FilterMapParser<P, F>(P, F);
2630
impl<I: Clone, P, F, U> Parser<I> for FilterMapParser<P, F>
2731
where
2832
P: Parser<I>,
29-
33+
P::Error: Default,
3034
F: Fn(&P::Output) -> Option<U>,
3135
{
3236
type Output = U;
37+
type Error = P::Error;
3338

34-
fn parse(&self, tokenizer: I) -> ParseResult<I, Self::Output, ParseError> {
39+
fn parse(&self, tokenizer: I) -> ParseResult<I, Self::Output, Self::Error> {
3540
self.0
3641
.parse(tokenizer.clone())
3742
.flat_map(|input, result| match (self.1)(&result) {

rusty_parser/src/pc/flat_map.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
use crate::error::ParseError;
21
use crate::pc::{ParseResult, ParseResultTrait, Parser};
32

43
pub trait FlatMap<I>: Parser<I>
54
where
65
Self: Sized,
76
{
87
/// Flat map the result of this parser for successful results.
9-
fn flat_map<F, U>(self, mapper: F) -> impl Parser<I, Output = U>
8+
fn flat_map<F, U>(self, mapper: F) -> impl Parser<I, Output = U, Error = Self::Error>
109
where
11-
F: Fn(I, Self::Output) -> ParseResult<I, U, ParseError>,
10+
F: Fn(I, Self::Output) -> ParseResult<I, U, Self::Error>,
1211
{
1312
FlatMapParser(self, mapper)
1413
}
@@ -21,10 +20,12 @@ struct FlatMapParser<P, F>(P, F);
2120
impl<I, P, F, U> Parser<I> for FlatMapParser<P, F>
2221
where
2322
P: Parser<I>,
24-
F: Fn(I, P::Output) -> ParseResult<I, U, ParseError>,
23+
F: Fn(I, P::Output) -> ParseResult<I, U, P::Error>,
2524
{
2625
type Output = U;
27-
fn parse(&self, tokenizer: I) -> ParseResult<I, Self::Output, ParseError> {
26+
type Error = P::Error;
27+
28+
fn parse(&self, tokenizer: I) -> ParseResult<I, Self::Output, Self::Error> {
2829
self.0.parse(tokenizer).flat_map(&self.1)
2930
}
3031
}

0 commit comments

Comments
 (0)