Skip to content

Commit c7ec4dc

Browse files
bors[bot]Marwes
andauthored
Merge #857
857: Recover on various tokenization errors r=Marwes a=Marwes Co-authored-by: Markus Westerlind <[email protected]>
2 parents 87ca824 + 1869210 commit c7ec4dc

File tree

7 files changed

+236
-160
lines changed

7 files changed

+236
-160
lines changed

base/src/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ impl<T> Errors<T> {
6363
pub fn iter(&self) -> slice::Iter<T> {
6464
self.errors.iter()
6565
}
66+
67+
pub fn drain(
68+
&mut self,
69+
range: impl std::ops::RangeBounds<usize>,
70+
) -> impl Iterator<Item = T> + '_ {
71+
self.errors.drain(range)
72+
}
6673
}
6774

6875
impl<T> Index<usize> for Errors<T> {

base/tests/types.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ fn show_record_long_type() {
155155
],
156156
Type::string(),
157157
);
158-
let test = data("Test", vec![data("a", vec![])]);
159158
let record = Type::record(
160159
vec![Field::new(
161160
"Test",

parser/src/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ where
130130
{
131131
pub fn new(tokens: Tokens) -> Layout<'input, Tokens> {
132132
Layout {
133-
tokens: tokens,
133+
tokens,
134134
unprocessed_tokens: Vec::new(),
135135
indent_levels: Contexts::new(),
136136
}

parser/src/lib.rs

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -422,33 +422,17 @@ where
422422
Id: Clone + AsRef<str> + std::fmt::Debug,
423423
S: ?Sized + ParserSource,
424424
{
425-
let layout = Layout::new(Tokenizer::new(input));
426-
427-
let mut parse_errors = Errors::new();
428-
429-
let result = grammar::TopExprParser::new().parse(
430-
&input,
431-
type_cache,
432-
arena,
433-
symbols,
434-
&mut parse_errors,
435-
&mut TempVecs::new(),
436-
layout,
437-
);
438-
439-
match result {
440-
Ok(expr) => {
441-
if parse_errors.has_errors() {
442-
Err((Some(expr), transform_errors(input.span(), parse_errors)))
443-
} else {
444-
Ok(expr)
445-
}
446-
}
447-
Err(err) => {
448-
parse_errors.push(err);
449-
Err((None, transform_errors(input.span(), parse_errors)))
450-
}
451-
}
425+
parse_with(input, &mut |parse_errors, layout| {
426+
grammar::TopExprParser::new().parse(
427+
&input,
428+
type_cache,
429+
arena,
430+
symbols,
431+
parse_errors,
432+
&mut TempVecs::new(),
433+
layout,
434+
)
435+
})
452436
}
453437

454438
pub fn parse_expr<'ast>(
@@ -475,34 +459,65 @@ where
475459
Id: Clone + Eq + Hash + AsRef<str> + ::std::fmt::Debug,
476460
S: ?Sized + ParserSource,
477461
{
478-
let layout = Layout::new(Tokenizer::new(input));
462+
parse_with(input, &mut |parse_errors, layout| {
463+
let type_cache = TypeCache::default();
464+
465+
grammar::ReplLineParser::new()
466+
.parse(
467+
&input,
468+
&type_cache,
469+
arena,
470+
symbols,
471+
parse_errors,
472+
&mut TempVecs::new(),
473+
layout,
474+
)
475+
.map(|o| o.map(|b| *b))
476+
})
477+
.map_err(|(opt, err)| (opt.and_then(|opt| opt), err))
478+
}
479+
480+
fn parse_with<'ast, 'input, S, T>(
481+
input: &'input S,
482+
parse: &mut dyn FnMut(
483+
ErrorEnv<'_, 'input>,
484+
Layout<'input, &mut Tokenizer<'input>>,
485+
) -> Result<
486+
T,
487+
lalrpop_util::ParseError<BytePos, Token<&'input str>, Spanned<Error, BytePos>>,
488+
>,
489+
) -> Result<T, (Option<T>, ParseErrors)>
490+
where
491+
S: ?Sized + ParserSource,
492+
{
493+
let mut tokenizer = Tokenizer::new(input);
494+
let layout = Layout::new(&mut tokenizer);
479495

480496
let mut parse_errors = Errors::new();
481497

482-
let type_cache = TypeCache::default();
498+
let result = parse(&mut parse_errors, layout);
499+
500+
let mut all_errors = transform_errors(input.span(), parse_errors);
483501

484-
let result = grammar::ReplLineParser::new().parse(
485-
&input,
486-
&type_cache,
487-
arena,
488-
symbols,
489-
&mut parse_errors,
490-
&mut TempVecs::new(),
491-
layout,
492-
);
502+
all_errors.extend(tokenizer.errors.drain(..).map(|sp_error| {
503+
pos::spanned2(
504+
sp_error.span.start().absolute,
505+
sp_error.span.end().absolute,
506+
sp_error.value.into(),
507+
)
508+
}));
493509

494510
match result {
495-
Ok(repl_line) => {
496-
let repl_line = repl_line.map(|b| *b);
497-
if parse_errors.has_errors() {
498-
Err((repl_line, transform_errors(input.span(), parse_errors)))
511+
Ok(value) => {
512+
if all_errors.has_errors() {
513+
Err((Some(value), all_errors))
499514
} else {
500-
Ok(repl_line)
515+
Ok(value)
501516
}
502517
}
503518
Err(err) => {
504-
parse_errors.push(err);
505-
Err((None, transform_errors(input.span(), parse_errors)))
519+
all_errors.push(Error::from_lalrpop(input.span(), err));
520+
Err((None, all_errors))
506521
}
507522
}
508523
}

0 commit comments

Comments
 (0)