wisp/src/lexer.rs

124 lines
2.4 KiB
Rust

/// This ID is explicitly picked to prevent excessive bloat
pub type ID = u16;
use std::num::ParseIntError;
pub struct Metadata {
pub title: Option<String>,
}
use logos::{Lexer, Logos};
#[derive(Logos, Debug, PartialEq)]
pub enum Token {
// Tokens can be literal strings, of any length.
#[regex(r#"\([a-zA-Z-]+"#, tag_parser)]
Tag(String),
#[token("'")]
Quote,
#[token("(")]
StartParen,
#[token(")")]
EndParen,
#[regex("\"[a-zA-Z ,.!]+\"", strg)]
Strg(String),
#[regex(":[a-zA-Z ,.!]+", kwarg_parse)]
Kwarg(Kwarg),
#[regex("[+-]?[0-9]+", num)]
Num(i64),
#[regex("[+-]?[0-9]*[.]?[0-9]+(?:[eE][+-]?[0-9]+)?", priority = 2, callback = float_parse)]
Float(f64),
#[regex("#[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]", hexa)]
HexaDec(Rgb),
#[error]
#[regex(r"[ \t\n\f]+", logos::skip)]
Error,
}
pub fn lex_string(strn: String) -> Vec<Token> {
let lex = Token::lexer(&strn);
let mut vec = vec![];
for token in lex {
vec.push(token);
}
vec
}
pub fn tag_parser(lex: &mut Lexer<Token>) -> Option<String> {
let mut tag = lex.slice().to_string();
tag.remove(0);
Some(tag)
}
pub fn strg(lex: &mut Lexer<Token>) -> Option<String> {
let mut strg = lex.slice().to_string();
strg.remove(0);
strg.pop();
Some(strg)
}
pub fn float_parse(lex: &mut Lexer<Token>) -> f64 {
let num = lex.slice();
num.parse::<f64>().unwrap()
}
pub fn num(lex: &mut Lexer<Token>) -> i64 {
let num = lex.slice();
let num: Result<i64, ParseIntError> = num.parse::<i64>();
match num {
Ok(num) => num,
Err(err) => {
unreachable!("{}", err)
}
}
}
pub fn kwarg_parse(lex: &mut Lexer<Token>) -> Kwarg {
let mut strg = lex.slice().to_string();
strg.remove(0);
let mut spl = strg.split(" ");
let arg_name = spl.next().unwrap().to_string();
let arg_value = spl.next().unwrap().to_string();
Kwarg {
name: arg_name,
value: arg_value,
}
}
#[derive(Debug, PartialEq)]
pub struct Rgb {
pub red: u8,
pub green: u8,
pub blue: u8,
}
#[derive(Debug, PartialEq)]
pub struct Kwarg {
name: String,
value: String,
}
pub fn hexa(lex: &mut Lexer<Token>) -> Rgb {
let slice = lex.slice();
let rgb = Rgb {
red: slice[0..=1].as_bytes()[0],
green: slice[2..=3].as_bytes()[0],
blue: slice[4..=5].as_bytes()[0],
};
rgb
}