mirror of
https://github.com/oxalica/nil.git
synced 2024-11-23 03:57:06 +03:00
Enhance error recovery for incomplete syntax
This commit is contained in:
parent
d31baa16cb
commit
1463d498b5
@ -153,30 +153,42 @@ impl<'i> Parser<'i> {
|
||||
}
|
||||
|
||||
/// Consumes a token if the next token matches the expected one, or does nothing if not.
|
||||
fn want(&mut self, expect: SyntaxKind) {
|
||||
/// Return whether the expected token is consumed.
|
||||
fn want(&mut self, expect: SyntaxKind) -> bool {
|
||||
if self.peek_non_ws() == Some(expect) {
|
||||
self.bump();
|
||||
true
|
||||
} else {
|
||||
self.error(ErrorKind::MissingToken(expect));
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes tokens until it matches the expected one.
|
||||
fn require(&mut self, expect: SyntaxKind) {
|
||||
/// Expect the termination of an experssion by a followed `guard` token.
|
||||
/// Return whether the expected token is consumed.
|
||||
fn require_expr_end(&mut self, guard: SyntaxKind) -> bool {
|
||||
if matches!(self.peek_non_ws(), Some(k) if k == guard) {
|
||||
self.bump();
|
||||
return true;
|
||||
}
|
||||
self.error(ErrorKind::MissingToken(guard));
|
||||
|
||||
// Try to consume more experssions as recovery.
|
||||
loop {
|
||||
match self.peek_non_ws() {
|
||||
Some(k) if k == expect => {
|
||||
Some(k) if k == guard => {
|
||||
self.bump();
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
Some(_) => {
|
||||
self.error(ErrorKind::UnexpectedToken);
|
||||
self.bump();
|
||||
}
|
||||
None => {
|
||||
self.error(ErrorKind::MissingToken(expect));
|
||||
break;
|
||||
Some(k) if !k.is_separator() => {
|
||||
let prev = self.tokens.len();
|
||||
self.expr_function_opt();
|
||||
// Don't stuck!
|
||||
if self.tokens.len() == prev {
|
||||
self.bump();
|
||||
}
|
||||
}
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -235,10 +247,13 @@ impl<'i> Parser<'i> {
|
||||
self.start_node(IF_THEN_ELSE);
|
||||
self.bump(); // if
|
||||
self.expr_function_opt();
|
||||
self.require(T![then]);
|
||||
self.expr_function_opt();
|
||||
self.require(T![else]);
|
||||
self.expr_function_opt();
|
||||
// If the separator is not found, stop early.
|
||||
if self.require_expr_end(T![then]) {
|
||||
self.expr_function_opt();
|
||||
if self.require_expr_end(T![else]) {
|
||||
self.expr_function_opt();
|
||||
}
|
||||
}
|
||||
self.finish_node();
|
||||
}
|
||||
Some(T!['{']) => {
|
||||
@ -454,7 +469,7 @@ impl<'i> Parser<'i> {
|
||||
self.start_node(PAREN);
|
||||
self.bump(); // '('
|
||||
self.expr_function_opt();
|
||||
self.require(T![')']);
|
||||
self.require_expr_end(T![')']);
|
||||
self.finish_node();
|
||||
}
|
||||
Some(T![rec] | T![let]) => {
|
||||
@ -491,11 +506,11 @@ impl<'i> Parser<'i> {
|
||||
self.expr_select_opt();
|
||||
continue;
|
||||
}
|
||||
Some(_) => {
|
||||
Some(k) if !k.is_separator() => {
|
||||
self.error(ErrorKind::UnexpectedToken);
|
||||
self.bump();
|
||||
}
|
||||
None => {
|
||||
_ => {
|
||||
self.error(ErrorKind::MissingToken(T![']']));
|
||||
break;
|
||||
}
|
||||
@ -638,7 +653,7 @@ impl<'i> Parser<'i> {
|
||||
self.start_node(PAREN);
|
||||
self.bump(); // '('
|
||||
self.expr_function_opt();
|
||||
self.require(T![')']);
|
||||
self.require_expr_end(T![')']);
|
||||
self.finish_node();
|
||||
}
|
||||
// Use lookahead for ending condition, since `;` might not be typed yet.
|
||||
@ -652,7 +667,32 @@ impl<'i> Parser<'i> {
|
||||
Some(k) if k.can_start_attr() => {
|
||||
self.start_node(ATTR_PATH_VALUE);
|
||||
self.attrpath_opt();
|
||||
self.want(T![=]);
|
||||
// If there is no `=`, we assume this binding is to be typed.
|
||||
// Stop parsing RHS and try the next binding.
|
||||
// ```
|
||||
// {
|
||||
// b.| # Typing...
|
||||
// a = 1; # Valid binding follows.
|
||||
// }
|
||||
// ```
|
||||
if self.want(T![=]) {
|
||||
self.expr_function_opt();
|
||||
}
|
||||
self.want(T![;]);
|
||||
self.finish_node();
|
||||
}
|
||||
// Recover for missing attrpath. This happens when the previous binding is not
|
||||
// terminated by `;`.
|
||||
// ```
|
||||
// {
|
||||
// a = 1 # => `a = 1 b <missing semicolon>`
|
||||
// b = 2; # => `= 2;` <- We are here.
|
||||
// }
|
||||
// ```
|
||||
Some(T![=]) => {
|
||||
self.error(ErrorKind::MissingAttr);
|
||||
self.start_node(ATTR_PATH_VALUE);
|
||||
self.bump(); // =
|
||||
self.expr_function_opt();
|
||||
self.want(T![;]);
|
||||
self.finish_node();
|
||||
@ -699,7 +739,7 @@ impl<'i> Parser<'i> {
|
||||
self.start_node(DYNAMIC);
|
||||
self.bump(); // "${"
|
||||
self.expr_function_opt();
|
||||
self.require(T!['}']);
|
||||
self.require_expr_end(T!['}']);
|
||||
self.finish_node();
|
||||
}
|
||||
|
||||
@ -762,6 +802,15 @@ impl SyntaxKind {
|
||||
)
|
||||
}
|
||||
|
||||
/// Whether this token is a separator in some syntax.
|
||||
/// We should stop at these tokens during error recovery.
|
||||
fn is_separator(self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
T![then] | T![else] | T![')'] | T![']'] | T!['}'] | T![=] | T![;] | T![,]
|
||||
)
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn prefix_bp(self) -> Option<u8> {
|
||||
// See `infix_bp`.
|
||||
|
@ -1,43 +1,38 @@
|
||||
Unexpected token at 16..17
|
||||
Unexpected token at 16..17
|
||||
Unexpected token at 18..20
|
||||
Unexpected token at 21..22
|
||||
Unexpected token at 25..28
|
||||
Unexpected token at 29..30
|
||||
Unexpected token at 31..32
|
||||
Unexpected token at 32..34
|
||||
Unexpected token at 34..36
|
||||
Unexpected token at 36..37
|
||||
Unexpected token at 41..42
|
||||
Missing KW_IN at 43..43
|
||||
Missing expression at 43..43
|
||||
Missing R_CURLY at 16..17
|
||||
SOURCE_FILE@0..43
|
||||
LET_IN@0..43
|
||||
KW_LET@0..3 "let"
|
||||
SPACE@3..6 "\n "
|
||||
INHERIT@6..40
|
||||
INHERIT@6..17
|
||||
KW_INHERIT@6..13 "inherit"
|
||||
SPACE@13..14 " "
|
||||
DYNAMIC@14..38
|
||||
DYNAMIC@14..16
|
||||
DOLLAR_L_CURLY@14..16 "${"
|
||||
SEMICOLON@16..17 ";"
|
||||
SPACE@17..18 "\n"
|
||||
KW_IN@18..20 "in"
|
||||
SPACE@20..21 " "
|
||||
L_CURLY@21..22 "{"
|
||||
SPACE@22..25 "\n "
|
||||
IDENT@25..28 "foo"
|
||||
SPACE@28..29 " "
|
||||
SEMICOLON@16..17 ";"
|
||||
SPACE@17..18 "\n"
|
||||
KW_IN@18..20 "in"
|
||||
SPACE@20..21 " "
|
||||
ATTR_SET@21..42
|
||||
L_CURLY@21..22 "{"
|
||||
SPACE@22..25 "\n "
|
||||
ATTR_PATH_VALUE@25..40
|
||||
ATTR_PATH@25..29
|
||||
NAME@25..28
|
||||
IDENT@25..28 "foo"
|
||||
SPACE@28..29 " "
|
||||
EQ@29..30 "="
|
||||
SPACE@30..31 " "
|
||||
DQUOTE@31..32 "\""
|
||||
STRING_FRAGMENT@32..34 "a-"
|
||||
DOLLAR_L_CURLY@34..36 "${"
|
||||
IDENT@36..37 "b"
|
||||
R_CURLY@37..38 "}"
|
||||
STRING@38..39
|
||||
DQUOTE@38..39 "\""
|
||||
SEMICOLON@39..40 ";"
|
||||
SPACE@40..41 "\n"
|
||||
R_CURLY@41..42 "}"
|
||||
STRING@31..39
|
||||
DQUOTE@31..32 "\""
|
||||
STRING_FRAGMENT@32..34 "a-"
|
||||
DYNAMIC@34..38
|
||||
DOLLAR_L_CURLY@34..36 "${"
|
||||
REF@36..37
|
||||
IDENT@36..37 "b"
|
||||
R_CURLY@37..38 "}"
|
||||
DQUOTE@38..39 "\""
|
||||
SEMICOLON@39..40 ";"
|
||||
SPACE@40..41 "\n"
|
||||
R_CURLY@41..42 "}"
|
||||
SPACE@42..43 "\n"
|
||||
|
@ -1,45 +1,28 @@
|
||||
Missing SEMICOLON at 14..15
|
||||
Unexpected token at 14..15
|
||||
Unexpected token at 16..18
|
||||
Unexpected token at 18..19
|
||||
Missing attribute at 27..28
|
||||
Unexpected token at 29..30
|
||||
Missing SEMICOLON at 29..30
|
||||
Missing EQ at 38..39
|
||||
Unexpected token at 38..39
|
||||
Missing SEMICOLON at 38..39
|
||||
SOURCE_FILE@0..40
|
||||
BINARY_OP@0..40
|
||||
ATTR_SET@0..30
|
||||
Missing EQ at 4..5
|
||||
Missing SEMICOLON at 4..5
|
||||
Unexpected token at 12..13
|
||||
Missing SEMICOLON at 12..13
|
||||
SOURCE_FILE@0..14
|
||||
APPLY@0..14
|
||||
ATTR_SET@0..5
|
||||
L_CURLY@0..1 "{"
|
||||
SPACE@1..4 "\n "
|
||||
INHERIT@4..14
|
||||
KW_INHERIT@4..11 "inherit"
|
||||
SPACE@11..14 "\n "
|
||||
EQ@14..15 "="
|
||||
SPACE@15..16 " "
|
||||
INT@16..18 "42"
|
||||
SEMICOLON@18..19 ";"
|
||||
SPACE@19..22 "\n "
|
||||
ATTR_PATH_VALUE@22..29
|
||||
ATTR_PATH@22..27
|
||||
NAME@22..25
|
||||
IDENT@22..25 "bar"
|
||||
DOT@25..26 "."
|
||||
SPACE@26..27 " "
|
||||
EQ@27..28 "="
|
||||
SPACE@28..29 "\n"
|
||||
R_CURLY@29..30 "}"
|
||||
SPACE@30..31 " "
|
||||
SLASH2@31..33 "//"
|
||||
SPACE@33..34 " "
|
||||
ATTR_SET@34..39
|
||||
L_CURLY@34..35 "{"
|
||||
SPACE@35..36 " "
|
||||
ATTR_PATH_VALUE@36..38
|
||||
ATTR_PATH@36..38
|
||||
NAME@36..37
|
||||
IDENT@36..37 "x"
|
||||
SPACE@37..38 " "
|
||||
R_CURLY@38..39 "}"
|
||||
SPACE@39..40 "\n"
|
||||
SPACE@1..2 " "
|
||||
ATTR_PATH_VALUE@2..4
|
||||
ATTR_PATH@2..4
|
||||
NAME@2..3
|
||||
IDENT@2..3 "x"
|
||||
SPACE@3..4 " "
|
||||
R_CURLY@4..5 "}"
|
||||
SPACE@5..6 " "
|
||||
ATTR_SET@6..13
|
||||
L_CURLY@6..7 "{"
|
||||
SPACE@7..8 " "
|
||||
ATTR_PATH_VALUE@8..12
|
||||
ATTR_PATH@8..10
|
||||
NAME@8..9
|
||||
IDENT@8..9 "x"
|
||||
SPACE@9..10 " "
|
||||
EQ@10..11 "="
|
||||
SPACE@11..12 " "
|
||||
R_CURLY@12..13 "}"
|
||||
SPACE@13..14 "\n"
|
||||
|
@ -1,5 +1 @@
|
||||
{
|
||||
inherit
|
||||
= 42;
|
||||
bar. =
|
||||
} // { x }
|
||||
{ x } { x = }
|
||||
|
119
crates/syntax/test_data/parser/err/incomplete-binding.ast
Normal file
119
crates/syntax/test_data/parser/err/incomplete-binding.ast
Normal file
@ -0,0 +1,119 @@
|
||||
Missing EQ at 17..18
|
||||
Missing SEMICOLON at 17..18
|
||||
Missing EQ at 46..47
|
||||
Missing SEMICOLON at 46..47
|
||||
Missing SEMICOLON at 65..66
|
||||
Missing attribute at 65..66
|
||||
Missing SEMICOLON at 84..85
|
||||
Missing attribute at 84..85
|
||||
SOURCE_FILE@0..91
|
||||
ATTR_SET@0..90
|
||||
L_CURLY@0..1 "{"
|
||||
SPACE@1..4 "\n "
|
||||
ATTR_PATH_VALUE@4..10
|
||||
ATTR_PATH@4..6
|
||||
NAME@4..5
|
||||
IDENT@4..5 "a"
|
||||
SPACE@5..6 " "
|
||||
EQ@6..7 "="
|
||||
SPACE@7..8 " "
|
||||
LITERAL@8..9
|
||||
INT@8..9 "1"
|
||||
SEMICOLON@9..10 ";"
|
||||
SPACE@10..13 "\n "
|
||||
ATTR_PATH_VALUE@13..17
|
||||
ATTR_PATH@13..17
|
||||
NAME@13..14
|
||||
IDENT@13..14 "x"
|
||||
SPACE@14..17 "\n "
|
||||
ATTR_PATH_VALUE@17..23
|
||||
ATTR_PATH@17..19
|
||||
NAME@17..18
|
||||
IDENT@17..18 "b"
|
||||
SPACE@18..19 " "
|
||||
EQ@19..20 "="
|
||||
SPACE@20..21 " "
|
||||
LITERAL@21..22
|
||||
INT@21..22 "1"
|
||||
SEMICOLON@22..23 ";"
|
||||
SPACE@23..26 "\n "
|
||||
ATTR_PATH_VALUE@26..37
|
||||
ATTR_PATH@26..33
|
||||
NAME@26..27
|
||||
IDENT@26..27 "x"
|
||||
DOT@27..28 "."
|
||||
SPACE@28..31 "\n "
|
||||
NAME@31..32
|
||||
IDENT@31..32 "c"
|
||||
SPACE@32..33 " "
|
||||
EQ@33..34 "="
|
||||
SPACE@34..35 " "
|
||||
LITERAL@35..36
|
||||
INT@35..36 "1"
|
||||
SEMICOLON@36..37 ";"
|
||||
SPACE@37..40 "\n "
|
||||
ATTR_PATH_VALUE@40..46
|
||||
ATTR_PATH@40..46
|
||||
NAME@40..41
|
||||
IDENT@40..41 "x"
|
||||
DOT@41..42 "."
|
||||
NAME@42..43
|
||||
IDENT@42..43 "y"
|
||||
SPACE@43..46 "\n "
|
||||
ATTR_PATH_VALUE@46..52
|
||||
ATTR_PATH@46..48
|
||||
NAME@46..47
|
||||
IDENT@46..47 "d"
|
||||
SPACE@47..48 " "
|
||||
EQ@48..49 "="
|
||||
SPACE@49..50 " "
|
||||
LITERAL@50..51
|
||||
INT@50..51 "1"
|
||||
SEMICOLON@51..52 ";"
|
||||
SPACE@52..55 "\n "
|
||||
ATTR_PATH_VALUE@55..65
|
||||
ATTR_PATH@55..59
|
||||
NAME@55..56
|
||||
IDENT@55..56 "x"
|
||||
DOT@56..57 "."
|
||||
NAME@57..58
|
||||
IDENT@57..58 "y"
|
||||
SPACE@58..59 " "
|
||||
EQ@59..60 "="
|
||||
SPACE@60..63 "\n "
|
||||
REF@63..64
|
||||
IDENT@63..64 "e"
|
||||
SPACE@64..65 " "
|
||||
ATTR_PATH_VALUE@65..69
|
||||
EQ@65..66 "="
|
||||
SPACE@66..67 " "
|
||||
LITERAL@67..68
|
||||
INT@67..68 "1"
|
||||
SEMICOLON@68..69 ";"
|
||||
SPACE@69..72 "\n "
|
||||
ATTR_PATH_VALUE@72..84
|
||||
ATTR_PATH@72..76
|
||||
NAME@72..73
|
||||
IDENT@72..73 "x"
|
||||
DOT@73..74 "."
|
||||
NAME@74..75
|
||||
IDENT@74..75 "y"
|
||||
SPACE@75..76 " "
|
||||
EQ@76..77 "="
|
||||
SPACE@77..78 " "
|
||||
APPLY@78..84
|
||||
LITERAL@78..79
|
||||
INT@78..79 "1"
|
||||
SPACE@79..82 "\n "
|
||||
REF@82..83
|
||||
IDENT@82..83 "f"
|
||||
SPACE@83..84 " "
|
||||
ATTR_PATH_VALUE@84..88
|
||||
EQ@84..85 "="
|
||||
SPACE@85..86 " "
|
||||
LITERAL@86..87
|
||||
INT@86..87 "1"
|
||||
SEMICOLON@87..88 ";"
|
||||
SPACE@88..89 "\n"
|
||||
R_CURLY@89..90 "}"
|
||||
SPACE@90..91 "\n"
|
13
crates/syntax/test_data/parser/err/incomplete-binding.nix
Normal file
13
crates/syntax/test_data/parser/err/incomplete-binding.nix
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
a = 1;
|
||||
x
|
||||
b = 1;
|
||||
x.
|
||||
c = 1;
|
||||
x.y
|
||||
d = 1;
|
||||
x.y =
|
||||
e = 1;
|
||||
x.y = 1
|
||||
f = 1;
|
||||
}
|
105
crates/syntax/test_data/parser/err/incomplete-if.ast
Normal file
105
crates/syntax/test_data/parser/err/incomplete-if.ast
Normal file
@ -0,0 +1,105 @@
|
||||
Unexpected token at 10..11
|
||||
Missing KW_THEN at 10..11
|
||||
Missing KW_THEN at 22..23
|
||||
Unexpected token at 39..40
|
||||
Missing KW_ELSE at 39..40
|
||||
Missing KW_ELSE at 58..59
|
||||
Unexpected token at 82..83
|
||||
SOURCE_FILE@0..95
|
||||
ATTR_SET@0..94
|
||||
L_CURLY@0..1 "{"
|
||||
SPACE@1..4 "\n "
|
||||
ATTR_PATH_VALUE@4..11
|
||||
ATTR_PATH@4..6
|
||||
NAME@4..5
|
||||
IDENT@4..5 "a"
|
||||
SPACE@5..6 " "
|
||||
EQ@6..7 "="
|
||||
SPACE@7..8 " "
|
||||
IF_THEN_ELSE@8..10
|
||||
KW_IF@8..10 "if"
|
||||
SEMICOLON@10..11 ";"
|
||||
SPACE@11..14 "\n "
|
||||
ATTR_PATH_VALUE@14..23
|
||||
ATTR_PATH@14..16
|
||||
NAME@14..15
|
||||
IDENT@14..15 "b"
|
||||
SPACE@15..16 " "
|
||||
EQ@16..17 "="
|
||||
SPACE@17..18 " "
|
||||
IF_THEN_ELSE@18..22
|
||||
KW_IF@18..20 "if"
|
||||
SPACE@20..21 " "
|
||||
LITERAL@21..22
|
||||
INT@21..22 "1"
|
||||
SEMICOLON@22..23 ";"
|
||||
SPACE@23..26 "\n "
|
||||
ATTR_PATH_VALUE@26..40
|
||||
ATTR_PATH@26..28
|
||||
NAME@26..27
|
||||
IDENT@26..27 "c"
|
||||
SPACE@27..28 " "
|
||||
EQ@28..29 "="
|
||||
SPACE@29..30 " "
|
||||
IF_THEN_ELSE@30..39
|
||||
KW_IF@30..32 "if"
|
||||
SPACE@32..33 " "
|
||||
LITERAL@33..34
|
||||
INT@33..34 "1"
|
||||
SPACE@34..35 " "
|
||||
KW_THEN@35..39 "then"
|
||||
SEMICOLON@39..40 ";"
|
||||
SPACE@40..43 "\n "
|
||||
ATTR_PATH_VALUE@43..59
|
||||
ATTR_PATH@43..45
|
||||
NAME@43..44
|
||||
IDENT@43..44 "d"
|
||||
SPACE@44..45 " "
|
||||
EQ@45..46 "="
|
||||
SPACE@46..47 " "
|
||||
IF_THEN_ELSE@47..58
|
||||
KW_IF@47..49 "if"
|
||||
SPACE@49..50 " "
|
||||
LITERAL@50..51
|
||||
INT@50..51 "1"
|
||||
SPACE@51..52 " "
|
||||
KW_THEN@52..56 "then"
|
||||
SPACE@56..57 " "
|
||||
LITERAL@57..58
|
||||
INT@57..58 "2"
|
||||
SEMICOLON@58..59 ";"
|
||||
SPACE@59..62 "\n "
|
||||
ATTR_PATH_VALUE@62..83
|
||||
ATTR_PATH@62..64
|
||||
NAME@62..63
|
||||
IDENT@62..63 "e"
|
||||
SPACE@63..64 " "
|
||||
EQ@64..65 "="
|
||||
SPACE@65..66 " "
|
||||
IF_THEN_ELSE@66..82
|
||||
KW_IF@66..68 "if"
|
||||
SPACE@68..69 " "
|
||||
LITERAL@69..70
|
||||
INT@69..70 "1"
|
||||
SPACE@70..71 " "
|
||||
KW_THEN@71..75 "then"
|
||||
SPACE@75..76 " "
|
||||
LITERAL@76..77
|
||||
INT@76..77 "2"
|
||||
SPACE@77..78 " "
|
||||
KW_ELSE@78..82 "else"
|
||||
SEMICOLON@82..83 ";"
|
||||
SPACE@83..86 "\n "
|
||||
ATTR_PATH_VALUE@86..92
|
||||
ATTR_PATH@86..88
|
||||
NAME@86..87
|
||||
IDENT@86..87 "f"
|
||||
SPACE@87..88 " "
|
||||
EQ@88..89 "="
|
||||
SPACE@89..90 " "
|
||||
LITERAL@90..91
|
||||
INT@90..91 "1"
|
||||
SEMICOLON@91..92 ";"
|
||||
SPACE@92..93 "\n"
|
||||
R_CURLY@93..94 "}"
|
||||
SPACE@94..95 "\n"
|
8
crates/syntax/test_data/parser/err/incomplete-if.nix
Normal file
8
crates/syntax/test_data/parser/err/incomplete-if.nix
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
a = if;
|
||||
b = if 1;
|
||||
c = if 1 then;
|
||||
d = if 1 then 2;
|
||||
e = if 1 then 2 else;
|
||||
f = 1;
|
||||
}
|
64
crates/syntax/test_data/parser/err/incomplete-list.ast
Normal file
64
crates/syntax/test_data/parser/err/incomplete-list.ast
Normal file
@ -0,0 +1,64 @@
|
||||
Missing R_BRACK at 23..24
|
||||
Missing SEMICOLON at 23..24
|
||||
Missing attribute at 23..24
|
||||
Missing R_BRACK at 36..37
|
||||
SOURCE_FILE@0..49
|
||||
ATTR_SET@0..48
|
||||
L_CURLY@0..1 "{"
|
||||
SPACE@1..4 "\n "
|
||||
ATTR_PATH_VALUE@4..10
|
||||
ATTR_PATH@4..6
|
||||
NAME@4..5
|
||||
IDENT@4..5 "a"
|
||||
SPACE@5..6 " "
|
||||
EQ@6..7 "="
|
||||
SPACE@7..8 " "
|
||||
LITERAL@8..9
|
||||
INT@8..9 "1"
|
||||
SEMICOLON@9..10 ";"
|
||||
SPACE@10..13 "\n "
|
||||
ATTR_PATH_VALUE@13..23
|
||||
ATTR_PATH@13..15
|
||||
NAME@13..14
|
||||
IDENT@13..14 "x"
|
||||
SPACE@14..15 " "
|
||||
EQ@15..16 "="
|
||||
SPACE@16..17 " "
|
||||
LIST@17..23
|
||||
L_BRACK@17..18 "["
|
||||
SPACE@18..21 "\n "
|
||||
REF@21..22
|
||||
IDENT@21..22 "b"
|
||||
SPACE@22..23 " "
|
||||
ATTR_PATH_VALUE@23..27
|
||||
EQ@23..24 "="
|
||||
SPACE@24..25 " "
|
||||
LITERAL@25..26
|
||||
INT@25..26 "2"
|
||||
SEMICOLON@26..27 ";"
|
||||
SPACE@27..30 "\n "
|
||||
ATTR_PATH_VALUE@30..37
|
||||
ATTR_PATH@30..32
|
||||
NAME@30..31
|
||||
IDENT@30..31 "x"
|
||||
SPACE@31..32 " "
|
||||
EQ@32..33 "="
|
||||
SPACE@33..34 " "
|
||||
LIST@34..36
|
||||
L_BRACK@34..35 "["
|
||||
SPACE@35..36 " "
|
||||
SEMICOLON@36..37 ";"
|
||||
SPACE@37..40 "\n "
|
||||
ATTR_PATH_VALUE@40..46
|
||||
ATTR_PATH@40..42
|
||||
NAME@40..41
|
||||
IDENT@40..41 "c"
|
||||
SPACE@41..42 " "
|
||||
EQ@42..43 "="
|
||||
SPACE@43..44 " "
|
||||
LITERAL@44..45
|
||||
INT@44..45 "3"
|
||||
SEMICOLON@45..46 ";"
|
||||
SPACE@46..47 "\n"
|
||||
R_CURLY@47..48 "}"
|
||||
SPACE@48..49 "\n"
|
7
crates/syntax/test_data/parser/err/incomplete-list.nix
Normal file
7
crates/syntax/test_data/parser/err/incomplete-list.nix
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
a = 1;
|
||||
x = [
|
||||
b = 2;
|
||||
x = [ ;
|
||||
c = 3;
|
||||
}
|
40
crates/syntax/test_data/parser/err/incomplete-pat.ast
Normal file
40
crates/syntax/test_data/parser/err/incomplete-pat.ast
Normal file
@ -0,0 +1,40 @@
|
||||
Unexpected token at 6..7
|
||||
Unexpected token at 16..17
|
||||
SOURCE_FILE@0..25
|
||||
LAMBDA@0..25
|
||||
PARAM@0..21
|
||||
PAT@0..21
|
||||
L_CURLY@0..1 "{"
|
||||
SPACE@1..2 " "
|
||||
PAT_FIELD@2..4
|
||||
NAME@2..3
|
||||
IDENT@2..3 "a"
|
||||
SPACE@3..4 "\n"
|
||||
COMMA@4..5 ","
|
||||
SPACE@5..6 "\n"
|
||||
COMMA@6..7 ","
|
||||
SPACE@7..8 " "
|
||||
PAT_FIELD@8..10
|
||||
NAME@8..9
|
||||
IDENT@8..9 "b"
|
||||
SPACE@9..10 "\n"
|
||||
COMMA@10..11 ","
|
||||
SPACE@11..12 " "
|
||||
PAT_FIELD@12..16
|
||||
NAME@12..13
|
||||
IDENT@12..13 "x"
|
||||
SPACE@13..14 " "
|
||||
QUESTION@14..15 "?"
|
||||
SPACE@15..16 "\n"
|
||||
COMMA@16..17 ","
|
||||
SPACE@17..18 " "
|
||||
PAT_FIELD@18..20
|
||||
NAME@18..19
|
||||
IDENT@18..19 "c"
|
||||
SPACE@19..20 "\n"
|
||||
R_CURLY@20..21 "}"
|
||||
COLON@21..22 ":"
|
||||
SPACE@22..23 " "
|
||||
LITERAL@23..24
|
||||
INT@23..24 "1"
|
||||
SPACE@24..25 "\n"
|
6
crates/syntax/test_data/parser/err/incomplete-pat.nix
Normal file
6
crates/syntax/test_data/parser/err/incomplete-pat.nix
Normal file
@ -0,0 +1,6 @@
|
||||
{ a
|
||||
,
|
||||
, b
|
||||
, x ?
|
||||
, c
|
||||
}: 1
|
@ -1,3 +1,4 @@
|
||||
Missing R_PAREN at 6..8
|
||||
Unexpected token at 6..8
|
||||
Unexpected token at 17..19
|
||||
SOURCE_FILE@0..24
|
||||
@ -11,7 +12,9 @@ SOURCE_FILE@0..24
|
||||
REF@3..5
|
||||
IDENT@3..5 "or"
|
||||
SPACE@5..6 " "
|
||||
KW_OR@6..8 "or"
|
||||
APPLY@6..8
|
||||
REF@6..8
|
||||
IDENT@6..8 "or"
|
||||
R_PAREN@8..9 ")"
|
||||
SPACE@9..10 " "
|
||||
LIST@10..23
|
||||
|
@ -7,6 +7,7 @@ Multiple root expressions at 19..20
|
||||
Unexpected token at 20..21
|
||||
Unexpected token at 21..22
|
||||
Unexpected token at 22..23
|
||||
Missing R_CURLY at 50..51
|
||||
Unexpected token at 50..51
|
||||
Unexpected token at 51..52
|
||||
Unexpected token at 52..53
|
||||
@ -75,26 +76,28 @@ Unexpected token at 114..115
|
||||
Unexpected token at 115..116
|
||||
Unexpected token at 116..117
|
||||
Unexpected token at 117..118
|
||||
Unexpected token at 118..122
|
||||
Unexpected token at 122..123
|
||||
Unexpected token at 123..124
|
||||
Unexpected token at 124..125
|
||||
Unexpected token at 125..126
|
||||
Unexpected token at 126..127
|
||||
Unexpected token at 127..128
|
||||
Unexpected token at 128..129
|
||||
Missing R_BRACK at 129..130
|
||||
Missing R_BRACK at 129..130
|
||||
Multiple root expressions at 129..130
|
||||
Unexpected token at 129..130
|
||||
Multiple root expressions at 130..131
|
||||
Unexpected token at 130..131
|
||||
Multiple root expressions at 131..132
|
||||
Unexpected token at 131..132
|
||||
Multiple root expressions at 132..133
|
||||
Unexpected token at 132..133
|
||||
Unexpected token at 133..133
|
||||
Unexpected token at 133..134
|
||||
Unexpected token at 134..136
|
||||
Unexpected token at 136..141
|
||||
Multiple root expressions at 133..133
|
||||
Missing R_CURLY at 141..142
|
||||
Unexpected token at 141..142
|
||||
Unexpected token at 142..143
|
||||
Unexpected token at 143..144
|
||||
Unexpected token at 144..146
|
||||
Missing EQ at 146..147
|
||||
Missing SEMICOLON at 146..147
|
||||
Unexpected token at 146..147
|
||||
Unexpected token at 147..148
|
||||
Unexpected token at 148..149
|
||||
@ -104,53 +107,82 @@ Unexpected token at 151..152
|
||||
Unexpected token at 152..153
|
||||
Unexpected token at 153..154
|
||||
Unexpected token at 154..155
|
||||
Unexpected token at 156..157
|
||||
Multiple root expressions at 157..158
|
||||
Unexpected token at 157..158
|
||||
Multiple root expressions at 158..159
|
||||
Unexpected token at 158..159
|
||||
Multiple root expressions at 159..160
|
||||
Unexpected token at 159..160
|
||||
Multiple root expressions at 160..161
|
||||
Unexpected token at 160..161
|
||||
Multiple root expressions at 161..162
|
||||
Unexpected token at 161..162
|
||||
Multiple root expressions at 162..163
|
||||
Unexpected token at 162..163
|
||||
Multiple root expressions at 163..164
|
||||
Unexpected token at 163..164
|
||||
Multiple root expressions at 164..165
|
||||
Unexpected token at 164..165
|
||||
Multiple root expressions at 165..166
|
||||
Missing R_BRACK at 169..170
|
||||
Multiple root expressions at 169..170
|
||||
Unexpected token at 169..170
|
||||
Multiple root expressions at 170..170
|
||||
Unexpected token at 170..170
|
||||
Unexpected token at 172..173
|
||||
Multiple root expressions at 170..171
|
||||
Unexpected token at 173..174
|
||||
Multiple root expressions at 173..174
|
||||
Unexpected token at 173..174
|
||||
Multiple root expressions at 174..174
|
||||
Unexpected token at 174..174
|
||||
Multiple root expressions at 174..175
|
||||
Unexpected token at 174..175
|
||||
Multiple root expressions at 175..176
|
||||
Unexpected token at 175..176
|
||||
Multiple root expressions at 176..177
|
||||
Unexpected token at 176..177
|
||||
Multiple root expressions at 177..178
|
||||
Unexpected token at 177..178
|
||||
Multiple root expressions at 178..179
|
||||
Missing R_BRACK at 182..183
|
||||
Multiple root expressions at 182..183
|
||||
Unexpected token at 182..183
|
||||
Multiple root expressions at 183..184
|
||||
Unexpected token at 184..185
|
||||
Multiple root expressions at 186..187
|
||||
Unexpected token at 186..187
|
||||
Unexpected token at 189..190
|
||||
Multiple root expressions at 187..188
|
||||
Unexpected token at 190..191
|
||||
Multiple root expressions at 190..191
|
||||
Unexpected token at 190..191
|
||||
Multiple root expressions at 191..210
|
||||
Multiple root expressions at 210..211
|
||||
Unexpected token at 210..211
|
||||
Multiple root expressions at 211..212
|
||||
Unexpected token at 211..212
|
||||
Multiple root expressions at 212..213
|
||||
Unexpected token at 212..213
|
||||
Multiple root expressions at 213..214
|
||||
Unexpected token at 213..214
|
||||
Multiple root expressions at 214..215
|
||||
Unexpected token at 214..215
|
||||
Multiple root expressions at 215..216
|
||||
Unexpected token at 215..216
|
||||
Multiple root expressions at 216..217
|
||||
Unexpected token at 217..218
|
||||
Unexpected token at 218..219
|
||||
Unexpected token at 219..220
|
||||
Unexpected token at 220..221
|
||||
Missing R_CURLY at 232..233
|
||||
Unexpected token at 232..233
|
||||
Unexpected token at 233..234
|
||||
Unexpected token at 234..235
|
||||
Unexpected token at 235..236
|
||||
Unexpected token at 236..237
|
||||
Unexpected token at 237..238
|
||||
Unexpected token at 238..238
|
||||
Unexpected token at 238..239
|
||||
Unexpected token at 239..241
|
||||
Missing expression at 241..241
|
||||
Missing R_CURLY at 241..241
|
||||
Missing R_BRACK at 241..241
|
||||
Missing R_BRACK at 241..241
|
||||
Missing R_BRACK at 241..241
|
||||
Missing R_BRACK at 241..241
|
||||
SOURCE_FILE@0..241
|
||||
REF@0..7
|
||||
IDENT@0..7 "KKKKKKK"
|
||||
@ -160,15 +192,15 @@ SOURCE_FILE@0..241
|
||||
IDENT@8..17 "KKKKKKKKK"
|
||||
ERROR@17..18 "%"
|
||||
ERROR@18..19 "$"
|
||||
LIST@19..241
|
||||
LIST@19..129
|
||||
L_BRACK@19..20 "["
|
||||
ERROR@20..21 "^"
|
||||
ERROR@21..22 "'"
|
||||
ERROR@22..23 "$"
|
||||
PATH_INTERPOLATION@23..156
|
||||
PATH_INTERPOLATION@23..129
|
||||
PATH_START@23..23 ""
|
||||
PATH_FRAGMENT@23..24 "/"
|
||||
DYNAMIC@24..156
|
||||
DYNAMIC@24..129
|
||||
DOLLAR_L_CURLY@24..26 "${"
|
||||
REF@26..50
|
||||
IDENT@26..50 "KKKKKKKKKKKKKKKcKKkKKKKK"
|
||||
@ -240,26 +272,35 @@ SOURCE_FILE@0..241
|
||||
ERROR@115..116 "\u{11}"
|
||||
ERROR@116..117 "\u{11}"
|
||||
ERROR@117..118 "\u{11}"
|
||||
IDENT@118..122 "KKKK"
|
||||
REF@118..122
|
||||
IDENT@118..122 "KKKK"
|
||||
ERROR@122..123 "%"
|
||||
ERROR@123..124 "\0"
|
||||
ERROR@124..125 "\0"
|
||||
ERROR@125..126 "\0"
|
||||
ERROR@126..127 "\u{14}"
|
||||
ERROR@127..128 "$"
|
||||
L_BRACK@128..129 "["
|
||||
R_PAREN@129..130 ")"
|
||||
ERROR@130..131 "^"
|
||||
ERROR@131..132 "'"
|
||||
ERROR@132..133 "$"
|
||||
PATH_START@133..133 ""
|
||||
PATH_FRAGMENT@133..134 "/"
|
||||
DOLLAR_L_CURLY@134..136 "${"
|
||||
LIST@128..129
|
||||
L_BRACK@128..129 "["
|
||||
R_PAREN@129..130 ")"
|
||||
ERROR@130..131 "^"
|
||||
ERROR@131..132 "'"
|
||||
ERROR@132..133 "$"
|
||||
PATH_INTERPOLATION@133..157
|
||||
PATH_START@133..133 ""
|
||||
PATH_FRAGMENT@133..134 "/"
|
||||
DYNAMIC@134..157
|
||||
DOLLAR_L_CURLY@134..136 "${"
|
||||
REF@136..141
|
||||
IDENT@136..141 "KKKKK"
|
||||
ERROR@141..142 "\u{6}"
|
||||
ERROR@142..143 "\u{6}"
|
||||
ERROR@141..142 "\u{6}"
|
||||
ERROR@142..143 "\u{6}"
|
||||
ATTR_SET@143..156
|
||||
L_CURLY@143..144 "{"
|
||||
IDENT@144..146 "YY"
|
||||
ATTR_PATH_VALUE@144..146
|
||||
ATTR_PATH@144..146
|
||||
NAME@144..146
|
||||
IDENT@144..146 "YY"
|
||||
L_CURLY@146..147 "{"
|
||||
ERROR@147..148 "'"
|
||||
ERROR@148..149 "\0"
|
||||
@ -270,79 +311,86 @@ SOURCE_FILE@0..241
|
||||
ERROR@153..154 "\0"
|
||||
ERROR@154..155 "\0"
|
||||
R_CURLY@155..156 "}"
|
||||
R_CURLY@156..157 "}"
|
||||
ERROR@157..158 "\u{1}"
|
||||
ERROR@158..159 "\0"
|
||||
ERROR@159..160 "|"
|
||||
ERROR@160..161 "\0"
|
||||
ERROR@161..162 "\0"
|
||||
ERROR@162..163 "\0"
|
||||
ERROR@163..164 "\0"
|
||||
ERROR@164..165 "\0"
|
||||
LIST@165..241
|
||||
L_BRACK@165..166 "["
|
||||
REF@166..167
|
||||
IDENT@166..167 "a"
|
||||
ATTR_SET@167..169
|
||||
L_CURLY@167..168 "{"
|
||||
R_CURLY@168..169 "}"
|
||||
R_CURLY@169..170 "}"
|
||||
PATH_END@170..170 ""
|
||||
ATTR_SET@170..172
|
||||
R_CURLY@156..157 "}"
|
||||
ERROR@157..158 "\u{1}"
|
||||
ERROR@158..159 "\0"
|
||||
ERROR@159..160 "|"
|
||||
ERROR@160..161 "\0"
|
||||
ERROR@161..162 "\0"
|
||||
ERROR@162..163 "\0"
|
||||
ERROR@163..164 "\0"
|
||||
ERROR@164..165 "\0"
|
||||
LIST@165..169
|
||||
L_BRACK@165..166 "["
|
||||
REF@166..167
|
||||
IDENT@166..167 "a"
|
||||
ATTR_SET@167..169
|
||||
L_CURLY@167..168 "{"
|
||||
R_CURLY@168..169 "}"
|
||||
R_CURLY@169..170 "}"
|
||||
PATH_END@170..170 ""
|
||||
LAMBDA@170..173
|
||||
PARAM@170..172
|
||||
PAT@170..172
|
||||
L_CURLY@170..171 "{"
|
||||
R_CURLY@171..172 "}"
|
||||
COLON@172..173 ":"
|
||||
R_CURLY@173..174 "}"
|
||||
PATH_END@174..174 ""
|
||||
ERROR@174..175 "\0"
|
||||
ERROR@175..176 "\0"
|
||||
ERROR@176..177 "\0"
|
||||
R_PAREN@177..178 ")"
|
||||
LIST@178..241
|
||||
L_BRACK@178..179 "["
|
||||
REF@179..180
|
||||
IDENT@179..180 "a"
|
||||
ATTR_SET@180..182
|
||||
L_CURLY@180..181 "{"
|
||||
R_CURLY@181..182 "}"
|
||||
R_CURLY@182..183 "}"
|
||||
ATTR_SET@183..186
|
||||
L_CURLY@183..184 "{"
|
||||
L_CURLY@184..185 "{"
|
||||
R_CURLY@185..186 "}"
|
||||
R_CURLY@186..187 "}"
|
||||
ATTR_SET@187..189
|
||||
L_CURLY@187..188 "{"
|
||||
R_CURLY@188..189 "}"
|
||||
COLON@189..190 ":"
|
||||
R_CURLY@190..191 "}"
|
||||
REF@191..210
|
||||
IDENT@191..210 "KKKKKKKKKKKKKKKKKKK"
|
||||
ERROR@210..211 "%"
|
||||
ERROR@211..212 "\0"
|
||||
ERROR@212..213 "\0"
|
||||
ERROR@213..214 "\0"
|
||||
ERROR@214..215 "\u{14}"
|
||||
ERROR@215..216 "$"
|
||||
LIST@216..241
|
||||
L_BRACK@216..217 "["
|
||||
PLUS@217..218 "+"
|
||||
ERROR@218..219 "^"
|
||||
ERROR@219..220 "'"
|
||||
ERROR@220..221 "$"
|
||||
PATH_INTERPOLATION@221..241
|
||||
PATH_START@221..221 ""
|
||||
PATH_FRAGMENT@221..222 "/"
|
||||
DYNAMIC@222..241
|
||||
DOLLAR_L_CURLY@222..224 "${"
|
||||
REF@224..232
|
||||
IDENT@224..232 "KKKKKKKK"
|
||||
ERROR@232..233 "%"
|
||||
ERROR@233..234 "$"
|
||||
L_BRACK@234..235 "["
|
||||
ERROR@235..236 "^"
|
||||
ERROR@236..237 "'"
|
||||
ERROR@237..238 "$"
|
||||
PATH_START@238..238 ""
|
||||
PATH_FRAGMENT@238..239 "/"
|
||||
COLON@172..173 ":"
|
||||
R_CURLY@173..174 "}"
|
||||
PATH_END@174..174 ""
|
||||
ERROR@174..175 "\0"
|
||||
ERROR@175..176 "\0"
|
||||
ERROR@176..177 "\0"
|
||||
R_PAREN@177..178 ")"
|
||||
LIST@178..182
|
||||
L_BRACK@178..179 "["
|
||||
REF@179..180
|
||||
IDENT@179..180 "a"
|
||||
ATTR_SET@180..182
|
||||
L_CURLY@180..181 "{"
|
||||
R_CURLY@181..182 "}"
|
||||
R_CURLY@182..183 "}"
|
||||
ATTR_SET@183..186
|
||||
L_CURLY@183..184 "{"
|
||||
L_CURLY@184..185 "{"
|
||||
R_CURLY@185..186 "}"
|
||||
R_CURLY@186..187 "}"
|
||||
LAMBDA@187..190
|
||||
PARAM@187..189
|
||||
PAT@187..189
|
||||
L_CURLY@187..188 "{"
|
||||
R_CURLY@188..189 "}"
|
||||
COLON@189..190 ":"
|
||||
R_CURLY@190..191 "}"
|
||||
REF@191..210
|
||||
IDENT@191..210 "KKKKKKKKKKKKKKKKKKK"
|
||||
ERROR@210..211 "%"
|
||||
ERROR@211..212 "\0"
|
||||
ERROR@212..213 "\0"
|
||||
ERROR@213..214 "\0"
|
||||
ERROR@214..215 "\u{14}"
|
||||
ERROR@215..216 "$"
|
||||
LIST@216..241
|
||||
L_BRACK@216..217 "["
|
||||
PLUS@217..218 "+"
|
||||
ERROR@218..219 "^"
|
||||
ERROR@219..220 "'"
|
||||
ERROR@220..221 "$"
|
||||
PATH_INTERPOLATION@221..241
|
||||
PATH_START@221..221 ""
|
||||
PATH_FRAGMENT@221..222 "/"
|
||||
DYNAMIC@222..241
|
||||
DOLLAR_L_CURLY@222..224 "${"
|
||||
REF@224..232
|
||||
IDENT@224..232 "KKKKKKKK"
|
||||
ERROR@232..233 "%"
|
||||
ERROR@233..234 "$"
|
||||
LIST@234..241
|
||||
L_BRACK@234..235 "["
|
||||
ERROR@235..236 "^"
|
||||
ERROR@236..237 "'"
|
||||
ERROR@237..238 "$"
|
||||
PATH_INTERPOLATION@238..241
|
||||
PATH_START@238..238 ""
|
||||
PATH_FRAGMENT@238..239 "/"
|
||||
DYNAMIC@239..241
|
||||
DOLLAR_L_CURLY@239..241 "${"
|
||||
|
Loading…
Reference in New Issue
Block a user