use crate::phonetic::common::traits::SyllableParser;
use super::super::error::{LLevError, LLevErrorKind, LLevResult, Position};
use super::super::lexer::{Lexer, Token};
use super::Parser;
impl<'a> Parser<'a> {
pub(super) fn advance(&mut self) -> LLevResult<Token> {
self.lexer.next_token()
}
pub(super) fn check(&mut self, expected: &Token) -> bool {
self.lexer.peek().ok() == Some(expected)
}
pub(super) fn expect(&mut self, expected: &Token) -> LLevResult<Token> {
let token = self.advance()?;
if &token == expected {
Ok(token)
} else {
Err(LLevError::expected_token(
format!("{:?}", expected),
format!("{:?}", token),
self.lexer.position(),
))
}
}
pub(super) fn expect_string(&mut self) -> LLevResult<String> {
match self.advance()? {
Token::String(s) => Ok(s),
other => Err(LLevError::expected_token(
"string".to_string(),
format!("{:?}", other),
self.lexer.position(),
)),
}
}
pub(super) fn expect_identifier(&mut self) -> LLevResult<String> {
match self.advance()? {
Token::Identifier(s) => Ok(s),
other => Err(LLevError::expected_token(
"identifier".to_string(),
format!("{:?}", other),
self.lexer.position(),
)),
}
}
pub(super) fn expect_identifier_or_string(&mut self) -> LLevResult<String> {
match self.advance()? {
Token::Identifier(s) => Ok(s),
Token::String(s) => Ok(s),
other => Err(LLevError::expected_token(
"identifier or string".to_string(),
format!("{:?}", other),
self.lexer.position(),
)),
}
}
pub(super) fn expect_number(&mut self) -> LLevResult<usize> {
match self.advance()? {
Token::Number(n) => Ok(n),
Token::Char(c) if c.is_ascii_digit() => {
let mut num_str = String::new();
num_str.push(c);
while let Ok(Token::Char(next_c)) = self.lexer.peek() {
if next_c.is_ascii_digit() {
num_str.push(*next_c);
self.advance()?;
} else {
break;
}
}
num_str.parse::<usize>().map_err(|_| {
LLevError::expected_token(
"number".to_string(),
format!("'{}'", num_str),
self.lexer.position(),
)
})
}
other => Err(LLevError::expected_token(
"number".to_string(),
format!("{:?}", other),
self.lexer.position(),
)),
}
}
pub(super) fn expect_float_or_number(&mut self) -> LLevResult<f64> {
match self.advance()? {
Token::Float(f) => Ok(f),
Token::Number(n) => Ok(n as f64),
other => Err(LLevError::expected_token(
"number or float".to_string(),
format!("{:?}", other),
self.lexer.position(),
)),
}
}
pub(super) fn expect_bool(&mut self) -> LLevResult<bool> {
match self.advance()? {
Token::Identifier(s) if s == "true" => Ok(true),
Token::Identifier(s) if s == "false" => Ok(false),
other => Err(LLevError::expected_token(
"true or false".to_string(),
format!("{:?}", other),
self.lexer.position(),
)),
}
}
pub(super) fn skip_terminator(&mut self) {
loop {
let remaining = self.lexer.remaining_input();
if remaining.starts_with(';') || remaining.starts_with('\n') {
self.lexer.enter_top_level();
let _ = self.advance();
} else {
break;
}
}
}
}
impl<'a> SyllableParser for Parser<'a> {
type Lexer = Lexer<'a>;
type Error = LLevError;
fn lexer_mut(&mut self) -> &mut Self::Lexer {
&mut self.lexer
}
fn make_unexpected_token_error(
&self,
expected: &str,
found: &Token,
position: Position,
) -> Self::Error {
LLevError::with_position(
LLevErrorKind::InvalidPattern(format!("expected {}, got {:?}", expected, found)),
position,
)
}
fn from_lexer_error(&self, err: LLevError) -> Self::Error {
err
}
}