fail when end of input is not reached by parser

This commit is contained in:
Folkert 2021-02-01 16:38:14 +01:00
parent 37f17da27e
commit 8f5df8b7b8
4 changed files with 45 additions and 7 deletions

View file

@ -8,8 +8,8 @@ use crate::header::{
};
use crate::ident::{lowercase_ident, unqualified_ident, uppercase_ident};
use crate::parser::{
self, ascii_char, ascii_string, loc, optional, peek_utf8_char, peek_utf8_char_at, unexpected,
unexpected_eof, Either, ParseResult, Parser, State,
self, ascii_char, ascii_string, end_of_file, loc, optional, peek_utf8_char, peek_utf8_char_at,
unexpected, unexpected_eof, Either, ParseResult, Parser, State,
};
use crate::string_literal;
use crate::type_annotation;
@ -290,7 +290,11 @@ pub fn platform_header<'a>() -> impl Parser<'a, PlatformHeader<'a>> {
#[inline(always)]
pub fn module_defs<'a>() -> impl Parser<'a, Vec<'a, Located<Def<'a>>>> {
zero_or_more!(space0_around(loc(def(0)), 0))
// this parses just the defs
let defs = zero_or_more!(space0_around(loc(def(0)), 0));
// but when parsing a file, we really want to reach the end of the file
skip_second!(defs, end_of_file())
}
struct ProvidesTo<'a> {

View file

@ -75,6 +75,11 @@ impl<'a> State<'a> {
self.original_len - self.bytes.len()
}
/// Returns whether the parser has reached the end of the input
pub fn has_reached_end(&self) -> bool {
self.bytes.len() == 0
}
/// Increments the line, then resets column, indent_col, and is_indenting.
/// Advances the input by 1, to consume the newline character.
pub fn newline(&self) -> Result<Self, (Fail, Self)> {
@ -1278,3 +1283,18 @@ pub fn parse_utf8(bytes: &[u8]) -> Result<&str, FailReason> {
Err(_) => Err(FailReason::BadUtf8),
}
}
pub fn end_of_file<'a>() -> impl Parser<'a, ()> {
|_arena: &'a Bump, state: State<'a>| {
if state.has_reached_end() {
Ok(((), state))
} else {
let fail = Fail {
attempting: state.attempting,
reason: FailReason::ConditionFailed,
};
Err((fail, state))
}
}
}