Minimal Imperative Parsing Library | https://docs.rs/mipl

improve naming and item visibility in prelude

ecsolticia.codeberg.page 3fa68c98 765e455d

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