1
1
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:
oxalica 2022-09-20 17:35:42 +08:00
parent d31baa16cb
commit 1463d498b5
14 changed files with 645 additions and 209 deletions

View File

@ -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`.

View File

@ -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"

View File

@ -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"

View File

@ -1,5 +1 @@
{
inherit
= 42;
bar. =
} // { x }
{ x } { x = }

View 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"

View 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;
}

View 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"

View 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;
}

View 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"

View File

@ -0,0 +1,7 @@
{
a = 1;
x = [
b = 2;
x = [ ;
c = 3;
}

View 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"

View File

@ -0,0 +1,6 @@
{ a
,
, b
, x ?
, c
}: 1

View File

@ -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

View File

@ -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 "${"