1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::collections::VecDeque;
use super::token::Token;
pub type ParserResult<T> = Result<T, ParserError>;
#[derive(Debug)]
pub enum ParserError {
Expecting(String),
OutOfTokens,
}
pub struct Parser {
tokens: VecDeque<Token>,
}
impl Parser {
/// Return a reference to the next token in the queue
pub fn peek(&self) -> Option<&Token> {
self.tokens.get(0)
}
/// Is the next token equal to `expecting`
pub fn peek_is(&self, expecting: &Token) -> bool {
match self.peek() {
Some(token) if token == expecting => true,
_ => false,
}
}
/// Mandatory pop
/// Pop the next token off the queue
pub fn pop(&mut self) -> ParserResult<Token> {
self.tokens.pop_front().ok_or(ParserError::OutOfTokens)
}
/// Optional pop
/// If the next token is equal to `expecting`, pop it and return true,
/// otherwise return false and leave the next token
pub fn pop_if(&mut self, expecting: &Token) -> bool {
let eq = self.peek_is(expecting);
if eq {
self.tokens.pop_front().expect("Impossible error");
true
} else {
false
}
}
pub fn expect(&mut self, expecting: &Token) -> ParserResult<Token> {
let tok = self.pop()?;
// We know tok is a token at this point, since the previous line
// would've done an early return with ParserError::OutOfTokens otherwise
if &tok == expecting {
Ok(tok)
} else {
Err(ParserError::Expecting(
format!("{:?}, found {:?}", tok, expecting),
))
}
}
pub fn expect_string(&mut self) -> ParserResult<Token> {
let tok = self.pop()?;
// We know tok is a token at this point, since the previous line
// would've done an early return with ParserError::OutOfTokens otherwise
match tok {
Token::StringLiteral(_) => Ok(tok),
_ => Err(ParserError::Expecting(format!("string, found {:?}", tok))),
}
}
pub fn expect_number(&mut self) -> ParserResult<Token> {
let tok = self.pop()?;
// We know tok is a token at this point, since the previous line
// would've done an early return with ParserError::OutOfTokens otherwise
match tok {
Token::NumberLiteral(_) => Ok(tok),
_ => Err(ParserError::Expecting(format!("number, found {:?}", tok))),
}
}
pub fn expect_identifier(&mut self) -> ParserResult<Token> {
let tok = self.pop()?;
// We know tok is a token at this point, since the previous line
// would've done an early return with ParserError::OutOfTokens otherwise
match tok {
Token::Identifier(_) => Ok(tok),
_ => Err(ParserError::Expecting(
format!("identifier, found {:?}", tok),
)),
}
}
pub fn from_tokens(v: Vec<Token>) -> Parser {
Parser { tokens: VecDeque::from(v) }
}
}