104 lines
2.3 KiB
Rust
104 lines
2.3 KiB
Rust
#[derive(PartialEq, Debug)]
|
|
pub enum IncludeType {
|
|
System(String),
|
|
Local(String),
|
|
}
|
|
|
|
#[derive(PartialEq, Debug, Logos)]
|
|
pub enum Tokens {
|
|
/// A signed integer literal.
|
|
#[regex("[-]?[0-9]+", parse_int, priority = 1)]
|
|
Int(i32),
|
|
|
|
#[regex("[-]?[0-9]+.[0-9]+", float_parse, priority = 2)]
|
|
Float(f32),
|
|
|
|
#[regex(";")]
|
|
SemiColon,
|
|
|
|
#[regex("[A-Za-z][A-Za-z0-9]+", parse_ident, priority = 3)]
|
|
Ident(String),
|
|
|
|
/*
|
|
// FIXME: I don't know how to properly parse this.
|
|
#[regex("\"[A-Za-z0-9]+\"", parse_string, priority = 123)]
|
|
StringLiteral(String),
|
|
*/
|
|
#[regex("#include[ \t]+<[^>]+>", include_parse)]
|
|
Include(IncludeType),
|
|
|
|
#[regex("return")]
|
|
Return,
|
|
|
|
#[token("(")]
|
|
LParen,
|
|
#[token(")")]
|
|
RParen,
|
|
#[token("{")]
|
|
LBrace,
|
|
#[token("}")]
|
|
RBrace,
|
|
|
|
#[regex(r"[ \t\n\f]+", logos::skip)]
|
|
#[error]
|
|
Error,
|
|
}
|
|
|
|
use logos::{Lexer, Logos};
|
|
|
|
fn parse_int(lex: &mut Lexer<Tokens>) -> Option<i32> {
|
|
let slice = lex.slice();
|
|
|
|
let int = slice.parse::<i32>().ok()?;
|
|
|
|
Some(int)
|
|
}
|
|
pub fn float_parse(lex: &mut Lexer<Tokens>) -> Option<f32> {
|
|
let slice = lex.slice();
|
|
|
|
let float = slice.parse::<f32>().ok()?;
|
|
|
|
Some(float)
|
|
}
|
|
|
|
fn include_parse(lex: &mut Lexer<Tokens>) -> Option<IncludeType> {
|
|
let slice = lex.slice();
|
|
let system_include_check = slice.starts_with("#include <");
|
|
|
|
let include = slice.to_string();
|
|
if system_include_check {
|
|
let ret = parse_inner_include(&include, "<", ">");
|
|
|
|
Some(IncludeType::System(ret))
|
|
} else {
|
|
let ret = parse_inner_include(&include, "\"", "\"");
|
|
|
|
Some(IncludeType::Local(ret))
|
|
}
|
|
}
|
|
|
|
fn parse_inner_include(include: &str, opener: &str, closer: &str) -> String {
|
|
let start_bytes = include.find(opener).unwrap_or(0); //index where "pattern" starts
|
|
let end_bytes = include.find(closer).unwrap_or(include.len()); //index where "<" is found
|
|
|
|
let ret = &include[start_bytes + 1..end_bytes];
|
|
|
|
ret.to_string()
|
|
}
|
|
|
|
pub fn parse_ident(lex: &mut Lexer<Tokens>) -> Option<String> {
|
|
let slice = lex.slice();
|
|
|
|
let ident = slice.to_string();
|
|
|
|
Some(ident)
|
|
}
|
|
|
|
pub fn parse_string(lex: &mut Lexer<Tokens>) -> Option<String> {
|
|
let slice = lex.slice();
|
|
|
|
let string = slice.to_string();
|
|
|
|
Some(string)
|
|
}
|