use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[allow(non_camel_case_types)]
pub enum TokenType {
EOF,
SPACE,
TAB,
NEWLINE,
CR,
FORM_FEED,
NOT,
AND,
OR,
BETWEEN,
LIKE,
ESCAPE,
IN,
IS,
TRUE,
FALSE,
NULL,
EQ,
NE,
GT,
GE,
LT,
LE,
LPAREN,
COMMA,
RPAREN,
PLUS,
MINUS,
STAR,
SLASH,
PERCENT,
LINE_COMMENT,
BLOCK_COMMENT,
DECIMAL_LITERAL,
HEX_LITERAL,
OCTAL_LITERAL,
FLOATING_POINT_LITERAL,
STRING_LITERAL,
ID,
INVALID,
}
impl fmt::Display for TokenType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TokenType::EOF => write!(f, "EOF"),
TokenType::SPACE => write!(f, "SPACE"),
TokenType::TAB => write!(f, "TAB"),
TokenType::NEWLINE => write!(f, "NEWLINE"),
TokenType::CR => write!(f, "CR"),
TokenType::FORM_FEED => write!(f, "FORM_FEED"),
TokenType::NOT => write!(f, "NOT"),
TokenType::AND => write!(f, "AND"),
TokenType::OR => write!(f, "OR"),
TokenType::BETWEEN => write!(f, "BETWEEN"),
TokenType::LIKE => write!(f, "LIKE"),
TokenType::ESCAPE => write!(f, "ESCAPE"),
TokenType::IN => write!(f, "IN"),
TokenType::IS => write!(f, "IS"),
TokenType::TRUE => write!(f, "TRUE"),
TokenType::FALSE => write!(f, "FALSE"),
TokenType::NULL => write!(f, "NULL"),
TokenType::EQ => write!(f, "="),
TokenType::NE => write!(f, "<>"),
TokenType::GT => write!(f, ">"),
TokenType::GE => write!(f, ">="),
TokenType::LT => write!(f, "<"),
TokenType::LE => write!(f, "<="),
TokenType::LPAREN => write!(f, "("),
TokenType::COMMA => write!(f, ","),
TokenType::RPAREN => write!(f, ")"),
TokenType::PLUS => write!(f, "+"),
TokenType::MINUS => write!(f, "-"),
TokenType::STAR => write!(f, "*"),
TokenType::SLASH => write!(f, "/"),
TokenType::PERCENT => write!(f, "%"),
TokenType::LINE_COMMENT => write!(f, "LINE_COMMENT"),
TokenType::BLOCK_COMMENT => write!(f, "BLOCK_COMMENT"),
TokenType::DECIMAL_LITERAL => write!(f, "DECIMAL_LITERAL"),
TokenType::HEX_LITERAL => write!(f, "HEX_LITERAL"),
TokenType::OCTAL_LITERAL => write!(f, "OCTAL_LITERAL"),
TokenType::FLOATING_POINT_LITERAL => write!(f, "FLOATING_POINT_LITERAL"),
TokenType::STRING_LITERAL => write!(f, "STRING_LITERAL"),
TokenType::ID => write!(f, "ID"),
TokenType::INVALID => write!(f, "INVALID"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum LexicalState {
DEFAULT,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Token {
pub token_type: TokenType,
pub image: String,
pub begin_offset: usize,
pub end_offset: usize,
pub next: Option<usize>,
pub previous: Option<usize>,
}
impl Token {
pub fn new(
token_type: TokenType,
image: String,
begin_offset: usize,
end_offset: usize,
) -> Self {
Token {
token_type,
image,
begin_offset,
end_offset,
next: None,
previous: None,
}
}
pub fn len(&self) -> usize {
self.end_offset.saturating_sub(self.begin_offset)
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn is_type(&self, token_type: TokenType) -> bool {
self.token_type == token_type
}
pub fn is_one_of(&self, types: &[TokenType]) -> bool {
types.contains(&self.token_type)
}
}
impl fmt::Display for Token {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: \"{}\"", self.token_type, self.image)
}
}
pub trait TokenSource {
fn get_line_from_offset(&self, offset: usize) -> usize;
fn get_column_from_offset(&self, offset: usize) -> usize;
}