parser3
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
use crate::parser::error::ParseError;
|
||||
pub use span::*;
|
||||
use std::iter::Peekable;
|
||||
pub use token::*;
|
||||
|
||||
mod span;
|
||||
mod token;
|
||||
|
||||
pub struct Cursor<'a> {
|
||||
pub span: Span,
|
||||
tokens: Peekable<Tokens<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Cursor<'a> {
|
||||
pub fn new(text: &'a str) -> Self {
|
||||
Self {
|
||||
span: Span { first: 0, last: 0 },
|
||||
tokens: Tokens::new(text).peekable(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next(&mut self) -> Option<Token> {
|
||||
self.tokens.next().map(|inst| {
|
||||
self.span = inst.span;
|
||||
inst.inner
|
||||
})
|
||||
}
|
||||
|
||||
pub fn peek(&mut self) -> Option<&Token> {
|
||||
self.tokens.peek().map(|inst| &inst.inner)
|
||||
}
|
||||
|
||||
pub fn expect_next(&mut self) -> Result<Token, ParseError> {
|
||||
self.next().ok_or_else(|| ParseError {
|
||||
spans: Vec::new(),
|
||||
msg: "unexpected end of file".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expect(&mut self, token: Token) -> Result<Token, ParseError> {
|
||||
let next = self.expect_next()?;
|
||||
if next == token {
|
||||
Ok(next)
|
||||
} else {
|
||||
self.unexpected(next, &format!("{token:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_ident(&mut self) -> Result<String, ParseError> {
|
||||
let next = self.expect_next()?;
|
||||
if let Token::Ident(s) = next {
|
||||
Ok(s)
|
||||
} else {
|
||||
self.unexpected(next, "identifier")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unexpected<T>(&self, token: Token, expected: &str) -> Result<T, ParseError> {
|
||||
Err(ParseError::unexpected_token(
|
||||
Spanned {
|
||||
inner: token,
|
||||
span: self.span,
|
||||
},
|
||||
expected,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn peek_first(&mut self) -> usize {
|
||||
self.tokens.peek().map(|i| i.span.first).unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn cur_last(&mut self) -> usize {
|
||||
self.span.last
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user