Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions lrlex/src/lib/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub struct LexBuildError {
impl Error for LexBuildError {}

/// The various different possible Lex parser errors.
#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum LexErrorKind {
PrematureEnd,
Expand All @@ -59,13 +59,37 @@ pub enum LexErrorKind {
InvalidStartState,
InvalidStartStateName,
DuplicateName,
RegexError,
RegexError(regex::Error),
InvalidGrmtoolsSectionValue,
InvalidNumber,
DuplicateGrmtoolsSectionValue,
VerbatimNotSupported,
}

impl LexErrorKind {
fn is_same_kind(&self, other: &Self) -> bool {
use LexErrorKind as EK;
match (self, other) {
(EK::PrematureEnd, EK::PrematureEnd)
| (EK::RoutinesNotSupported, EK::RoutinesNotSupported)
| (EK::UnknownDeclaration, EK::UnknownDeclaration)
| (EK::MissingSpace, EK::MissingSpace)
| (EK::InvalidName, EK::InvalidName)
| (EK::UnknownStartState, EK::UnknownStartState)
| (EK::DuplicateStartState, EK::DuplicateStartState)
| (EK::InvalidStartState, EK::InvalidStartState)
| (EK::InvalidStartStateName, EK::InvalidStartStateName)
| (EK::DuplicateName, EK::DuplicateName)
| (EK::InvalidGrmtoolsSectionValue, EK::InvalidGrmtoolsSectionValue)
| (EK::InvalidNumber, EK::InvalidNumber)
| (EK::DuplicateGrmtoolsSectionValue, EK::DuplicateGrmtoolsSectionValue)
| (EK::RegexError(_), EK::RegexError(_))
| (EK::VerbatimNotSupported, EK::VerbatimNotSupported) => true,
_ => false,
}
}
}

impl Spanned for LexBuildError {
fn spans(&self) -> &[Span] {
self.spans.as_slice()
Expand All @@ -84,7 +108,7 @@ impl Spanned for LexBuildError {
| LexErrorKind::InvalidGrmtoolsSectionValue
| LexErrorKind::InvalidNumber
| LexErrorKind::VerbatimNotSupported
| LexErrorKind::RegexError => SpansKind::Error,
| LexErrorKind::RegexError(_) => SpansKind::Error,
LexErrorKind::DuplicateName
| LexErrorKind::DuplicateStartState
| LexErrorKind::DuplicateGrmtoolsSectionValue => SpansKind::DuplicationError,
Expand All @@ -94,7 +118,7 @@ impl Spanned for LexBuildError {

impl fmt::Display for LexBuildError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self.kind {
let s = match &self.kind {
LexErrorKind::VerbatimNotSupported => "Verbatim code not supported",
LexErrorKind::PrematureEnd => "File ends prematurely",
LexErrorKind::RoutinesNotSupported => "Routines not currently supported",
Expand All @@ -109,7 +133,7 @@ impl fmt::Display for LexBuildError {
LexErrorKind::InvalidNumber => "Invalid number",
LexErrorKind::DuplicateGrmtoolsSectionValue => "Duplicate grmtools section value",
LexErrorKind::DuplicateName => "Rule name already exists",
LexErrorKind::RegexError => "Invalid regular expression",
LexErrorKind::RegexError(e) => return write!(f, "Invalid regular expression: {e}"),
};
write!(f, "{s}")
}
Expand Down
36 changes: 19 additions & 17 deletions lrlex/src/lib/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn add_duplicate_occurrence(
dup_span: Span,
) {
if !errs.iter_mut().any(|e| {
if e.kind == kind && e.spans[0] == orig_span {
if e.kind.is_same_kind(&kind) && e.spans[0] == orig_span {
e.spans.push(dup_span);
true
} else {
Expand Down Expand Up @@ -618,7 +618,7 @@ where
target_state,
&self.lex_flags,
)
.map_err(|_| self.mk_error(LexErrorKind::RegexError, i))?;
.map_err(|e| self.mk_error(LexErrorKind::RegexError(e), i))?;
self.rules.push(rule);
}
Ok(i + line_len)
Expand Down Expand Up @@ -864,7 +864,7 @@ mod test {
.expect_err("Parsed ok while expecting error");
assert_eq!(errs.len(), 1);
let e = &errs[0];
assert_eq!(e.kind, kind);
assert!(e.kind.is_same_kind(&kind));
assert_eq!(
e.spans()
.iter()
Expand Down Expand Up @@ -892,20 +892,22 @@ mod test {
}
}

assert_eq!(
errs.iter()
.map(|e| {
(
e.kind.clone(),
e.spans()
.iter()
.map(|span| line_col!(src, span))
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
expected.collect::<Vec<_>>()
);
for ((ek1, es1), (ek2, es2)) in errs
.iter()
.map(|e| {
(
e.kind.clone(),
e.spans()
.iter()
.map(|span| line_col!(src, span))
.collect::<Vec<_>>(),
)
})
.zip(expected)
{
assert!(ek1.is_same_kind(&ek2));
assert_eq!(es1, es2);
}
}
}

Expand Down