From e00da070fdb4642f0efe27178e50baebd8dcddd2 Mon Sep 17 00:00:00 2001 From: JT Date: Tue, 7 Sep 2021 15:56:30 +1200 Subject: [PATCH] Fail more gently for bad list/table parses --- crates/nu-parser/src/lex.rs | 7 ++--- crates/nu-parser/src/parser.rs | 50 ++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/crates/nu-parser/src/lex.rs b/crates/nu-parser/src/lex.rs index f68a6b630..867fdb483 100644 --- a/crates/nu-parser/src/lex.rs +++ b/crates/nu-parser/src/lex.rs @@ -161,15 +161,14 @@ pub fn lex_item( let span = Span::new(span_offset + token_start, span_offset + *curr_offset); - // If there is still unclosed opening delimiters, close them and add - // synthetic closing characters to the accumulated token. + // If there is still unclosed opening delimiters, remember they were missing if let Some(block) = block_level.last() { let delim = block.closing(); let cause = ParseError::UnexpectedEof( (delim as char).to_string(), Span { - start: span.end - 1, - end: span.end, + start: span.end, + end: span.end + 1, }, ); diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 6b483d1c1..45cddb5d2 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -2050,26 +2050,40 @@ pub fn parse_value( } } SyntaxShape::Any => { - let shapes = [ - SyntaxShape::Int, - SyntaxShape::Number, - SyntaxShape::Range, - SyntaxShape::Filesize, - SyntaxShape::Duration, - SyntaxShape::Block, - SyntaxShape::Table, - SyntaxShape::List(Box::new(SyntaxShape::Any)), - SyntaxShape::String, - ]; - for shape in shapes.iter() { - if let (s, None) = parse_value(working_set, span, shape) { - return (s, None); + if bytes.starts_with(b"[") { + let shapes = [SyntaxShape::Table]; + for shape in shapes.iter() { + if let (s, None) = parse_value(working_set, span, shape) { + return (s, None); + } } + parse_value( + working_set, + span, + &SyntaxShape::List(Box::new(SyntaxShape::Any)), + ) + } else { + let shapes = [ + SyntaxShape::Int, + SyntaxShape::Number, + SyntaxShape::Range, + SyntaxShape::Filesize, + SyntaxShape::Duration, + SyntaxShape::Block, + SyntaxShape::Table, + SyntaxShape::List(Box::new(SyntaxShape::Any)), + SyntaxShape::String, + ]; + for shape in shapes.iter() { + if let (s, None) = parse_value(working_set, span, shape) { + return (s, None); + } + } + ( + garbage(span), + Some(ParseError::Expected("any shape".into(), span)), + ) } - ( - garbage(span), - Some(ParseError::Expected("any shape".into(), span)), - ) } _ => (garbage(span), Some(ParseError::IncompleteParser(span))), }