#![allow(clippy::new_without_default)]
#![allow(clippy::type_complexity)]
#![allow(clippy::unnecessary_wraps)]
#![allow(clippy::upper_case_acronyms)]
#![forbid(unsafe_code)]
#![deny(unreachable_pub)]
use std::{error::Error, fmt};
mod ctbuilder;
#[doc(hidden)]
pub mod defaults;
mod lexer;
mod parser;
pub use crate::{
ctbuilder::{ct_token_map, CTLexer, CTLexerBuilder, LexerKind, RustEdition, Visibility},
defaults::{DefaultLexeme, DefaultLexerTypes},
lexer::{
LRNonStreamingLexer, LRNonStreamingLexerDef, LexerDef, RegexOptions, Rule,
DEFAULT_REGEX_OPTIONS,
},
parser::StartState,
parser::StartStateOperation,
};
use cfgrammar::yacc::parser::SpansKind;
use cfgrammar::{Span, Spanned};
pub type LexBuildResult<T> = Result<T, Vec<LexBuildError>>;
#[derive(Debug)]
pub struct LexBuildError {
pub(crate) kind: LexErrorKind,
pub(crate) spans: Vec<Span>,
}
impl Error for LexBuildError {}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum LexErrorKind {
PrematureEnd,
RoutinesNotSupported,
UnknownDeclaration,
MissingSpace,
InvalidName,
UnknownStartState,
DuplicateStartState,
InvalidStartState,
InvalidStartStateName,
DuplicateName,
RegexError,
VerbatimNotSupported,
}
impl Spanned for LexBuildError {
fn spans(&self) -> &[Span] {
self.spans.as_slice()
}
fn spanskind(&self) -> SpansKind {
match self.kind {
LexErrorKind::PrematureEnd
| LexErrorKind::RoutinesNotSupported
| LexErrorKind::UnknownDeclaration
| LexErrorKind::MissingSpace
| LexErrorKind::InvalidName
| LexErrorKind::UnknownStartState
| LexErrorKind::InvalidStartState
| LexErrorKind::InvalidStartStateName
| LexErrorKind::VerbatimNotSupported
| LexErrorKind::RegexError => SpansKind::Error,
LexErrorKind::DuplicateName | LexErrorKind::DuplicateStartState => {
SpansKind::DuplicationError
}
}
}
}
impl fmt::Display for LexBuildError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self.kind {
LexErrorKind::VerbatimNotSupported => "Verbatim code not supported",
LexErrorKind::PrematureEnd => "File ends prematurely",
LexErrorKind::RoutinesNotSupported => "Routines not currently supported",
LexErrorKind::UnknownDeclaration => "Unknown declaration",
LexErrorKind::MissingSpace => "Rule is missing a space",
LexErrorKind::InvalidName => "Invalid rule name",
LexErrorKind::UnknownStartState => "Start state not known",
LexErrorKind::DuplicateStartState => "Start state already exists",
LexErrorKind::InvalidStartState => "Invalid start state",
LexErrorKind::InvalidStartStateName => "Invalid start state name",
LexErrorKind::DuplicateName => "Rule name already exists",
LexErrorKind::RegexError => "Invalid regular expression",
};
write!(f, "{s}")
}
}
#[derive(Copy, Clone, Debug)]
pub struct StartStateId {
_id: usize,
}
impl StartStateId {
fn new(id: usize) -> Self {
Self { _id: id }
}
}
#[derive(Clone, Debug)]
pub struct LRLexError {
span: Span,
lexing_state: Option<StartStateId>,
}
impl lrpar::LexError for LRLexError {
fn span(&self) -> Span {
self.span
}
}
impl LRLexError {
pub fn new(span: Span) -> Self {
LRLexError {
span,
lexing_state: None,
}
}
pub fn new_with_lexing_state(span: Span, lexing_state: StartStateId) -> Self {
LRLexError {
span,
lexing_state: Some(lexing_state),
}
}
pub fn lexing_state(&self) -> Option<StartStateId> {
self.lexing_state
}
}
impl Error for LRLexError {}
impl fmt::Display for LRLexError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"Couldn't lex input starting at byte {}",
self.span.start()
)
}
}
#[deprecated(
since = "0.8.0",
note = "This struct has been renamed to LRNonStreamingLexerDef"
)]
pub type NonStreamingLexerDef<StorageT> = LRNonStreamingLexerDef<StorageT>;
#[macro_export]
macro_rules! lrlex_mod {
($path:expr) => {
include!(concat!(env!("OUT_DIR"), "/", $path, ".rs"));
};
}