divide atom parser into sub-parsers with context
This commit is contained in:
parent
900b8b198e
commit
9c910b8076
1 changed files with 160 additions and 45 deletions
|
@ -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),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue