divide atom parser into sub-parsers with context

This commit is contained in:
Ponj 2024-11-09 18:58:28 -05:00
parent 900b8b198e
commit 9c910b8076
Signed by: p6nj
GPG key ID: 6FED68D87C479A59

View file

@ -16,8 +16,6 @@ use nom::{
Err, IResult, Parser, Err, IResult, Parser,
}; };
use crate::bng::score::{modifier, quick_modifier, slope_modifier};
use super::{ use super::{
super::super::Expression as Instruction, Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier, super::super::Expression as Instruction, Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier,
}; };
@ -45,6 +43,154 @@ where
))(i) ))(i)
} }
fn note<'a, E>(notes: &'a str) -> impl Parser<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str> + FromExternalError<&'a str, TryFromIntError>,
{
context(
"note",
map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from).map(FlatAtom::Note),
)
}
fn rest<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
context("rest", value(FlatAtom::Rest, char(Atom::REST)))(i)
}
fn start_here<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
context(
"start_here",
value(FlatAtom::StartHere, char(Atom::START_HERE)),
)(i)
}
fn modifier<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
use super::super::modifier;
context(
"modifier",
preceded(char(Atom::MODIFIER), modifier).map(FlatAtom::Modifier),
)(i)
}
fn quick_modifier<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
use super::super::quick_modifier;
context(
"quick_modifier",
quick_modifier.map(FlatAtom::QuickModifier),
)(i)
}
fn loop_starts<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
context(
"loop_starts",
preceded(
char(Atom::LOOP.0),
map_opt(opt(u8), |n| {
if let Some(n) = n {
NonZeroU8::new(n)
} else {
unsafe { Some(NonZeroU8::new_unchecked(2)) }
}
}),
)
.map(FlatAtom::LoopStarts),
)(i)
}
fn loop_ends<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
context("loop_ends", value(FlatAtom::LoopEnds, char(Atom::LOOP.1)))(i)
}
fn tuple_starts<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
context(
"tuple_starts",
value(FlatAtom::TupleStarts, char(Atom::TUPLE.0)),
)(i)
}
fn tuple_ends<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
context(
"tuple_ends",
value(FlatAtom::TupleEnds, char(Atom::TUPLE.1)),
)(i)
}
fn slope_starts<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str> + FromExternalError<&'a str, E>,
{
use super::super::slope_modifier;
context(
"slope_starts",
terminated(
preceded(
char(Atom::SLOPE.0),
separated_pair(
slope_modifier,
char(' '),
map_res(take_till1(|c| c == ','), |s: &str| {
s.parse()
.map_err(|_| E::from_error_kind(s, ErrorKind::Verify))
}),
),
),
char(','),
)
.map(|(sm, i)| FlatAtom::SlopeStarts(sm, i)),
)(i)
}
fn slope_ends<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
context(
"slope_ends",
value(FlatAtom::SlopeEnds, char(Atom::SLOPE.1)),
)(i)
}
fn comment<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
where
E: ParseError<&'a str> + ContextError<&'a str>,
{
context(
"comment",
value(
FlatAtom::Comment,
delimited(
char(Atom::COMMENT.0),
take_till(|c| c == Atom::COMMENT.1),
char(Atom::COMMENT.1),
),
),
)(i)
}
fn atom<'a, E>(notes: &'a str) -> impl Parser<&'a str, FlatAtom, E> fn atom<'a, E>(notes: &'a str) -> impl Parser<&'a str, FlatAtom, E>
where where
E: ParseError<&'a str> E: ParseError<&'a str>
@ -55,49 +201,18 @@ where
context( context(
"atom", "atom",
alt(( alt((
map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from).map(FlatAtom::Note), note(notes),
value(FlatAtom::Rest, char(Atom::REST)), rest,
value(FlatAtom::StartHere, char(Atom::START_HERE)), start_here,
preceded(char(Atom::MODIFIER), modifier).map(FlatAtom::Modifier), modifier,
quick_modifier.map(FlatAtom::QuickModifier), quick_modifier,
preceded( loop_starts,
char(Atom::LOOP.0), loop_ends,
map_opt(opt(u8), |n| { tuple_starts,
if let Some(n) = n { tuple_ends,
NonZeroU8::new(n) slope_starts,
} else { slope_ends,
unsafe { Some(NonZeroU8::new_unchecked(2)) } comment,
}
}),
)
.map(FlatAtom::LoopStarts),
value(FlatAtom::LoopEnds, char(Atom::LOOP.1)),
value(FlatAtom::TupleStarts, char(Atom::TUPLE.0)),
value(FlatAtom::TupleEnds, char(Atom::TUPLE.1)),
terminated(
preceded(
char(Atom::SLOPE.0),
separated_pair(
slope_modifier,
char(' '),
map_res(take_till1(|c| c == ','), |s: &str| {
s.parse()
.map_err(|_| E::from_error_kind(s, ErrorKind::Verify))
}),
),
),
char(','),
)
.map(|(sm, i)| FlatAtom::SlopeStarts(sm, i)),
value(FlatAtom::SlopeEnds, char(Atom::SLOPE.1)),
value(
FlatAtom::Comment,
delimited(
char(Atom::COMMENT.0),
take_till(|c| c == Atom::COMMENT.1),
char(Atom::COMMENT.1),
),
),
)), )),
) )
} }