ableos_userland/programs/aidl/src/lexer.rs

112 lines
2.2 KiB
Rust

use std::ops::{Range, Add};
use logos::Logos;
#[derive(Logos, Debug, PartialEq)]
#[logos(skip r"[ \t\n\f]+")]
pub enum Token {
#[token("{")]
LeftBrace,
#[token("}")]
RightBrace,
#[token("(")]
LeftParen,
#[token(")")]
RightParen,
#[token(";")]
Semicolon,
#[token(":")]
Colon,
#[token("<")]
LeftArrow,
#[token(">")]
RightArrow,
#[token(",")]
Comma,
#[token("=")]
Equals,
//#[regex(r#"[A-z]+"#, |lex| lex.slice().parse().ok())]
//Literal(String),
#[regex(r#"[A-z]+"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))]
Ident(Ident),
#[regex("use [a-zA-Z/]+;", |lex| lex.slice().parse().ok())]
Component(String),
#[regex("U[0-9]+", |lex| lex.slice().parse().ok())]
UnsignedType(String),
#[regex("I[0-9]+", |lex| lex.slice().parse().ok())]
SignedType(String),
#[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("Type")]
Type,
#[token("Use")]
Use,
#[regex(r"[A-z]+", |lex| lex.slice().parse().ok())]
Other(String)
}
#[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::{min, max};
Self(min(self.lower(), other.lower())..max(self.upper(), other.upper()))
}
}
impl Add for Span {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
self.concat(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)
}
}