clarify EOF error across stream types and predicates (#1867, #1870)

This commit is contained in:
Mark
2023-07-08 13:38:32 -06:00
parent 2e26f37f5e
commit 067b5998ee
11 changed files with 84 additions and 71 deletions

View File

@@ -7,7 +7,7 @@ use crate::types::HeapCellValueTag;
use std::cell::{Cell, Ref, RefCell, RefMut};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::io::{Error as IOError};
use std::io::{Error as IOError, ErrorKind};
use std::ops::{Deref, Neg};
use std::rc::Rc;
use std::vec::Vec;
@@ -380,7 +380,7 @@ pub enum ParserError {
NonPrologChar(usize, usize),
ParseBigInt(usize, usize),
UnexpectedChar(char, usize, usize),
UnexpectedEOF,
// UnexpectedEOF,
Utf8Error(usize, usize),
}
@@ -403,16 +403,30 @@ impl ParserError {
ParserError::BackQuotedString(..) => atom!("back_quoted_string"),
ParserError::IncompleteReduction(..) => atom!("incomplete_reduction"),
ParserError::InvalidSingleQuotedCharacter(..) => atom!("invalid_single_quoted_character"),
ParserError::IO(e) if e.kind() == ErrorKind::UnexpectedEof => atom!("unexpected_end_of_file"),
ParserError::IO(_) => atom!("input_output_error"),
ParserError::LexicalError(_) => atom!("lexical_error"), // TODO: ?
ParserError::LexicalError(_) => atom!("lexical_error"),
ParserError::MissingQuote(..) => atom!("missing_quote"),
ParserError::NonPrologChar(..) => atom!("non_prolog_character"),
ParserError::ParseBigInt(..) => atom!("cannot_parse_big_int"),
ParserError::UnexpectedChar(..) => atom!("unexpected_char"),
ParserError::UnexpectedEOF => atom!("unexpected_end_of_file"),
ParserError::Utf8Error(..) => atom!("utf8_conversion_error"),
}
}
#[inline]
pub fn unexpected_eof() -> Self {
ParserError::IO(std::io::Error::from(ErrorKind::UnexpectedEof))
}
#[inline]
pub fn is_unexpected_eof(&self) -> bool {
if let ParserError::IO(e) = self {
e.kind() == ErrorKind::UnexpectedEof
} else {
false
}
}
}
impl From<lexical::Error> for ParserError {

View File

@@ -117,8 +117,6 @@ impl<R: Read> CharReader<R> {
// Branch using `>=` instead of the more correct `==`
// to tell the compiler that the pos..cap slice is always valid.
if self.pos >= self.buf.len() {
debug_assert!(self.pos >= self.buf.len());
self.buf.clear();
let mut word = [0u8; std::mem::size_of::<char>()];

View File

@@ -18,7 +18,7 @@ macro_rules! is_not_eof {
return Ok(true);
}
Ok(c) => c,
Err($crate::parser::ast::ParserError::UnexpectedEOF) => return Ok(true),
Err(e) if e.is_unexpected_eof() => return Ok(true),
Err(e) => return Err(e),
}
};
@@ -94,14 +94,14 @@ impl<'a, R: CharRead> Lexer<'a, R> {
pub fn lookahead_char(&mut self) -> Result<char, ParserError> {
match self.reader.peek_char() {
Some(Ok(c)) => Ok(c),
_ => Err(ParserError::UnexpectedEOF)
_ => Err(ParserError::unexpected_eof())
}
}
pub fn read_char(&mut self) -> Result<char, ParserError> {
match self.reader.read_char() {
Some(Ok(c)) => Ok(c),
_ => Err(ParserError::UnexpectedEOF)
_ => Err(ParserError::unexpected_eof())
}
}
@@ -168,7 +168,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
let mut c = self.lookahead_char()?;
let mut comment_loop = || {
let mut comment_loop = || -> Result<(), ParserError> {
loop {
while !comment_2_char!(c) {
self.skip_char(c);
@@ -187,7 +187,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
};
match comment_loop() {
Err(ParserError::UnexpectedEOF) => {
Err(e) if e.is_unexpected_eof() => {
return Err(ParserError::IncompleteReduction(self.line_num, self.col_num));
}
Err(e) => {
@@ -1003,7 +1003,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
return Ok(Token::End);
}
Err(ParserError::UnexpectedEOF) => {
Err(e) if e.is_unexpected_eof() => {
return Ok(Token::End);
}
_ => {
@@ -1055,7 +1055,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
}
if c == '\u{0}' {
return Err(ParserError::UnexpectedEOF);
return Err(ParserError::unexpected_eof())
}
self.name_token(c)

View File

@@ -275,7 +275,7 @@ fn read_tokens<R: CharRead>(lexer: &mut Lexer<R>) -> Result<Vec<Token>, ParserEr
break;
}
}
Err(ParserError::UnexpectedEOF) if !tokens.is_empty() => {
Err(e) if e.is_unexpected_eof() && !tokens.is_empty() => {
return Err(ParserError::IncompleteReduction(
lexer.line_num,
lexer.col_num,
@@ -883,7 +883,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
}) = get_op_desc(name, op_dir)
{
if (pre > 0 && inf + post > 0) || is_negate!(spec) {
match self.tokens.last().ok_or(ParserError::UnexpectedEOF)? {
match self.tokens.last().ok_or(ParserError::unexpected_eof())? {
// do this when layout hasn't been inserted,
// ie. why we don't match on Token::Open.
Token::OpenCT => {