ableos_userland/programs/aidl/src/lexer.rs

174 lines
3.4 KiB
Rust

use std::{
fmt::Display,
ops::{Add, AddAssign, Range},
};
use logos::Logos;
#[derive(Logos, Debug, PartialEq)]
#[logos(skip r"[ \t\n\f]+")]
pub enum Token {
#[token("{")]
LeftCurly,
#[token("}")]
RightCurly,
#[token("(")]
LeftParen,
#[token(")")]
RightParen,
#[token(";")]
Semicolon,
#[token(":")]
Colon,
#[token("<")]
LeftArrow,
#[token(">")]
RightArrow,
#[token(",")]
Comma,
#[token("=")]
Equals,
#[token(".")]
Dot,
// why
#[regex("\"(?s:[^\"\\\\]|\\\\.)*\"", |lex| lex.slice().strip_prefix('"')?.strip_suffix('"').map(ToOwned::to_owned))]
StringLiteral(String),
#[regex(r"'.'", |lex| lex.slice().strip_prefix('\'')?.strip_suffix('\'')?.parse().ok())]
CharLiteral(char),
#[regex(r#"(-)?\d+"#, |lex| lex.slice().parse().ok())]
NumberLiteral(i64),
#[regex(
r"(ptr|u8|i8|u16|i16|u32|i32|u64|i64|f32|f64)",
|lex| NumberSuffix::lexer(lex.slice()).next().and_then(Result::ok)
)]
NumberSuffix(NumberSuffix),
#[regex(r#"[a-zA-Z_][a-zA-Z\d_]*"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))]
Ident(Ident),
#[regex(r"//.*", |lex| lex.slice().parse().ok())]
Comment(String),
}
#[derive(Logos, Debug, PartialEq, Eq)]
pub enum Ident {
#[token("Interface")]
Interface,
#[token("Function")]
Function,
#[token("Constant")]
Constant,
#[token("Structure")]
Structure,
#[token("Alias")]
Alias,
#[token("Enumeration")]
Enumeration,
#[token("Use")]
Use,
#[token("Make")]
Make,
#[token("Takes")]
Takes,
#[token("Returns")]
Returns,
#[token("_")]
Underscore,
#[regex(r"[a-zA-Z_][a-zA-Z\d_]*", |lex| lex.slice().parse().ok())]
Other(String),
}
#[derive(Logos, Debug, PartialEq, Eq)]
pub enum NumberSuffix {
#[token("Ptr")]
Ptr,
#[token("u8")]
U8,
#[token("i8")]
I8,
#[token("u16")]
U16,
#[token("i16")]
I16,
#[token("u32")]
U32,
#[token("i32")]
I32,
#[token("u64")]
U64,
#[token("i64")]
I64,
#[token("f32")]
F32,
#[token("f64")]
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)
}
}