ableos_userland/programs/aidl/src/lexer.rs

233 lines
4.9 KiB
Rust

use std::{
fmt::Display,
ops::{Add, AddAssign, Range},
};
use logos::Logos;
#[derive(Logos, Debug, PartialEq, derive_more::Display, Clone)]
#[logos(skip r"[ \t\n\f]+")]
pub enum Token {
#[token("{")]
#[display(fmt = "{{")]
LeftCurly,
#[token("}")]
#[display(fmt = "}}")]
RightCurly,
#[token("(")]
#[display(fmt = "(")]
LeftParen,
#[token(")")]
#[display(fmt = ")")]
RightParen,
#[token(";")]
#[display(fmt = ";")]
Semicolon,
#[token(":")]
#[display(fmt = ":")]
Colon,
#[token("<")]
#[display(fmt = "<")]
LeftArrow,
#[token(">")]
#[display(fmt = ">")]
RightArrow,
#[token(",")]
#[display(fmt = ",")]
Comma,
#[token("=")]
#[display(fmt = "=")]
Equals,
#[token(".")]
#[display(fmt = ".")]
Dot,
// why
#[regex("\"(?s:[^\"\\\\]|\\\\.)*\"", |lex| lex.slice().strip_prefix('"')?.strip_suffix('"').map(ToOwned::to_owned))]
#[display(fmt = "\"{_0}\"")]
StringLiteral(String),
#[regex(r"'.'", |lex| lex.slice().strip_prefix('\'')?.strip_suffix('\'')?.parse().ok())]
#[display(fmt = "{_0}")]
CharLiteral(char),
#[regex(r#"(-)?\d+"#, |lex| lex.slice().parse().ok())]
#[display(fmt = "{_0}")]
NumberLiteral(i64),
#[regex(
"(ptr|u8|i8|u16|i16|u32|i32|u64|i64|f32|f64)",
|lex| NumberSuffix::lexer(lex.slice()).next().and_then(Result::ok)
)]
#[display(fmt = "{_0}")]
NumberSuffix(NumberSuffix),
#[regex(r#"[a-zA-Z_][a-zA-Z\d_]*"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))]
#[display(fmt = "{_0}")]
Ident(Ident),
#[regex(r"//.*", |lex| lex.slice().parse().ok())]
#[display(fmt = "//{_0}")]
Comment(String),
}
#[derive(Logos, Debug, Clone, PartialEq, Eq, derive_more::Display)]
pub enum Ident {
#[token("Module")]
#[display(fmt = "Module")]
Module,
#[token("Interface")]
#[display(fmt = "Interface")]
Interface,
#[token("Function")]
#[display(fmt = "Function")]
Function,
#[token("Constant")]
#[display(fmt = "Constant")]
Constant,
#[token("Structure")]
#[display(fmt = "Structure")]
Structure,
#[token("Alias")]
#[display(fmt = "Alias")]
Alias,
#[token("Enumeration")]
#[display(fmt = "Enumeration")]
Enumeration,
#[token("Use")]
#[display(fmt = "Use")]
Use,
#[token("Make")]
#[display(fmt = "Make")]
Make,
#[token("Takes")]
#[display(fmt = "Takes")]
Takes,
#[token("Returns")]
#[display(fmt = "Returns")]
Returns,
#[token("_")]
#[display(fmt = "_")]
Underscore,
#[regex(r"[a-zA-Z_][a-zA-Z\d_]*", |lex| lex.slice().parse().ok())]
#[display(fmt = "{_0}")]
Other(String),
}
#[derive(Logos, Debug, Clone, Copy, PartialEq, Eq, derive_more::Display)]
pub enum NumberSuffix {
#[token("ptr")]
#[display(fmt = "ptr")]
Ptr,
#[token("u8")]
#[display(fmt = "u8")]
U8,
#[token("i8")]
#[display(fmt = "i8")]
I8,
#[token("u16")]
#[display(fmt = "u16")]
U16,
#[token("i16")]
#[display(fmt = "i16")]
I16,
#[token("u32")]
#[display(fmt = "u32")]
U32,
#[token("i32")]
#[display(fmt = "i32")]
I32,
#[token("u64")]
#[display(fmt = "u64")]
U64,
#[token("i64")]
#[display(fmt = "i64")]
I64,
#[token("f32")]
#[display(fmt = "f32")]
F32,
#[token("f64")]
#[display(fmt = "f64")]
F64,
}
impl NumberSuffix {
pub const ALL_SUFFIXES: [&str; 11] = [
"ptr",
"u8",
"i8",
"u16",
"i16",
"u32",
"i32",
"u64",
"i64",
"f32",
"f64"
];
}
#[derive(Debug, Clone)]
pub struct Span(pub Range<usize>);
impl Span {
pub const ZERO: Self = Self(0..0);
pub fn lower(&self) -> usize {
self.0.start
}
pub fn upper(&self) -> usize {
self.0.end
}
pub fn concat(self, other: Span) -> Self {
use std::cmp::{max, min};
Self(min(self.lower(), other.lower())..max(self.upper(), other.upper()))
}
}
impl Display for Span {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}..{}", self.lower(), self.upper())
}
}
impl Add for Span {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
self.concat(rhs)
}
}
impl AddAssign for Span {
fn add_assign(&mut self, rhs: Self) {
*self = self.clone() + rhs;
}
}
#[derive(Debug, Clone)]
pub struct Spanned<T>(pub T, pub Span);
impl<T> Spanned<T> {
pub fn new<const N: usize>(thing: T, spans: [Span; N]) -> Self {
Self(thing, spans.into_iter().fold(Span::ZERO, Span::concat))
}
pub fn map<R>(self, f: impl Fn(T) -> R) -> Spanned<R> {
Spanned(f(self.0), self.1)
}
}
impl<T: Display> Display for Spanned<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} @ {}", self.0, self.1)
}
}