ableos_userland/programs/aidl/src/lexer.rs

233 lines
4.9 KiB
Rust
Raw Normal View History

2023-05-04 13:51:31 +00:00
use std::{
fmt::Display,
2023-05-05 11:21:24 +00:00
ops::{Add, AddAssign, Range},
2023-05-04 13:51:31 +00:00
};
2023-05-04 11:19:32 +00:00
use logos::Logos;
2023-05-05 14:15:38 +00:00
#[derive(Logos, Debug, PartialEq, derive_more::Display, Clone)]
2023-05-04 11:19:32 +00:00
#[logos(skip r"[ \t\n\f]+")]
pub enum Token {
#[token("{")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "{{")]
2023-05-04 17:31:20 +00:00
LeftCurly,
2023-05-04 11:19:32 +00:00
#[token("}")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "}}")]
2023-05-04 17:31:20 +00:00
RightCurly,
2023-05-04 11:19:32 +00:00
#[token("(")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "(")]
2023-05-04 11:19:32 +00:00
LeftParen,
#[token(")")]
2023-05-05 14:15:38 +00:00
#[display(fmt = ")")]
2023-05-04 11:19:32 +00:00
RightParen,
#[token(";")]
2023-05-05 14:15:38 +00:00
#[display(fmt = ";")]
2023-05-04 11:19:32 +00:00
Semicolon,
#[token(":")]
2023-05-05 14:15:38 +00:00
#[display(fmt = ":")]
2023-05-04 11:19:32 +00:00
Colon,
#[token("<")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "<")]
2023-05-04 11:19:32 +00:00
LeftArrow,
#[token(">")]
2023-05-05 14:15:38 +00:00
#[display(fmt = ">")]
2023-05-04 11:19:32 +00:00
RightArrow,
#[token(",")]
2023-05-05 14:15:38 +00:00
#[display(fmt = ",")]
2023-05-04 11:19:32 +00:00
Comma,
#[token("=")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "=")]
2023-05-04 11:19:32 +00:00
Equals,
2023-05-04 13:47:05 +00:00
#[token(".")]
2023-05-05 14:15:38 +00:00
#[display(fmt = ".")]
2023-05-04 13:47:05 +00:00
Dot,
2023-05-04 11:19:32 +00:00
2023-05-04 16:50:17 +00:00
// why
2023-05-04 17:31:20 +00:00
#[regex("\"(?s:[^\"\\\\]|\\\\.)*\"", |lex| lex.slice().strip_prefix('"')?.strip_suffix('"').map(ToOwned::to_owned))]
2023-05-05 14:15:38 +00:00
#[display(fmt = "\"{_0}\"")]
2023-05-04 16:50:17 +00:00
StringLiteral(String),
#[regex(r"'.'", |lex| lex.slice().strip_prefix('\'')?.strip_suffix('\'')?.parse().ok())]
2023-05-05 14:15:38 +00:00
#[display(fmt = "{_0}")]
2023-05-04 16:50:17 +00:00
CharLiteral(char),
#[regex(r#"(-)?\d+"#, |lex| lex.slice().parse().ok())]
2023-05-05 14:15:38 +00:00
#[display(fmt = "{_0}")]
2023-05-04 16:50:17 +00:00
NumberLiteral(i64),
2023-05-05 11:21:24 +00:00
#[regex(
2023-05-05 14:15:38 +00:00
"(ptr|u8|i8|u16|i16|u32|i32|u64|i64|f32|f64)",
2023-05-05 11:21:24 +00:00
|lex| NumberSuffix::lexer(lex.slice()).next().and_then(Result::ok)
)]
2023-05-05 14:15:38 +00:00
#[display(fmt = "{_0}")]
2023-05-04 16:50:17 +00:00
NumberSuffix(NumberSuffix),
2023-05-04 13:47:05 +00:00
#[regex(r#"[a-zA-Z_][a-zA-Z\d_]*"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))]
2023-05-05 14:15:38 +00:00
#[display(fmt = "{_0}")]
2023-05-04 13:47:05 +00:00
Ident(Ident),
2023-05-04 11:19:32 +00:00
#[regex(r"//.*", |lex| lex.slice().parse().ok())]
2023-05-05 14:15:38 +00:00
#[display(fmt = "//{_0}")]
2023-05-04 11:19:32 +00:00
Comment(String),
}
2023-05-05 14:15:38 +00:00
#[derive(Logos, Debug, Clone, PartialEq, Eq, derive_more::Display)]
2023-05-04 11:19:32 +00:00
pub enum Ident {
2023-05-06 15:57:45 +00:00
#[token("Module")]
#[display(fmt = "Module")]
Module,
2023-05-04 11:19:32 +00:00
#[token("Interface")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Interface")]
2023-05-04 11:19:32 +00:00
Interface,
#[token("Function")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Function")]
2023-05-04 11:19:32 +00:00
Function,
#[token("Constant")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Constant")]
2023-05-04 11:19:32 +00:00
Constant,
#[token("Structure")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Structure")]
2023-05-04 11:19:32 +00:00
Structure,
2023-05-04 12:44:49 +00:00
#[token("Alias")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Alias")]
2023-05-04 12:44:49 +00:00
Alias,
2023-05-05 11:21:24 +00:00
#[token("Enumeration")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Enumeration")]
2023-05-05 11:21:24 +00:00
Enumeration,
2023-05-04 11:19:32 +00:00
#[token("Use")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Use")]
2023-05-04 11:19:32 +00:00
Use,
2023-05-04 17:31:20 +00:00
#[token("Make")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Make")]
2023-05-04 17:31:20 +00:00
Make,
2023-05-05 11:21:24 +00:00
#[token("Takes")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Takes")]
2023-05-05 11:21:24 +00:00
Takes,
#[token("Returns")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "Returns")]
2023-05-05 11:21:24 +00:00
Returns,
#[token("_")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "_")]
2023-05-05 11:21:24 +00:00
Underscore,
2023-05-04 16:50:17 +00:00
#[regex(r"[a-zA-Z_][a-zA-Z\d_]*", |lex| lex.slice().parse().ok())]
2023-05-05 14:15:38 +00:00
#[display(fmt = "{_0}")]
2023-05-04 13:51:31 +00:00
Other(String),
2023-05-04 11:19:32 +00:00
}
2023-05-05 14:15:38 +00:00
#[derive(Logos, Debug, Clone, Copy, PartialEq, Eq, derive_more::Display)]
2023-05-04 16:50:17 +00:00
pub enum NumberSuffix {
2023-05-05 14:15:38 +00:00
#[token("ptr")]
#[display(fmt = "ptr")]
2023-05-04 16:50:17 +00:00
Ptr,
#[token("u8")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "u8")]
2023-05-04 16:50:17 +00:00
U8,
#[token("i8")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "i8")]
2023-05-04 16:50:17 +00:00
I8,
#[token("u16")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "u16")]
2023-05-04 16:50:17 +00:00
U16,
#[token("i16")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "i16")]
2023-05-04 16:50:17 +00:00
I16,
#[token("u32")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "u32")]
2023-05-04 16:50:17 +00:00
U32,
#[token("i32")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "i32")]
2023-05-04 16:50:17 +00:00
I32,
#[token("u64")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "u64")]
2023-05-04 16:50:17 +00:00
U64,
#[token("i64")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "i64")]
2023-05-04 16:50:17 +00:00
I64,
#[token("f32")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "f32")]
2023-05-04 16:50:17 +00:00
F32,
#[token("f64")]
2023-05-05 14:15:38 +00:00
#[display(fmt = "f64")]
2023-05-04 16:50:17 +00:00
F64,
}
2023-05-05 14:15:38 +00:00
impl NumberSuffix {
pub const ALL_SUFFIXES: [&str; 11] = [
"ptr",
"u8",
"i8",
"u16",
"i16",
"u32",
"i32",
"u64",
"i64",
"f32",
"f64"
];
}
2023-05-04 11:19:32 +00:00
#[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 {
2023-05-04 13:51:31 +00:00
use std::cmp::{max, min};
2023-05-04 11:19:32 +00:00
Self(min(self.lower(), other.lower())..max(self.upper(), other.upper()))
}
}
2023-05-04 12:44:49 +00:00
impl Display for Span {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}..{}", self.lower(), self.upper())
}
}
2023-05-04 11:19:32 +00:00
impl Add for Span {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
2023-05-04 13:51:31 +00:00
self.concat(rhs)
2023-05-04 11:19:32 +00:00
}
}
2023-05-04 17:31:20 +00:00
impl AddAssign for Span {
fn add_assign(&mut self, rhs: Self) {
*self = self.clone() + rhs;
}
}
2023-05-04 11:19:32 +00:00
#[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)
}
}
2023-05-04 12:44:49 +00:00
impl<T: Display> Display for Spanned<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} @ {}", self.0, self.1)
}
}