matdb 0.1.0

An experimental embedded SQL-like DBMS
Documentation
use crate::ast::BinOp;

use super::{lexer::Token, Parser, ParserError};

macro_rules! try_consume {
    ($self:expr, $p:pat => $e:expr) => {
        match $self.peek()? {
            $p => {
                let _ = $self.lexer.next().unwrap();
                Ok($e)
            }
            token => Err(ParserError::Unexpected(token)),
        }
    };
}

impl<'a> Parser<'a> {
    pub(super) fn peek(&mut self) -> Result<Token, ParserError> {
        Ok(self
            .lexer
            .peek()
            .ok_or(ParserError::UnexpectedEOF)?
            .clone()
            .map_err(ParserError::LexerError)?
            .item)
    }

    pub(super) fn try_consume_null(&mut self) -> Result<(), ParserError> {
        try_consume!(self, Token::Null => ())
    }

    pub(super) fn try_consume_not(&mut self) -> Result<(), ParserError> {
        try_consume!(self, Token::Not => ())
    }

    pub(super) fn try_consume_arrow(&mut self) -> Result<(), ParserError> {
        try_consume!(self, Token::Arrow => ())
    }

    pub(super) fn try_consume_dot(&mut self) -> Result<(), ParserError> {
        try_consume!(self, Token::Dot => ())
    }

    pub(super) fn try_consume_semi(&mut self) -> Result<(), ParserError> {
        try_consume!(self, Token::Semi => ())
    }

    pub(super) fn try_consume_open_paren(&mut self) -> Result<(), ParserError> {
        try_consume!(self, Token::OpenParen => ())
    }

    pub(super) fn try_consume_close_paren(&mut self) -> Result<(), ParserError> {
        try_consume!(self, Token::CloseParen => ())
    }

    pub(super) fn try_consume_eq(&mut self) -> Result<(), ParserError> {
        try_consume!(self, Token::Eq => ())
    }

    pub(super) fn peek_symbol(&mut self) -> Result<String, ParserError> {
        match self.peek()? {
            Token::Symbol(s) => Ok(s),
            token => Err(ParserError::Unexpected(token)),
        }
    }

    pub(super) fn try_consume_symbol(&mut self) -> Result<String, ParserError> {
        match self.peek()? {
            Token::Symbol(s) => {
                let _ = self.lexer.next().unwrap();
                Ok(s)
            }
            token => Err(ParserError::Unexpected(token)),
        }
    }

    pub(super) fn try_consume_keyword(&mut self, keyword: &str) -> Result<(), ParserError> {
        match self.peek()? {
            Token::Symbol(s) => {
                if s == keyword {
                    let _ = self.lexer.next().unwrap();
                    Ok(())
                } else {
                    Err(ParserError::UnexpectedKeyword(s))
                }
            }
            token => Err(ParserError::Unexpected(token)),
        }
    }

    pub(super) fn try_consume_binary_operator(&mut self) -> Result<BinOp, ParserError> {
        match self.peek()? {
            Token::Eq => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::Eq)
            }
            Token::NEq => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::NEq)
            }
            Token::Gt => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::Gt)
            }
            Token::GtEq => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::GtEq)
            }
            Token::Lt => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::Lt)
            }
            Token::LtEq => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::LtEq)
            }
            Token::And => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::And)
            }
            Token::Or => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::Or)
            }
            Token::Plus => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::Add)
            }
            Token::Minus => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::Sub)
            }
            Token::Star => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::Mul)
            }
            Token::Slash => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::Div)
            }
            Token::Mod => {
                let _ = self.lexer.next().unwrap();
                Ok(BinOp::Mod)
            }
            token => Err(ParserError::Unexpected(token)),
        }
    }
}