2021-03-02 03:39:55 +00:00
|
|
|
use pest::{ParseResult as PestResult, ParserState};
|
|
|
|
|
2021-03-02 22:47:33 +00:00
|
|
|
use super::Rule;
|
2021-03-02 03:39:55 +00:00
|
|
|
|
|
|
|
type PSR<'a> = Box<ParserState<'a, Rule>>;
|
|
|
|
|
2021-03-02 22:47:33 +00:00
|
|
|
/// This is a hack around the literal syntax to allow us to parse characters statefully.
|
2021-03-02 03:39:55 +00:00
|
|
|
pub(crate) fn literal_internal(state: PSR) -> PestResult<PSR> {
|
|
|
|
use pest::Atomicity;
|
|
|
|
|
|
|
|
// yoinked from the generated code
|
|
|
|
#[inline]
|
|
|
|
#[allow(non_snake_case, unused_variables)]
|
|
|
|
pub fn digit(state: PSR) -> PestResult<PSR> {
|
|
|
|
state.rule(Rule::digit, |state| {
|
|
|
|
state.atomic(Atomicity::Atomic, |state| {
|
|
|
|
state.match_range('\u{30}'..'\u{39}')
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
#[allow(non_snake_case, unused_variables)]
|
|
|
|
pub fn number(state: PSR) -> PestResult<PSR> {
|
|
|
|
state.rule(Rule::number, |state| {
|
|
|
|
state.atomic(Atomicity::Atomic, |state| {
|
|
|
|
state.sequence(|state| {
|
|
|
|
digit(state).and_then(|state| state.repeat(|state| digit(state)))
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
#[allow(non_snake_case, unused_variables)]
|
|
|
|
pub fn char8(state: PSR) -> PestResult<PSR> {
|
|
|
|
state.rule(Rule::char8, |state| {
|
|
|
|
state.atomic(Atomicity::Atomic, |state| {
|
|
|
|
state.match_range('\u{1}'..'\u{ff}')
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
#[allow(non_snake_case, unused_variables)]
|
|
|
|
pub fn crlf(state: PSR) -> PestResult<PSR> {
|
|
|
|
state.sequence(|state| state.match_string("\r")?.match_string("\n"))
|
|
|
|
}
|
|
|
|
|
|
|
|
let state = state.match_string("{").and_then(number)?;
|
|
|
|
let num_chars = {
|
|
|
|
let mut queue = state.queue().iter().rev();
|
|
|
|
println!("QUEUE: {:?}", queue);
|
|
|
|
let end = queue.next().unwrap();
|
|
|
|
let start = queue.next().unwrap();
|
|
|
|
let inp = state.position().get_str();
|
|
|
|
let seg = &inp[start.input_pos()..end.input_pos()];
|
|
|
|
seg.parse::<usize>().unwrap()
|
|
|
|
};
|
|
|
|
|
|
|
|
state
|
|
|
|
.match_string("}")
|
|
|
|
.and_then(crlf)?
|
|
|
|
.rule(Rule::literal_str, |state| {
|
|
|
|
state.atomic(Atomicity::Atomic, |state| {
|
|
|
|
let mut state = Ok(state);
|
|
|
|
for _ in 0..num_chars {
|
|
|
|
state = state.and_then(char8);
|
|
|
|
}
|
|
|
|
|
|
|
|
state
|
|
|
|
})
|
|
|
|
})
|
|
|
|
// todo!("hit internal state: {:?}", state,);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn noop(state: PSR) -> PestResult<PSR> {
|
|
|
|
// TODO: probably should be unreachable?
|
|
|
|
Ok(state)
|
|
|
|
}
|