Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed May 6, 2024
1 parent 608ecae commit 26bb810
Show file tree
Hide file tree
Showing 44 changed files with 1,139 additions and 1,209 deletions.
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ name = "ast-demangle"
repository = "https://github.com/EFanZh/ast-demangle"
version = "0.4.0"

[workspace]
members = ["crates/mini-parser", "fuzz", "test-utilities"]

[dependencies]
fmt-tools = "0.1"
mini-parser = { path = "crates/mini-parser" }
num-traits = "0.2"
punycode = "0.4"

[dev-dependencies]
rustc-demangle = "0.1"
test-utilities = { path = "test-utilities" }

[workspace]
members = ["fuzz", "test-utilities"]
5 changes: 5 additions & 0 deletions crates/mini-parser/Cargo.toml
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"
48 changes: 48 additions & 0 deletions crates/mini-parser/src/combinators/alt.rs
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),
}
}
40 changes: 40 additions & 0 deletions crates/mini-parser/src/combinators/delimited.rs
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 }
}
35 changes: 35 additions & 0 deletions crates/mini-parser/src/combinators/flat_map.rs
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 }
}
35 changes: 35 additions & 0 deletions crates/mini-parser/src/combinators/inspect.rs
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 }
}
34 changes: 34 additions & 0 deletions crates/mini-parser/src/combinators/many0.rs
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 }
}
31 changes: 31 additions & 0 deletions crates/mini-parser/src/combinators/map.rs
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 }
}
33 changes: 33 additions & 0 deletions crates/mini-parser/src/combinators/map_opt.rs
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 }
}
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;
28 changes: 28 additions & 0 deletions crates/mini-parser/src/combinators/opt.rs
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 }
}
37 changes: 37 additions & 0 deletions crates/mini-parser/src/combinators/or.rs
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 }
}
Loading

0 comments on commit 26bb810

Please sign in to comment.