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 { impl Path {
@ -149,7 +153,7 @@ impl Path {
// make sure the parser can somewhat recover... // make sure the parser can somewhat recover...
*ctx = tmpctx; *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 { break Ok(Path {
loc: pathloc, loc: pathloc,
idents: ret.into_boxed_slice(), idents: ret.into_boxed_slice(),
@ -189,7 +193,7 @@ impl Statement {
let args = if let Some(&(_, Token::Comma)) = ctx.pklx.peek() { let args = if let Some(&(_, Token::Comma)) = ctx.pklx.peek() {
let mut args = BTreeMap::new(); 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)?; let Path { loc, idents } = Path::parse_high(ctx)?;
ctx.expect_token(Token::Assign, "=")?; ctx.expect_token(Token::Assign, "=")?;
let obj = Object::parse_high(ctx)?; 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() { match ctx.pklx.peek() {
None => Err(ctx.make_eof()), None => Err(ctx.make_eof()),
Some((_, Token::OpenBrace)) => { Some((_, Token::OpenBrace)) => {
ctx.pklx.next(); ctx.pklx.next();
let mut codata = Vec::new(); let mut codata = Vec::new();
let mut ret = None; 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)?; 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); codata.push(stmt);
} else { } else {
ret = Some(stmt); ret = Some(stmt);
@ -316,7 +319,7 @@ impl Module {
// optional: arguments // optional: arguments
let mut args = Vec::new(); 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 { loop {
let (loc, tok) = ctx.pklx.next().ok_or(Error { let (loc, tok) = ctx.pklx.next().ok_or(Error {
loc: ctx.eof_loc, loc: ctx.eof_loc,