tamer: parse::state: Superstate support for Token type lifting
What hell have I gotten myself into. In the end, this wasn't too bad, but the initial batch of errors was really demotivating; the diff does this no justice. `Lookahead::into_super` was created to help tame those errors. ...now I can move forward. Imagine my disappointment when I ran into this when expecting from previous work that superstates would now work properly for the AirAggregate parsers. (The reason this was needed is because AirAggregate splits tokens into subtypes for child parsers.) DEV-13708main
parent
68e2d5d10e
commit
c59b92370c
|
@ -129,7 +129,7 @@ where
|
|||
Self::Error: Into<<Self::Super as ParseState>::Error>,
|
||||
{
|
||||
/// Input tokens to the parser.
|
||||
type Token: Token;
|
||||
type Token: Token + Into<<Self::Super as ParseState>::Token>;
|
||||
|
||||
/// Objects produced by a parser utilizing these states.
|
||||
type Object: Object;
|
||||
|
@ -156,11 +156,8 @@ where
|
|||
/// This is the same concept as [`StitchableParseState`],
|
||||
/// but operating in reverse
|
||||
/// (delegation via trampoline instead of direct function call).
|
||||
type Super: ClosedParseState<
|
||||
Token = Self::Token,
|
||||
Object = Self::Object,
|
||||
Context = Self::Context,
|
||||
> = Self;
|
||||
type Super: ClosedParseState<Object = Self::Object, Context = Self::Context> =
|
||||
Self;
|
||||
|
||||
/// Object provided to parser alongside each token.
|
||||
///
|
||||
|
@ -359,7 +356,7 @@ where
|
|||
mut context: C,
|
||||
dead: impl FnOnce(
|
||||
Self::Super,
|
||||
Self::Token,
|
||||
<Self::Super as ParseState>::Token,
|
||||
C,
|
||||
) -> TransitionResult<Self::Super>,
|
||||
) -> TransitionResult<Self::Super>
|
||||
|
@ -460,7 +457,7 @@ where
|
|||
into(newst, Some(obj), env),
|
||||
TransitionData::Result(
|
||||
Ok(Incomplete),
|
||||
lookahead.map(Lookahead::inner_into),
|
||||
lookahead.map(Lookahead::into_super::<SP>),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -472,7 +469,7 @@ where
|
|||
Ok(_) => Ok(Incomplete),
|
||||
Err(e) => Err(e.into()),
|
||||
},
|
||||
lookahead.map(Lookahead::inner_into),
|
||||
lookahead.map(Lookahead::into_super::<SP>),
|
||||
),
|
||||
),
|
||||
}
|
||||
|
@ -511,7 +508,8 @@ pub trait StitchableParseState<SP: ParseState> =
|
|||
|
||||
pub trait PartiallyStitchableParseState<SP: ParseState> = ClosedParseState
|
||||
where
|
||||
<SP as ParseState>::Token: From<<Self as ParseState>::Token>,
|
||||
<<SP as ParseState>::Super as ParseState>::Token:
|
||||
From<<<Self as ParseState>::Super as ParseState>::Token>,
|
||||
<Self as ParseState>::Error: Into<<SP as ParseState>::Error>;
|
||||
|
||||
pub mod context {
|
||||
|
|
|
@ -206,13 +206,13 @@ impl<S: ParseState> TransitionResult<S> {
|
|||
S: PartiallyStitchableParseState<SB>,
|
||||
{
|
||||
self.branch_dead_la(
|
||||
|st, Lookahead(la), bctx| {
|
||||
|st, la, bctx| {
|
||||
fdead(st, bctx)
|
||||
.with_lookahead(<SB as ParseState>::Token::from(la))
|
||||
.maybe_with_lookahead(Some(la.into_super::<SB>()))
|
||||
},
|
||||
|st, result, la, bctx| {
|
||||
falive(st, result, bctx)
|
||||
.maybe_with_lookahead(la.map(Lookahead::inner_into))
|
||||
.maybe_with_lookahead(la.map(Lookahead::into_super::<SB>))
|
||||
},
|
||||
bctx,
|
||||
)
|
||||
|
@ -294,6 +294,22 @@ impl<T: Token> Lookahead<T> {
|
|||
Self(tok) => Lookahead(tok.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the inner [`Token`] of lookahead into the token expected by
|
||||
/// the superstate [`S::Super`](ParseState::Super).
|
||||
///
|
||||
/// This simply sets strict trait bounds to serve as a checkpoint where
|
||||
/// we know for certain what types are involved;
|
||||
/// there's a whole lot of types involved in the parsing framework
|
||||
/// and it gets very difficult to understand when errors occur.
|
||||
pub fn into_super<S: ParseState>(
|
||||
self,
|
||||
) -> Lookahead<<S::Super as ParseState>::Token>
|
||||
where
|
||||
T: Into<<S::Super as ParseState>::Token>,
|
||||
{
|
||||
self.inner_into::<<S::Super as ParseState>::Token>()
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about the state transition.
|
||||
|
@ -340,9 +356,9 @@ impl<S: ParseState> TransitionData<S> {
|
|||
match self {
|
||||
Self::Result(st_result, ola) => TransitionData::Result(
|
||||
st_result.map(ParseStatus::into_super).map_err(|e| e.into()),
|
||||
ola,
|
||||
ola.map(Lookahead::inner_into),
|
||||
),
|
||||
Self::Dead(la) => TransitionData::Dead(la),
|
||||
Self::Dead(la) => TransitionData::Dead(la.inner_into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,7 +454,7 @@ impl<S: ParseState> TransitionData<S> {
|
|||
use TransitionData::*;
|
||||
|
||||
match self {
|
||||
Dead(la) => Dead(la.inner_into()),
|
||||
Dead(la) => Dead(la.into_super::<SB>()),
|
||||
Result(result, la) => Result(
|
||||
match result {
|
||||
Ok(status) => Ok(status.inner_into()),
|
||||
|
@ -447,7 +463,7 @@ impl<S: ParseState> TransitionData<S> {
|
|||
// (which will be the same type if SB is closed).
|
||||
Err(e) => Err(e.into().into()),
|
||||
},
|
||||
la.map(Lookahead::inner_into),
|
||||
la.map(Lookahead::into_super::<SB>),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -567,10 +583,13 @@ impl<S: ParseState> Transition<S> {
|
|||
/// object first,
|
||||
/// use [`Transition::result`] or other methods along with a token
|
||||
/// of [`Lookahead`].
|
||||
pub fn dead(self, tok: S::Token) -> TransitionResult<S::Super> {
|
||||
pub fn dead<T: Token + Into<<S::Super as ParseState>::Token>>(
|
||||
self,
|
||||
tok: T,
|
||||
) -> TransitionResult<S::Super> {
|
||||
TransitionResult(
|
||||
self.into_super(),
|
||||
TransitionData::Dead(Lookahead(tok)),
|
||||
TransitionData::Dead(Lookahead(tok).into_super::<S>()),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue