Skip to main content

parser_state/
lib.rs

1use anyhow::anyhow;
2use std::cmp::PartialEq;
3use std::fmt::Display;
4
5pub trait Token {
6    type Tag: Display + PartialEq;
7    fn tag(&self) -> Self::Tag;
8    fn lexeme(&self) -> &str;
9}
10
11pub trait Lexer {
12    type Token: Token;
13    fn next_token(&mut self) -> anyhow::Result<Self::Token>;
14}
15
16pub struct ParserState<L: Lexer> {
17    lexer: L,
18    pub current: L::Token,
19}
20
21impl<L: Lexer> ParserState<L> {
22    pub fn new(mut lexer: L) -> anyhow::Result<Self> {
23        let current = lexer.next_token()?;
24        Ok(Self { lexer, current })
25    }
26
27    pub fn advance(&mut self) -> anyhow::Result<()> {
28        self.current = self.lexer.next_token()?;
29        Ok(())
30    }
31
32    pub fn advance_keep_current(&mut self) -> anyhow::Result<L::Token> {
33        let kept = std::mem::replace(&mut self.current, self.lexer.next_token()?);
34        Ok(kept)
35    }
36
37    pub fn matches(&mut self, expected_tag: <L::Token as Token>::Tag) -> anyhow::Result<bool> {
38        let is_match = self.current.tag() == expected_tag;
39        if is_match {
40            self.advance()?;
41        }
42        Ok(is_match)
43    }
44
45    pub fn expect(&mut self, expected_tag: <L::Token as Token>::Tag) -> anyhow::Result<()> {
46        if self.current.tag() == expected_tag {
47            self.advance()?;
48            Ok(())
49        } else {
50            Err(anyhow!(
51                "expected `{}` but got `{}`",
52                expected_tag,
53                self.current.lexeme()
54            ))
55        }
56    }
57
58    pub fn expect_lexeme(&mut self, tag: <L::Token as Token>::Tag) -> anyhow::Result<String> {
59        if self.current.tag() == tag {
60            let token = self.advance_keep_current()?;
61            Ok(token.lexeme().to_string())
62        } else {
63            Err(anyhow!(
64                "expected `{}` but found `{}`",
65                tag,
66                self.current.lexeme()
67            ))
68        }
69    }
70}