reduce code repetition regarding single-token recognition in parser

This commit is contained in:
Alain Zscheile 2023-05-21 13:27:22 +02:00
parent 23ce8d0cb9
commit 8f1f746a82

View file

@ -124,6 +124,10 @@ impl<'a> ParserContext<'a> {
})
}
}
fn maybe_eat_token(&mut self, tok: Token<'a>) -> Option<Location> {
self.pklx.next_if(|(_, t)| t == &tok).map(|(loc, _)| loc)
}
}
impl Path {
@ -149,7 +153,7 @@ impl Path {
// make sure the parser can somewhat recover...
*ctx = tmpctx;
if ctx.pklx.next_if(|(_, t)| t == &Token::Dot).is_none() {
if ctx.maybe_eat_token(Token::Dot).is_none() {
break Ok(Path {
loc: pathloc,
idents: ret.into_boxed_slice(),
@ -189,7 +193,7 @@ impl Statement {
let args = if let Some(&(_, Token::Comma)) = ctx.pklx.peek() {
let mut args = BTreeMap::new();
while ctx.pklx.next_if(|(_, t)| t == &Token::Comma).is_some() {
while ctx.maybe_eat_token(Token::Comma).is_some() {
let Path { loc, idents } = Path::parse_high(ctx)?;
ctx.expect_token(Token::Assign, "=")?;
let obj = Object::parse_high(ctx)?;
@ -223,16 +227,15 @@ impl Object {
}
}
// either we need to deal with a bunch of stmts, or just a single one (basically alias)
match ctx.pklx.peek() {
None => Err(ctx.make_eof()),
Some((_, Token::OpenBrace)) => {
ctx.pklx.next();
let mut codata = Vec::new();
let mut ret = None;
while ctx.pklx.next_if(|(_, t)| t == &Token::CloseBrace).is_none() {
while ctx.maybe_eat_token(Token::CloseBrace).is_none() {
let stmt = Statement::parse_high(ctx)?;
if ctx.pklx.next_if(|(_, t)| t == &Token::SemiColon).is_some() {
if ctx.maybe_eat_token(Token::SemiColon).is_some() {
codata.push(stmt);
} else {
ret = Some(stmt);
@ -316,7 +319,7 @@ impl Module {
// optional: arguments
let mut args = Vec::new();
if ctx.pklx.next_if(|(_, t)| t == &Token::OpenBrace).is_some() {
if ctx.maybe_eat_token(Token::OpenBrace).is_some() {
loop {
let (loc, tok) = ctx.pklx.next().ok_or(Error {
loc: ctx.eof_loc,