···19}
2021/// The peeking functionality of concrete parsers.
22-pub trait PeekerOperator {
23 /// The type of the elements.
24 type Item: PeekerItem;
25···28 fn peek_for_token(&self, parser: &mut Parser) -> Option<Token>;
2930 /// Peek for the next element. Implemented based on
31- /// [PeekerOperator::peek_for_token].
32 fn peek_for(&self, parser: &mut Parser) -> Option<Self::Item> {
33 Self::Item::from_tok(
34 self.peek_for_token(parser)?
···36 }
37}
3839-/// Marks container input types at the trait-level.
40-pub trait IsContainerInput {}
41-/// Marks container types at the trait-level.
42pub trait ContainedType {}
4344/// Interface for containing data in the concrete parser structs.
45-pub trait Container {
46 /// The type the concrete parsers are constructed from.
47- type Input: IsContainerInput;
48 /// The type the concrete parser structs contain.
49 type ContainedType: ContainedType;
50···54 fn new(value: Self::Input) -> Self;
55}
5657-/// Along with [PeekerOperator], defines the core functionality
58/// of concrete parsers.
59///
60/// Has blanket implementation for all concrete parsers.
61-pub trait Operator: PeekerOperator + Container {
62 /// Peek the next token in the [Parser] stream. If it
63- /// satisfies the criteria as specified by the [PeekerOperator]
64 /// implementation, consume and return the [Token].
65 fn try_next_token(&self, parser: &mut Parser) -> Option<Token>;
66 /// Try to advance to the next element. Implemented based on
67- /// [Operator::try_next_token].
68 ///
69 /// If the inner `try_next_token` consumes and returns the token,
70 /// constructs and returns the element from it.
71 ///
72- /// Return type is the same as that of [PeekerOperator::peek_for].
73 fn try_next(&self, parser: &mut Parser) -> Option<Self::Item> {
74 Self::Item::from_tok(
75 self.try_next_token(parser)?
···77 }
78}
7980-impl<T> Operator for T
81where
82- T: PeekerOperator + Container
83{
84 fn try_next_token(&self, parser: &mut Parser) -> Option<Token> {
85 if let Some(tok) = self.peek_for_token(parser) {
···91 }
92}
9394-impl IsContainerInput for String {}
95impl ContainedType for String {}
9697-impl IsContainerInput for () {}
98impl ContainedType for () {}
99100mod exact_match;
101mod or_exact_match;
102mod any_str_match;
103mod is_newline;
104-pub use {
105- exact_match::ExactMatch,
106- or_exact_match::OrExactMatch,
107- any_str_match::AnyStrMatch,
108- is_newline::IsNewline,
109-};
000
···19}
2021/// The peeking functionality of concrete parsers.
22+pub trait Peeker {
23 /// The type of the elements.
24 type Item: PeekerItem;
25···28 fn peek_for_token(&self, parser: &mut Parser) -> Option<Token>;
2930 /// Peek for the next element. Implemented based on
31+ /// [Peeker::peek_for_token].
32 fn peek_for(&self, parser: &mut Parser) -> Option<Self::Item> {
33 Self::Item::from_tok(
34 self.peek_for_token(parser)?
···36 }
37}
3839+/// Marks [ContainerCp] input types at the trait-level.
40+pub trait IsContainerCpInput {}
41+/// Marks [ContainerCp] types at the trait-level.
42pub trait ContainedType {}
4344/// Interface for containing data in the concrete parser structs.
45+pub trait ContainerCp {
46 /// The type the concrete parsers are constructed from.
47+ type Input: IsContainerCpInput;
48 /// The type the concrete parser structs contain.
49 type ContainedType: ContainedType;
50···54 fn new(value: Self::Input) -> Self;
55}
5657+/// Along with [Peeker], defines the core functionality
58/// of concrete parsers.
59///
60/// Has blanket implementation for all concrete parsers.
61+pub trait ConcreteParser: Peeker + ContainerCp {
62 /// Peek the next token in the [Parser] stream. If it
63+ /// satisfies the criteria as specified by the [Peeker]
64 /// implementation, consume and return the [Token].
65 fn try_next_token(&self, parser: &mut Parser) -> Option<Token>;
66 /// Try to advance to the next element. Implemented based on
67+ /// [ConcreteParser::try_next_token].
68 ///
69 /// If the inner `try_next_token` consumes and returns the token,
70 /// constructs and returns the element from it.
71 ///
72+ /// Return type is the same as that of [Peeker::peek_for].
73 fn try_next(&self, parser: &mut Parser) -> Option<Self::Item> {
74 Self::Item::from_tok(
75 self.try_next_token(parser)?
···77 }
78}
7980+impl<T> ConcreteParser for T
81where
82+ T: Peeker + ContainerCp
83{
84 fn try_next_token(&self, parser: &mut Parser) -> Option<Token> {
85 if let Some(tok) = self.peek_for_token(parser) {
···91 }
92}
9394+impl IsContainerCpInput for String {}
95impl ContainedType for String {}
9697+impl IsContainerCpInput for () {}
98impl ContainedType for () {}
99100mod exact_match;
101mod or_exact_match;
102mod any_str_match;
103mod is_newline;
104+/// All concrete parsers.
105+pub mod list {
106+ pub use super::{
107+ exact_match::ExactMatch,
108+ or_exact_match::OrExactMatch,
109+ any_str_match::AnyStrMatch,
110+ is_newline::IsNewline,
111+ };
112+}
···5/// In particular, match the [Token::Str] variant of
6/// the [Token] enum, and return the inner [String].
7pub struct AnyStrMatch;
8-impl PeekerOperator for AnyStrMatch {
9 type Item = String;
1011 fn peek_for_token(&self, parser: &mut Parser) -> Option<Token> {
···15 }
16 }
17}
18-impl Container for AnyStrMatch {
19 type Input = ();
20 type ContainedType = ();
21
···5/// In particular, match the [Token::Str] variant of
6/// the [Token] enum, and return the inner [String].
7pub struct AnyStrMatch;
8+impl Peeker for AnyStrMatch {
9 type Item = String;
1011 fn peek_for_token(&self, parser: &mut Parser) -> Option<Token> {
···15 }
16 }
17}
18+impl ContainerCp for AnyStrMatch {
19 type Input = ();
20 type ContainedType = ();
21
···6pub struct OrExactMatch {
7 matches: HashSet<String>
8}
9-impl PeekerOperator for OrExactMatch {
10 type Item = String;
1112 fn peek_for_token(&self, parser: &mut Parser) -> Option<Token> {
···22 }
23}
2425-impl IsContainerInput for Vec<&'static str> {}
26impl ContainedType for HashSet<String> {}
2728-impl Container for OrExactMatch {
29 type ContainedType = HashSet<String>;
30 type Input = Vec<&'static str>;
31
···6pub struct OrExactMatch {
7 matches: HashSet<String>
8}
9+impl Peeker for OrExactMatch {
10 type Item = String;
1112 fn peek_for_token(&self, parser: &mut Parser) -> Option<Token> {
···22 }
23}
2425+impl IsContainerCpInput for Vec<&'static str> {}
26impl ContainedType for HashSet<String> {}
2728+impl ContainerCp for OrExactMatch {
29 type ContainedType = HashSet<String>;
30 type Input = Vec<&'static str>;
31
+2-2
src/parser/subparser.rs
···7/// tokens based on some pattern.
8///
9/// The pattern depends on the generic `C`, which corresponds
10-/// to a concrete parser. (See [parsers].)
11pub trait ConcreteSubparser<C> {
12 /// Build the subparser based on the concrete parser.
13 fn subparse
14 (value: C::Input, parser: &mut Parser) -> Parser
15 where
16- C: Container;
17}
1819mod collect_till;
···7/// tokens based on some pattern.
8///
9/// The pattern depends on the generic `C`, which corresponds
10+/// to a concrete parser. (See [concrete_parser].)
11pub trait ConcreteSubparser<C> {
12 /// Build the subparser based on the concrete parser.
13 fn subparse
14 (value: C::Input, parser: &mut Parser) -> Parser
15 where
16+ C: concrete_parser::ContainerCp;
17}
1819mod collect_till;
+4-4
src/parser/subparser/collect_till.rs
···1-use super::*;
23/// Consume tokens into a new parser until the concrete
4/// parser returns something. Stops when it hits `Some(_)`.
5///
6/// Said concrete pattern here is provided by
7/// the generic parameter `Op`.
8-pub struct CollectTill<Op: parsers::Operator>(Op);
9impl<Op> ConcreteSubparser<Op> for CollectTill<Op>
10where
11- Op: parsers::Operator
12{
13 fn subparse
14 (value: Op::Input, parser: &mut Parser) -> Parser
15 where
16- Op: Container
17 {
18 let op = Op::new(value);
19
···1+use crate::prelude::*;
23/// Consume tokens into a new parser until the concrete
4/// parser returns something. Stops when it hits `Some(_)`.
5///
6/// Said concrete pattern here is provided by
7/// the generic parameter `Op`.
8+pub struct CollectTill<Op: ConcreteParser>(Op);
9impl<Op> ConcreteSubparser<Op> for CollectTill<Op>
10where
11+ Op: ConcreteParser
12{
13 fn subparse
14 (value: Op::Input, parser: &mut Parser) -> Parser
15 where
16+ Op: concrete_parser::ContainerCp
17 {
18 let op = Op::new(value);
19
+4-4
src/parser/subparser/collect_while.rs
···1-use super::*;
23/// Consume tokens into a new parser while the concrete
4/// parser returns something. Stop consuming if it returns
···6///
7/// Said concrete pattern here is provided by
8/// the generic parameter `Op`.
9-pub struct CollectWhile<Op: parsers::Operator>(Op);
10impl<Op> ConcreteSubparser<Op> for CollectWhile<Op>
11where
12- Op: parsers::Operator
13{
14 fn subparse
15 (value: <Op>::Input, parser: &mut Parser) -> Parser
16 where
17- Op: Container
18 {
19 let op = Op::new(value);
20
···1+use crate::prelude::*;
23/// Consume tokens into a new parser while the concrete
4/// parser returns something. Stop consuming if it returns
···6///
7/// Said concrete pattern here is provided by
8/// the generic parameter `Op`.
9+pub struct CollectWhile<Op: ConcreteParser>(Op);
10impl<Op> ConcreteSubparser<Op> for CollectWhile<Op>
11where
12+ Op: ConcreteParser
13{
14 fn subparse
15 (value: <Op>::Input, parser: &mut Parser) -> Parser
16 where
17+ Op: concrete_parser::ContainerCp
18 {
19 let op = Op::new(value);
20