mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
fail when end of input is not reached by parser
This commit is contained in:
parent
37f17da27e
commit
8f5df8b7b8
4 changed files with 45 additions and 7 deletions
|
@ -3385,9 +3385,23 @@ fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, Loadi
|
||||||
let mut module_timing = header.module_timing;
|
let mut module_timing = header.module_timing;
|
||||||
let parse_start = SystemTime::now();
|
let parse_start = SystemTime::now();
|
||||||
let parse_state = parser::State::new(&header.src, Attempting::Module);
|
let parse_state = parser::State::new(&header.src, Attempting::Module);
|
||||||
let (parsed_defs, _) = module_defs()
|
let parsed_defs = match module_defs().parse(&arena, parse_state) {
|
||||||
.parse(&arena, parse_state)
|
Ok((success, _state)) => success,
|
||||||
.expect("TODO gracefully handle parse error on module defs. IMPORTANT: Bail out entirely if there are any BadUtf8 problems! That means the whole source file is not valid UTF-8 and any other errors we report may get mis-reported. We rely on this for safety in an `unsafe` block later on in this function.");
|
Err((fail, state)) => {
|
||||||
|
use roc_parse::parser::FailReason;
|
||||||
|
match fail.reason {
|
||||||
|
FailReason::BadUtf8 => panic!(
|
||||||
|
r"TODO gracefully handle parse error on module defs. IMPORTANT: Bail out entirely if there are any BadUtf8 problems! That means the whole source file is not valid UTF-8 and any other errors we report may get mis-reported. We rely on this for safety in an `unsafe` block later on in this function."
|
||||||
|
),
|
||||||
|
_ => panic!(
|
||||||
|
"Parser Error\nmodule: {:?}\nattempting: {:?}\n(line, col): {:?}\n",
|
||||||
|
header.module_id,
|
||||||
|
fail.attempting,
|
||||||
|
(state.line, state.column)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let parsed_defs = parsed_defs.into_bump_slice();
|
let parsed_defs = parsed_defs.into_bump_slice();
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ use crate::header::{
|
||||||
};
|
};
|
||||||
use crate::ident::{lowercase_ident, unqualified_ident, uppercase_ident};
|
use crate::ident::{lowercase_ident, unqualified_ident, uppercase_ident};
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
self, ascii_char, ascii_string, loc, optional, peek_utf8_char, peek_utf8_char_at, unexpected,
|
self, ascii_char, ascii_string, end_of_file, loc, optional, peek_utf8_char, peek_utf8_char_at,
|
||||||
unexpected_eof, Either, ParseResult, Parser, State,
|
unexpected, unexpected_eof, Either, ParseResult, Parser, State,
|
||||||
};
|
};
|
||||||
use crate::string_literal;
|
use crate::string_literal;
|
||||||
use crate::type_annotation;
|
use crate::type_annotation;
|
||||||
|
@ -290,7 +290,11 @@ pub fn platform_header<'a>() -> impl Parser<'a, PlatformHeader<'a>> {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn module_defs<'a>() -> impl Parser<'a, Vec<'a, Located<Def<'a>>>> {
|
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> {
|
struct ProvidesTo<'a> {
|
||||||
|
|
|
@ -75,6 +75,11 @@ impl<'a> State<'a> {
|
||||||
self.original_len - self.bytes.len()
|
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.
|
/// Increments the line, then resets column, indent_col, and is_indenting.
|
||||||
/// Advances the input by 1, to consume the newline character.
|
/// Advances the input by 1, to consume the newline character.
|
||||||
pub fn newline(&self) -> Result<Self, (Fail, Self)> {
|
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),
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -854,7 +854,7 @@ mod solve_expr {
|
||||||
infer_eq(
|
infer_eq(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
\f -> (\a, b -> f b a),
|
\f -> (\a, b -> f b a)
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
"(a, b -> c) -> (b, a -> c)",
|
"(a, b -> c) -> (b, a -> c)",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue