use super::stmt::parse_statement;
use crate::parser::ast::Stmt;
use crate::parser::lexer::{Token, TokenKind};
use std::fmt;
#[derive(Debug)]
pub struct ParseError {
pub msg: String,
pub line: usize,
pub col: usize,
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.line != 0 {
write!(f, "Parse error at line {}, col {}: {}", self.line, self.col, self.msg)
} else {
write!(f, "Parse error: {}", self.msg)
}
}
}
impl std::error::Error for ParseError {}
pub fn parse_tokens(tokens: &[Token], verbose: bool) -> Result<Vec<Stmt>, ParseError> {
let mut parser = super::utils::Parser {
tokens,
pos: 0,
verbose,
};
let mut statements = Vec::new();
while !parser.is_done() {
if parser.verbose {
eprintln!(
"[parser2] parse_tokens => about to parse statement at pos={} token={:?}",
parser.pos,
parser.current()
);
}
if let Some(tok) = parser.current() {
if let Token { kind: TokenKind::Semi, .. } = tok {
parser.advance();
continue;
}
}
let stmt = parse_statement(&mut parser)?;
if parser.verbose {
eprintln!("[parser2] parse_tokens => got a statement: {:?}", stmt);
}
statements.push(stmt);
}
Ok(statements)
}