-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
44 changed files
with
1,139 additions
and
1,209 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[package] | ||
edition = "2021" | ||
name = "mini-parser" | ||
publish = false | ||
version = "0.1.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use crate::combinators::or::{self, Or}; | ||
use crate::generic_tuple::{FoldFnMut, SplitLast, Tuple}; | ||
use crate::Parser; | ||
|
||
pub struct FoldOr; | ||
|
||
impl FoldFnMut for FoldOr { | ||
type Output<B, T> = Or<T, B>; | ||
|
||
fn call_mut<B, T>(&mut self, init: B, item: T) -> Self::Output<B, T> { | ||
or::or_unchecked(item, init) | ||
} | ||
} | ||
|
||
type AltImpl<T> = <<T as SplitLast>::Rest as Tuple>::RFold<<T as SplitLast>::Last, FoldOr>; | ||
|
||
pub struct Alt<T> | ||
where | ||
T: SplitLast + ?Sized, | ||
{ | ||
inner: AltImpl<T>, | ||
} | ||
|
||
impl<C, T> Parser<C> for Alt<T> | ||
where | ||
C: ?Sized, | ||
T: SplitLast + ?Sized, | ||
AltImpl<T>: Parser<C>, | ||
{ | ||
type Output = <AltImpl<T> as Parser<C>>::Output; | ||
|
||
fn parse(&mut self, context: &mut C) -> Result<Self::Output, ()> { | ||
self.inner.parse(context) | ||
} | ||
} | ||
|
||
pub fn alt<C, T>(parsers: T) -> Alt<T> | ||
where | ||
C: ?Sized, | ||
T: SplitLast, | ||
AltImpl<T>: Parser<C>, | ||
{ | ||
let (last, rest) = parsers.split_last(); | ||
|
||
Alt { | ||
inner: rest.rfold(last, &mut FoldOr), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use crate::Parser; | ||
|
||
pub struct Delimited<P, Q, R> | ||
where | ||
Q: ?Sized, | ||
{ | ||
left: P, | ||
right: R, | ||
middle: Q, | ||
} | ||
|
||
impl<C, P, Q, R> Parser<C> for Delimited<P, Q, R> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
Q: Parser<C> + ?Sized, | ||
R: Parser<C>, | ||
{ | ||
type Output = Q::Output; | ||
|
||
fn parse(&mut self, context: &mut C) -> Result<Self::Output, ()> { | ||
self.left.parse(context)?; | ||
|
||
let output = self.middle.parse(context)?; | ||
|
||
self.right.parse(context)?; | ||
|
||
Ok(output) | ||
} | ||
} | ||
|
||
pub fn delimited<C, P, Q, R>(left: P, middle: Q, right: R) -> Delimited<P, Q, R> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
Q: Parser<C>, | ||
R: Parser<C>, | ||
{ | ||
Delimited { left, right, middle } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use crate::Parser; | ||
|
||
pub struct FlatMap<P, F> | ||
where | ||
F: ?Sized, | ||
{ | ||
parser: P, | ||
f: F, | ||
} | ||
|
||
impl<C, P, F, Q> Parser<C> for FlatMap<P, F> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
F: FnMut(P::Output) -> Q + ?Sized, | ||
Q: Parser<C>, | ||
{ | ||
type Output = <F::Output as Parser<C>>::Output; | ||
|
||
fn parse(&mut self, context: &mut C) -> Result<Self::Output, ()> { | ||
let output = self.parser.parse(context)?; | ||
|
||
(self.f)(output).parse(context) | ||
} | ||
} | ||
|
||
pub fn flat_map<C, P, F, Q>(parser: P, f: F) -> FlatMap<P, F> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
F: FnMut(P::Output) -> Q, | ||
Q: Parser<C>, | ||
{ | ||
FlatMap { parser, f } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use crate::Parser; | ||
|
||
pub struct Inspect<P, F> | ||
where | ||
F: ?Sized, | ||
{ | ||
parser: P, | ||
f: F, | ||
} | ||
|
||
impl<C, P, F> Parser<C> for Inspect<P, F> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
F: FnMut(&mut C, &P::Output) + ?Sized, | ||
{ | ||
type Output = P::Output; | ||
|
||
fn parse(&mut self, context: &mut C) -> Result<Self::Output, ()> { | ||
let output = self.parser.parse(context)?; | ||
|
||
(self.f)(context, &output); | ||
|
||
Ok(output) | ||
} | ||
} | ||
|
||
pub fn inspect<C, P, F>(parser: P, f: F) -> Inspect<P, F> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
F: FnMut(&mut C, &P::Output), | ||
{ | ||
Inspect { parser, f } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
use crate::{Cursor, CursorExt, Parser}; | ||
|
||
pub struct Many0<P> | ||
where | ||
P: ?Sized, | ||
{ | ||
parser: P, | ||
} | ||
|
||
impl<C, P> Parser<C> for Many0<P> | ||
where | ||
C: Cursor + ?Sized, | ||
P: Parser<C> + ?Sized, | ||
{ | ||
type Output = Vec<P::Output>; | ||
|
||
fn parse(&mut self, context: &mut C) -> Result<Self::Output, ()> { | ||
let mut output = Vec::new(); | ||
|
||
while let Ok(item) = context.transaction(|context: &mut _| self.parser.parse(context)) { | ||
output.push(item); | ||
} | ||
|
||
Ok(output) | ||
} | ||
} | ||
|
||
pub fn many0<C, P>(parser: P) -> Many0<P> | ||
where | ||
C: Cursor + ?Sized, | ||
P: Parser<C>, | ||
{ | ||
Many0 { parser } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
use crate::Parser; | ||
|
||
pub struct Map<P, F> | ||
where | ||
F: ?Sized, | ||
{ | ||
parser: P, | ||
f: F, | ||
} | ||
|
||
impl<C, P, F, T> Parser<C> for Map<P, F> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
F: FnMut(P::Output) -> T + ?Sized, | ||
{ | ||
type Output = T; | ||
|
||
fn parse(&mut self, context: &mut C) -> Result<Self::Output, ()> { | ||
self.parser.parse(context).map(|output| (self.f)(output)) | ||
} | ||
} | ||
|
||
pub fn map<C, P, F, T>(parser: P, f: F) -> Map<P, F> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
F: FnMut(P::Output) -> T, | ||
{ | ||
Map { parser, f } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use crate::Parser; | ||
|
||
pub struct MapOpt<P, F> | ||
where | ||
F: ?Sized, | ||
{ | ||
parser: P, | ||
f: F, | ||
} | ||
|
||
impl<C, P, F, U> Parser<C> for MapOpt<P, F> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
F: FnMut(&mut C, P::Output) -> Option<U> + ?Sized, | ||
{ | ||
type Output = U; | ||
|
||
fn parse(&mut self, context: &mut C) -> Result<Self::Output, ()> { | ||
let output = self.parser.parse(context)?; | ||
|
||
(self.f)(context, output).ok_or(()) | ||
} | ||
} | ||
|
||
pub fn map_opt<C, P, F, U>(parser: P, f: F) -> MapOpt<P, F> | ||
where | ||
C: ?Sized, | ||
P: Parser<C>, | ||
F: FnMut(&mut C, P::Output) -> Option<U>, | ||
{ | ||
MapOpt { parser, f } | ||
} |
32 changes: 14 additions & 18 deletions
32
src/mini_parser/combinators/mod.rs → crates/mini-parser/src/combinators/mod.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,25 @@ | ||
mod alt; | ||
mod and; | ||
mod delimited; | ||
mod flat_map; | ||
mod inspect_with_context; | ||
mod many0; | ||
mod map; | ||
mod map_opt; | ||
mod map_opt_with_context; | ||
mod opt; | ||
mod or; | ||
mod preceded; | ||
mod terminated; | ||
mod tuple; | ||
|
||
pub use self::alt::{alt, Alt}; | ||
pub use self::and::{and, And}; | ||
pub use self::delimited::{delimited, Delimited}; | ||
pub use self::flat_map::{flat_map, FlatMap}; | ||
pub use self::inspect_with_context::{inspect_with_context, InspectWithContext}; | ||
pub use self::inspect::{inspect, Inspect}; | ||
pub use self::many0::{many0, Many0}; | ||
pub use self::map::{map, Map}; | ||
pub use self::map_opt::{map_opt, MapOpt}; | ||
pub use self::map_opt_with_context::{map_opt_with_context, MapOptWithContext}; | ||
pub use self::opt::{opt, Opt}; | ||
pub use self::or::{or, Or}; | ||
pub use self::preceded::{preceded, Preceded}; | ||
pub use self::terminated::{terminated, Terminated}; | ||
pub use self::tuple::{tuple, Tuple}; | ||
|
||
mod alt; | ||
mod delimited; | ||
mod flat_map; | ||
mod inspect; | ||
mod many0; | ||
mod map; | ||
mod map_opt; | ||
mod opt; | ||
mod or; | ||
mod preceded; | ||
mod terminated; | ||
mod tuple; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use crate::{Cursor, CursorExt, Parser}; | ||
|
||
pub struct Opt<P> | ||
where | ||
P: ?Sized, | ||
{ | ||
parser: P, | ||
} | ||
|
||
impl<C, P> Parser<C> for Opt<P> | ||
where | ||
C: Cursor + ?Sized, | ||
P: Parser<C> + ?Sized, | ||
{ | ||
type Output = Option<P::Output>; | ||
|
||
fn parse(&mut self, context: &mut C) -> Result<Self::Output, ()> { | ||
Ok(context.transaction(|context: &mut _| self.parser.parse(context)).ok()) | ||
} | ||
} | ||
|
||
pub fn opt<C, P>(parser: P) -> Opt<P> | ||
where | ||
C: Cursor + ?Sized, | ||
P: Parser<C>, | ||
{ | ||
Opt { parser } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use crate::{Cursor, CursorExt, Parser}; | ||
|
||
pub struct Or<P, Q> | ||
where | ||
Q: ?Sized, | ||
{ | ||
lhs: P, | ||
rhs: Q, | ||
} | ||
|
||
impl<C, P, Q> Parser<C> for Or<P, Q> | ||
where | ||
C: Cursor + ?Sized, | ||
P: Parser<C>, | ||
Q: Parser<C, Output = P::Output> + ?Sized, | ||
{ | ||
type Output = Q::Output; | ||
|
||
fn parse(&mut self, context: &mut C) -> Result<Self::Output, ()> { | ||
context | ||
.transaction(|context: &mut _| self.lhs.parse(context)) | ||
.or_else(|()| self.rhs.parse(context)) | ||
} | ||
} | ||
|
||
pub fn or<C, P, Q>(lhs: P, rhs: Q) -> Or<P, Q> | ||
where | ||
C: Cursor + ?Sized, | ||
P: Parser<C>, | ||
Q: Parser<C, Output = P::Output>, | ||
{ | ||
or_unchecked(lhs, rhs) | ||
} | ||
|
||
pub fn or_unchecked<P, Q>(lhs: P, rhs: Q) -> Or<P, Q> { | ||
Or { lhs, rhs } | ||
} |
Oops, something went wrong.