make ParserError a struct with an enum kind field

This commit is contained in:
Skgland
2026-01-24 03:24:02 +01:00
committed by Bennet Bleßmann
parent bd233fedfd
commit 18b476af28
6 changed files with 120 additions and 131 deletions

View File

@@ -1952,7 +1952,7 @@ impl MachineState {
) -> Result<Stream, ParserError> { ) -> Result<Stream, ParserError> {
match stream.peek_char() { match stream.peek_char() {
None => Ok(stream), // empty stream is handled gracefully by Lexer::eof None => Ok(stream), // empty stream is handled gracefully by Lexer::eof
Some(Err(e)) => Err(ParserError::IO(e)), Some(Err(e)) => Err(ParserError::from(e)),
Some(Ok(c)) => { Some(Ok(c)) => {
if c == '\u{feff}' { if c == '\u{feff}' {
// skip UTF-8 BOM // skip UTF-8 BOM

View File

@@ -1016,7 +1016,7 @@ impl MachineState {
self.unify_fixnum(n, nx); self.unify_fixnum(n, nx);
} }
_ => { _ => {
let err = ParserError::ParseBigInt(parser.lexer.location.clone()); let err = parser.lexer.parse_big_int_error();
let err = self.syntax_error(err); let err = self.syntax_error(err);
return Err(self.error_form(err, stub_gen())); return Err(self.error_form(err, stub_gen()));
@@ -1026,7 +1026,7 @@ impl MachineState {
return Ok(()); return Ok(());
} }
Ok(c) => { Ok(c) => {
let err = ParserError::UnexpectedChar(c, lexer.location); let err = lexer.unexpected_char(c);
let err = self.syntax_error(err); let err = self.syntax_error(err);
return Err(self.error_form(err, stub_gen())); return Err(self.error_form(err, stub_gen()));

View File

@@ -447,71 +447,71 @@ impl Location {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug)] #[derive(Debug)]
pub enum ParserError { pub struct ParserError {
BackQuotedString(Location), pub(crate) location: Option<Location>,
pub(crate) kind: ParserErrorKind,
}
#[allow(dead_code)]
#[derive(Debug)]
#[non_exhaustive]
pub enum ParserErrorKind {
BackQuotedString,
IO(IOError), IO(IOError),
IncompleteReduction(Location), IncompleteReduction,
InfiniteFloat(Location), InfiniteFloat,
InvalidSingleQuotedCharacter(char, Location), InvalidSingleQuotedCharacter(char),
LexicalError(lexical::Error), LexicalError(lexical::Error),
MissingQuote(Location), MissingQuote,
NonPrologChar(Location), NonPrologChar,
ParseBigInt(Location), ParseBigInt,
UnexpectedChar(char, Location), UnexpectedChar(char),
// UnexpectedEOF, // UnexpectedEOF,
Utf8Error(Option<Location>), Utf8Error,
} }
impl ParserError { impl ParserError {
pub fn location(&self) -> Option<Location> { pub fn location(&self) -> Option<Location> {
match self { self.location.as_ref().cloned()
ParserError::BackQuotedString(location)
| ParserError::InvalidSingleQuotedCharacter(_, location)
| ParserError::IncompleteReduction(location)
| ParserError::InfiniteFloat(location)
| ParserError::MissingQuote(location)
| ParserError::NonPrologChar(location)
| ParserError::ParseBigInt(location)
| ParserError::UnexpectedChar(_, location) => Some(location.clone()),
ParserError::Utf8Error(location) => location.as_ref().cloned(),
ParserError::IO(_) | ParserError::LexicalError(_) => None,
}
} }
pub fn as_atom(&self) -> Atom { pub fn as_atom(&self) -> Atom {
match self { match &self.kind {
ParserError::BackQuotedString(..) => atom!("back_quoted_string"), ParserErrorKind::BackQuotedString => atom!("back_quoted_string"),
ParserError::IncompleteReduction(..) => atom!("incomplete_reduction"), ParserErrorKind::IncompleteReduction => atom!("incomplete_reduction"),
ParserError::InvalidSingleQuotedCharacter(..) => { ParserErrorKind::InvalidSingleQuotedCharacter(..) => {
atom!("invalid_single_quoted_character") atom!("invalid_single_quoted_character")
} }
ParserError::InfiniteFloat(..) => { ParserErrorKind::InfiniteFloat => {
atom!("infinite_float") atom!("infinite_float")
} }
ParserError::IO(e) if e.kind() == ErrorKind::UnexpectedEof => { ParserErrorKind::IO(e) if e.kind() == ErrorKind::UnexpectedEof => {
atom!("unexpected_end_of_file") atom!("unexpected_end_of_file")
} }
ParserError::IO(e) if e.kind() == ErrorKind::InvalidData => { ParserErrorKind::IO(e) if e.kind() == ErrorKind::InvalidData => {
atom!("invalid_data") atom!("invalid_data")
} }
ParserError::IO(_) => atom!("input_output_error"), ParserErrorKind::IO(_) => atom!("input_output_error"),
ParserError::LexicalError(_) => atom!("lexical_error"), ParserErrorKind::LexicalError(_) => atom!("lexical_error"),
ParserError::MissingQuote(..) => atom!("missing_quote"), ParserErrorKind::MissingQuote => atom!("missing_quote"),
ParserError::NonPrologChar(..) => atom!("non_prolog_character"), ParserErrorKind::NonPrologChar => atom!("non_prolog_character"),
ParserError::ParseBigInt(..) => atom!("cannot_parse_big_int"), ParserErrorKind::ParseBigInt => atom!("cannot_parse_big_int"),
ParserError::UnexpectedChar(..) => atom!("unexpected_char"), ParserErrorKind::UnexpectedChar(..) => atom!("unexpected_char"),
ParserError::Utf8Error(..) => atom!("utf8_conversion_error"), ParserErrorKind::Utf8Error => atom!("utf8_conversion_error"),
} }
} }
#[inline] #[inline]
pub fn unexpected_eof() -> Self { pub fn unexpected_eof() -> Self {
ParserError::IO(std::io::Error::from(ErrorKind::UnexpectedEof)) ParserError {
location: None,
kind: ParserErrorKind::IO(std::io::Error::from(ErrorKind::UnexpectedEof)),
}
} }
#[inline] #[inline]
pub fn is_unexpected_eof(&self) -> bool { pub fn is_unexpected_eof(&self) -> bool {
if let ParserError::IO(e) = self { if let ParserErrorKind::IO(e) = &self.kind {
e.kind() == ErrorKind::UnexpectedEof e.kind() == ErrorKind::UnexpectedEof
} else { } else {
false false
@@ -521,25 +521,18 @@ impl ParserError {
impl From<lexical::Error> for ParserError { impl From<lexical::Error> for ParserError {
fn from(e: lexical::Error) -> ParserError { fn from(e: lexical::Error) -> ParserError {
ParserError::LexicalError(e) ParserError {
location: None,
kind: ParserErrorKind::LexicalError(e),
}
} }
} }
impl From<IOError> for ParserError { impl From<IOError> for ParserError {
fn from(e: IOError) -> ParserError { fn from(e: IOError) -> ParserError {
ParserError::IO(e) ParserError {
} location: None,
} kind: ParserErrorKind::IO(e),
impl From<&IOError> for ParserError {
fn from(error: &IOError) -> ParserError {
if let Some(_utf8_error) = error
.get_ref()
.and_then(|e| e.downcast_ref::<BadUtf8Error>())
{
ParserError::Utf8Error(None)
} else {
ParserError::IO(error.kind().into())
} }
} }
} }

View File

@@ -16,7 +16,10 @@ macro_rules! consume_chars_with {
match $e { match $e {
Ok(Some(c)) => $token.push(c), Ok(Some(c)) => $token.push(c),
Ok(None) => continue, Ok(None) => continue,
Err($crate::parser::ast::ParserError::UnexpectedChar(..)) => break, Err($crate::parser::ast::ParserError {
kind: $crate::parser::ast::ParserErrorKind::UnexpectedChar(..),
..
}) => break,
Err(e) => return Err(e), Err(e) => return Err(e),
} }
} }
@@ -103,6 +106,27 @@ impl<'a, R: fmt::Debug> fmt::Debug for Lexer<'a, R> {
} }
} }
impl<R> Lexer<'_, R> {
pub(crate) fn located_error(&self, kind: ParserErrorKind) -> ParserError {
ParserError {
location: Some(self.location.clone()),
kind,
}
}
pub(crate) fn parse_big_int_error(&self) -> ParserError {
self.located_error(ParserErrorKind::ParseBigInt)
}
pub(crate) fn incomplete_reduction(&self) -> ParserError {
self.located_error(ParserErrorKind::IncompleteReduction)
}
pub(crate) fn unexpected_char(&self, c: char) -> ParserError {
self.located_error(ParserErrorKind::UnexpectedChar(c))
}
}
impl<'a, R: CharRead> Lexer<'a, R> { impl<'a, R: CharRead> Lexer<'a, R> {
pub fn new(src: R, machine_st: &'a mut MachineState) -> Self { pub fn new(src: R, machine_st: &'a mut MachineState) -> Self {
Self { Self {
@@ -197,7 +221,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
match comment_loop() { match comment_loop() {
Err(e) if e.is_unexpected_eof() => { Err(e) if e.is_unexpected_eof() => {
return Err(ParserError::IncompleteReduction(self.location.clone())); return Err(self.incomplete_reduction());
} }
Err(e) => { Err(e) => {
return Err(e); return Err(e);
@@ -209,7 +233,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
self.skip_char(c); self.skip_char(c);
Ok(true) Ok(true)
} else { } else {
Err(ParserError::NonPrologChar(self.location.clone())) Err(self.located_error(ParserErrorKind::NonPrologChar))
} }
} else { } else {
self.return_char('/'); self.return_char('/');
@@ -226,7 +250,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
if !back_quote_char!(c2) { if !back_quote_char!(c2) {
self.return_char(c); self.return_char(c);
Err(ParserError::UnexpectedChar(c, self.location.clone())) Err(self.unexpected_char(c))
} else { } else {
self.skip_char(c2); self.skip_char(c2);
Ok(c2) Ok(c2)
@@ -251,7 +275,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
Ok(None) Ok(None)
} else { } else {
self.return_char(c); self.return_char(c);
Err(ParserError::UnexpectedChar(c, self.location.clone())) Err(self.unexpected_char(c))
} }
} else { } else {
self.get_back_quoted_char().map(Some) self.get_back_quoted_char().map(Some)
@@ -273,10 +297,13 @@ impl<'a, R: CharRead> Lexer<'a, R> {
self.skip_char(c); self.skip_char(c);
Ok(token) Ok(token)
} else { } else {
Err(ParserError::MissingQuote(self.location.clone())) Err({
let this = &self;
this.located_error(ParserErrorKind::MissingQuote)
})
} }
} else { } else {
Err(ParserError::UnexpectedChar(c, self.location.clone())) Err(self.unexpected_char(c))
} }
} }
@@ -307,7 +334,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
if !single_quote_char!(c2) { if !single_quote_char!(c2) {
self.return_char(c); self.return_char(c);
Err(ParserError::UnexpectedChar(c, self.location.clone())) Err(self.unexpected_char(c))
} else { } else {
self.skip_char(c2); self.skip_char(c2);
Ok(c2) Ok(c2)
@@ -348,7 +375,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
if !double_quote_char!(c2) { if !double_quote_char!(c2) {
self.return_char(c); self.return_char(c);
Err(ParserError::UnexpectedChar(c, self.location.clone())) Err(self.unexpected_char(c))
} else { } else {
self.skip_char(c2); self.skip_char(c2);
Ok(c2) Ok(c2)
@@ -372,7 +399,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
't' => '\t', 't' => '\t',
'n' => '\n', 'n' => '\n',
'r' => '\r', 'r' => '\r',
c => return Err(ParserError::UnexpectedChar(c, self.location.clone())), c => return Err(self.unexpected_char(c)),
}; };
self.skip_char(c); self.skip_char(c);
@@ -390,7 +417,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
if hexadecimal_digit_char!(c) { if hexadecimal_digit_char!(c) {
self.escape_sequence_to_char(|c| hexadecimal_digit_char!(c), 16) self.escape_sequence_to_char(|c| hexadecimal_digit_char!(c), 16)
} else { } else {
Err(ParserError::IncompleteReduction(self.location.clone())) Err(self.incomplete_reduction())
} }
} }
@@ -416,14 +443,11 @@ impl<'a, R: CharRead> Lexer<'a, R> {
if backslash_char!(c) { if backslash_char!(c) {
self.skip_char(c); self.skip_char(c);
u32::from_str_radix(&token, radix).map_or_else( u32::from_str_radix(&token, radix).map_or_else(
|_| Err(ParserError::ParseBigInt(self.location.clone())), |_| Err(self.parse_big_int_error()),
|n| { |n| char::try_from(n).map_err(|_| self.located_error(ParserErrorKind::Utf8Error)),
char::try_from(n)
.map_err(|_| ParserError::Utf8Error(Some(self.location.clone())))
},
) )
} else { } else {
Err(ParserError::IncompleteReduction(self.location.clone())) Err(self.incomplete_reduction())
} }
} }
@@ -435,7 +459,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
Ok(c) Ok(c)
} else { } else {
if !backslash_char!(c) { if !backslash_char!(c) {
return Err(ParserError::UnexpectedChar(c, self.location.clone())); return Err(self.unexpected_char(c));
} }
self.skip_char(c); self.skip_char(c);
@@ -466,7 +490,10 @@ impl<'a, R: CharRead> Lexer<'a, R> {
self.skip_char(c); self.skip_char(c);
Ok(token) Ok(token)
} else { } else {
Err(ParserError::MissingQuote(self.location.clone())) Err({
let this = &self;
this.located_error(ParserErrorKind::MissingQuote)
})
} }
} }
@@ -497,7 +524,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
.map(NumberToken::Integer) .map(NumberToken::Integer)
} else { } else {
self.return_char(start); self.return_char(start);
Err(ParserError::ParseBigInt(self.location.clone())) Err(self.parse_big_int_error())
} }
} }
@@ -528,7 +555,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
.map(NumberToken::Integer) .map(NumberToken::Integer)
} else { } else {
self.return_char(start); self.return_char(start);
Err(ParserError::ParseBigInt(self.location.clone())) Err(self.parse_big_int_error())
} }
} }
@@ -559,7 +586,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
.map(NumberToken::Integer) .map(NumberToken::Integer)
} else { } else {
self.return_char(start); self.return_char(start);
Err(ParserError::ParseBigInt(self.location.clone())) Err(self.parse_big_int_error())
} }
} }
@@ -632,14 +659,11 @@ impl<'a, R: CharRead> Lexer<'a, R> {
} }
} }
} else { } else {
return Err(ParserError::InvalidSingleQuotedCharacter( return Err(self.located_error(ParserErrorKind::InvalidSingleQuotedCharacter(c)));
c,
self.location.clone(),
));
} }
} else { } else {
match self.get_back_quoted_string() { match self.get_back_quoted_string() {
Ok(_) => return Err(ParserError::BackQuotedString(self.location.clone())), Ok(_) => return Err(self.located_error(ParserErrorKind::BackQuotedString)),
Err(e) => return Err(e), Err(e) => return Err(e),
} }
} }
@@ -677,7 +701,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
if decimal_digit_char!(c) { if decimal_digit_char!(c) {
Ok(c) Ok(c)
} else { } else {
Err(ParserError::ParseBigInt(self.location.clone())) Err(self.parse_big_int_error())
} }
} else { } else {
Ok(c) Ok(c)
@@ -699,7 +723,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
.or_else(|_| { .or_else(|_| {
Integer::from_str_radix(token, radix) Integer::from_str_radix(token, radix)
.map(|n| GInteger::Integer(arena_alloc!(n, &mut self.machine_st.arena))) .map(|n| GInteger::Integer(arena_alloc!(n, &mut self.machine_st.arena)))
.map_err(|_| ParserError::ParseBigInt(self.location.clone())) .map_err(|_| self.parse_big_int_error())
}) })
} }
@@ -817,7 +841,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
} else if token.starts_with('0') && token.len() == 1 { } else if token.starts_with('0') && token.len() == 1 {
if c == 'x' { if c == 'x' {
self.hexadecimal_constant(c).or_else(|e| { self.hexadecimal_constant(c).or_else(|e| {
if let ParserError::ParseBigInt(..) = e { if let ParserErrorKind::ParseBigInt = e.kind {
self.parse_integer(&token).map(NumberToken::Integer) self.parse_integer(&token).map(NumberToken::Integer)
} else { } else {
Err(e) Err(e)
@@ -825,7 +849,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
}) })
} else if c == 'o' { } else if c == 'o' {
self.octal_constant(c).or_else(|e| { self.octal_constant(c).or_else(|e| {
if let ParserError::ParseBigInt(..) = e { if let ParserErrorKind::ParseBigInt = e.kind {
self.parse_integer(&token).map(NumberToken::Integer) self.parse_integer(&token).map(NumberToken::Integer)
} else { } else {
Err(e) Err(e)
@@ -833,7 +857,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
}) })
} else if c == 'b' { } else if c == 'b' {
self.binary_constant(c).or_else(|e| { self.binary_constant(c).or_else(|e| {
if let ParserError::ParseBigInt(..) = e { if let ParserErrorKind::ParseBigInt = e.kind {
self.parse_integer(&token).map(NumberToken::Integer) self.parse_integer(&token).map(NumberToken::Integer)
} else { } else {
Err(e) Err(e)
@@ -862,9 +886,9 @@ impl<'a, R: CharRead> Lexer<'a, R> {
self.get_single_quoted_char() self.get_single_quoted_char()
.map(|c| NumberToken::Integer(GInteger::Fixnum(Fixnum::build_with(c)))) .map(|c| NumberToken::Integer(GInteger::Fixnum(Fixnum::build_with(c))))
.or_else(|err| { .or_else(|err| {
match err { match &err.kind {
ParserError::UnexpectedChar('\'', ..) => {} ParserErrorKind::UnexpectedChar('\'', ..) => {}
err => return Err(err), _ => return Err(err),
} }
self.return_char(c); self.return_char(c);

View File

@@ -254,7 +254,7 @@ pub fn read_tokens<R: CharRead>(lexer: &mut Lexer<'_, R>) -> Result<Vec<Token>,
} }
} }
Err(e) if e.is_unexpected_eof() && !tokens.is_empty() => { Err(e) if e.is_unexpected_eof() && !tokens.is_empty() => {
return Err(ParserError::IncompleteReduction(lexer.location.clone())); return Err(lexer.incomplete_reduction());
} }
Err(e) => { Err(e) => {
return Err(e); return Err(e);
@@ -697,11 +697,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
} else { } else {
let term = match self.terms.pop() { let term = match self.terms.pop() {
Some(term) => term, Some(term) => term,
_ => { _ => return Err(self.lexer.incomplete_reduction()),
return Err(ParserError::IncompleteReduction(
self.lexer.location.clone(),
))
}
}; };
if self.stack[idx].priority > 1000 { if self.stack[idx].priority > 1000 {
@@ -714,9 +710,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
}; };
if arity > self.terms.len() { if arity > self.terms.len() {
return Err(ParserError::IncompleteReduction( return Err(self.lexer.incomplete_reduction());
self.lexer.location.clone(),
));
} }
let idx = self.terms.len() - arity; let idx = self.terms.len() - arity;
@@ -784,11 +778,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
let term = match self.terms.pop() { let term = match self.terms.pop() {
Some(term) => term, Some(term) => term,
_ => { _ => return Err(self.lexer.incomplete_reduction()),
return Err(ParserError::IncompleteReduction(
self.lexer.location.clone(),
))
}
}; };
self.terms self.terms
@@ -966,7 +956,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
self.negate_number(n, negate_rat_rc, Literal::Rational) self.negate_number(n, negate_rat_rc, Literal::Rational)
} }
Token::Literal(Literal::F64(_offset, n)) if n.is_infinite() => { Token::Literal(Literal::F64(_offset, n)) if n.is_infinite() => {
return Err(ParserError::InfiniteFloat(self.lexer.location.clone())); return Err(self.lexer.located_error(ParserErrorKind::InfiniteFloat));
} }
Token::Literal(Literal::F64(offset, n)) => { Token::Literal(Literal::F64(offset, n)) => {
self.negate_number((offset, n), negate_f64, |(offset, n)| { self.negate_number((offset, n), negate_f64, |(offset, n)| {
@@ -988,25 +978,19 @@ impl<'a, R: CharRead> Parser<'a, R> {
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER), Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
Token::Close => { Token::Close => {
if !self.reduce_term() && !self.reduce_brackets() { if !self.reduce_term() && !self.reduce_brackets() {
return Err(ParserError::IncompleteReduction( return Err(self.lexer.incomplete_reduction());
self.lexer.location.clone(),
));
} }
} }
Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER), Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER),
Token::CloseList => { Token::CloseList => {
if !self.reduce_list()? { if !self.reduce_list()? {
return Err(ParserError::IncompleteReduction( return Err(self.lexer.incomplete_reduction());
self.lexer.location.clone(),
));
} }
} }
Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER), Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER),
Token::CloseCurly => { Token::CloseCurly => {
if !self.reduce_curly()? { if !self.reduce_curly()? {
return Err(ParserError::IncompleteReduction( return Err(self.lexer.incomplete_reduction());
self.lexer.location.clone(),
));
} }
} }
Token::HeadTailSeparator => { Token::HeadTailSeparator => {
@@ -1039,11 +1023,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
| Some(TokenType::OpenList) | Some(TokenType::OpenList)
| Some(TokenType::OpenCurly) | Some(TokenType::OpenCurly)
| Some(TokenType::HeadTailSeparator) | Some(TokenType::HeadTailSeparator)
| Some(TokenType::Comma) => { | Some(TokenType::Comma) => return Err(self.lexer.incomplete_reduction()),
return Err(ParserError::IncompleteReduction(
self.lexer.location.clone(),
))
}
_ => {} _ => {}
}, },
} }
@@ -1079,9 +1059,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
self.reduce_op(1400); self.reduce_op(1400);
if self.terms.len() > 1 || self.stack.len() > 1 { if self.terms.len() > 1 || self.stack.len() > 1 {
return Err(ParserError::IncompleteReduction( return Err(self.lexer.incomplete_reduction());
self.lexer.location.clone(),
));
} }
match self.terms.pop() { match self.terms.pop() {
@@ -1089,14 +1067,10 @@ impl<'a, R: CharRead> Parser<'a, R> {
if self.terms.is_empty() { if self.terms.is_empty() {
Ok(term) Ok(term)
} else { } else {
Err(ParserError::IncompleteReduction( Err(self.lexer.incomplete_reduction())
self.lexer.location.clone(),
))
} }
} }
_ => Err(ParserError::IncompleteReduction( _ => Err(self.lexer.incomplete_reduction()),
self.lexer.location.clone(),
)),
} }
} }
} }

View File

@@ -52,9 +52,7 @@ pub(crate) fn error_after_read_term<R>(
// rough overlap with errors 8.14.1.3 k) & l) of the ISO standard here // rough overlap with errors 8.14.1.3 k) & l) of the ISO standard here
if !(location.line() == prior_num_lines_read && location.column() == 0) { if !(location.line() == prior_num_lines_read && location.column() == 0) {
return CompilationError::from(ParserError::IncompleteReduction( return CompilationError::from(parser.lexer.incomplete_reduction());
parser.lexer.location.clone(),
));
} }
} }