#![allow(clippy::len_without_is_empty)]
use std::{cmp, error::Error, fmt, hash::Hash, marker};
use cfgrammar::Span;
use num_traits::{AsPrimitive, PrimInt, Unsigned};
pub trait LexerTypes: fmt::Debug
where
usize: AsPrimitive<Self::StorageT>,
{
type LexemeT: Lexeme<Self::StorageT>;
type StorageT: 'static + fmt::Debug + Hash + PrimInt + Unsigned;
type LexErrorT: LexError;
}
pub trait Lexer<LexerTypesT: LexerTypes>
where
usize: AsPrimitive<LexerTypesT::StorageT>,
{
fn iter<'a>(
&'a self,
) -> Box<dyn Iterator<Item = Result<LexerTypesT::LexemeT, LexerTypesT::LexErrorT>> + 'a>;
}
pub trait NonStreamingLexer<'input, LexerTypesT: LexerTypes>: Lexer<LexerTypesT>
where
usize: AsPrimitive<LexerTypesT::StorageT>,
{
fn span_str(&self, span: Span) -> &'input str;
fn span_lines_str(&self, span: Span) -> &'input str;
fn line_col(&self, span: Span) -> ((usize, usize), (usize, usize));
}
pub trait Lexeme<StorageT>: fmt::Debug + fmt::Display + cmp::Eq + Hash + marker::Copy {
fn new(tok_id: StorageT, start: usize, len: usize) -> Self
where
Self: Sized;
fn new_faulty(tok_id: StorageT, start: usize, len: usize) -> Self
where
Self: Sized;
fn tok_id(&self) -> StorageT;
fn span(&self) -> Span;
fn faulty(&self) -> bool;
}
pub trait LexError: Error {
fn span(&self) -> Span;
}