Always wrap error syntax in ERROR nodes

This prevents error tokens accidentally affect the container node, eg.
the dangling `let` inside an Attrset.

Fixes #20
This commit is contained in:
oxalica 2022-09-25 20:53:08 +08:00
parent 4c77fa90ef
commit 8f9882d1ad
9 changed files with 378 additions and 162 deletions

View file

@ -68,7 +68,7 @@ impl<'i> Parser<'i> {
self.expr_function_opt();
// Don't stuck.
if self.tokens.len() == prev {
self.bump();
self.bump_error();
}
}
self.finish_node();
@ -116,6 +116,13 @@ impl<'i> Parser<'i> {
self.builder.token(kind.into(), &self.src[range]);
}
/// Consume the next token and wrap it in an ERROR node.
fn bump_error(&mut self) {
self.start_node(ERROR);
self.bump();
self.finish_node();
}
/// Peek the next token, including whitespaces.
fn peek_full(&mut self) -> Option<(SyntaxKind, TextRange)> {
self.steps += 1;
@ -181,12 +188,14 @@ impl<'i> Parser<'i> {
return true;
}
Some(k) if !k.is_separator() => {
self.start_node(ERROR);
let prev = self.tokens.len();
self.expr_function_opt();
// Don't stuck!
if self.tokens.len() == prev {
self.bump();
}
self.finish_node();
}
_ => return false,
}
@ -239,7 +248,7 @@ impl<'i> Parser<'i> {
if matches!(self.peek_iter_non_ws().nth(1), Some(T!['{'])) {
self.expr_operator_opt()
} else {
self.bump();
self.bump_error();
self.error(ErrorKind::MissingToken(T!['{']));
}
}
@ -320,7 +329,7 @@ impl<'i> Parser<'i> {
self.bump(); // IDENT
self.finish_node();
if self.peek_non_ws() == Some(T![@]) {
self.bump();
self.bump(); // @
if self.peek_non_ws() == Some(T!['{']) {
self.pat();
} else {
@ -509,7 +518,7 @@ impl<'i> Parser<'i> {
}
Some(k) if !k.is_separator() => {
self.error(ErrorKind::MissingElemExpr);
self.bump();
self.bump_error();
}
_ => {
self.error(ErrorKind::MissingToken(T![']']));
@ -609,7 +618,7 @@ impl<'i> Parser<'i> {
}
Some(k) => {
self.error(ErrorKind::MissingParamIdent);
self.bump();
self.bump_error();
// Don't double error.
if k == T![,] {
continue;
@ -641,7 +650,7 @@ impl<'i> Parser<'i> {
break;
}
Some(k) if k == guard => {
self.bump();
self.bump(); // guard
break;
}
Some(T![inherit]) => {
@ -699,7 +708,7 @@ impl<'i> Parser<'i> {
// This can happen for some extra tokens (eg. unfinished exprs) in AttrSet or LetIn.
Some(_) => {
self.error(ErrorKind::MissingBinding);
self.bump();
self.bump_error();
}
}
}

View file

@ -12,7 +12,8 @@ SOURCE_FILE@0..25
SPACE@3..4 "\n"
COMMA@4..5 ","
SPACE@5..6 "\n"
COMMA@6..7 ","
ERROR@6..7
COMMA@6..7 ","
SPACE@7..8 " "
PAT_FIELD@8..10
NAME@8..9

View file

@ -7,7 +7,8 @@ SOURCE_FILE@0..21
LIST@0..6
L_BRACK@0..1 "["
SPACE@1..2 " "
KW_OR@2..4 "or"
ERROR@2..4
KW_OR@2..4 "or"
SPACE@4..5 " "
R_BRACK@5..6 "]"
SPACE@6..7 " "

View file

@ -13,5 +13,6 @@ SOURCE_FILE@0..12
SPACE@5..6 " "
EQ@6..7 "="
SPACE@7..8 " "
KW_REC@8..11 "rec"
ERROR@8..11
KW_REC@8..11 "rec"
SPACE@11..12 "\n"

View file

@ -0,0 +1,60 @@
Mising binding at 13..16
Mising binding at 30..32
Mising binding at 33..34
Multiple root expressions at 49..50
Missing expression at 49..50
Multiple root expressions at 51..52
Missing expression at 51..52
SOURCE_FILE@0..53
ATTR_SET@0..49
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 "
ERROR@13..16
KW_LET@13..16 "let"
SPACE@16..21 "\n "
ATTR_PATH_VALUE@21..27
ATTR_PATH@21..23
NAME@21..22
IDENT@21..22 "b"
SPACE@22..23 " "
EQ@23..24 "="
SPACE@24..25 " "
LITERAL@25..26
INT@25..26 "1"
SEMICOLON@26..27 ";"
SPACE@27..30 "\n "
ERROR@30..32
KW_IN@30..32 "in"
SPACE@32..33 " "
ERROR@33..34
L_CURLY@33..34 "{"
SPACE@34..39 "\n "
ATTR_PATH_VALUE@39..45
ATTR_PATH@39..41
NAME@39..40
IDENT@39..40 "c"
SPACE@40..41 " "
EQ@41..42 "="
SPACE@42..43 " "
REF@43..44
IDENT@43..44 "b"
SEMICOLON@44..45 ";"
SPACE@45..48 "\n "
R_CURLY@48..49 "}"
ERROR@49..50
SEMICOLON@49..50 ";"
SPACE@50..51 "\n"
ERROR@51..52
R_CURLY@51..52 "}"
SPACE@52..53 "\n"

View file

@ -0,0 +1,8 @@
{
a = 1;
let
b = 1;
in {
c = b;
};
}

View file

@ -12,9 +12,10 @@ SOURCE_FILE@0..24
REF@3..5
IDENT@3..5 "or"
SPACE@5..6 " "
APPLY@6..8
REF@6..8
IDENT@6..8 "or"
ERROR@6..8
APPLY@6..8
REF@6..8
IDENT@6..8 "or"
R_PAREN@8..9 ")"
SPACE@9..10 " "
LIST@10..23
@ -27,7 +28,8 @@ SOURCE_FILE@0..24
REF@14..16
IDENT@14..16 "or"
SPACE@16..17 " "
KW_OR@17..19 "or"
ERROR@17..19
KW_OR@17..19 "or"
SPACE@19..20 " "
REF@20..21
IDENT@20..21 "b"

View file

@ -11,6 +11,7 @@ SOURCE_FILE@0..6
NAME@1..2
IDENT@1..2 "Y"
COMMA@2..3 ","
L_CURLY@3..4 "{"
ERROR@3..4
L_CURLY@3..4 "{"
COMMA@4..5 ","
SPACE@5..6 "\n"

View file

@ -190,13 +190,18 @@ SOURCE_FILE@0..241
BANG@7..8 "!"
REF@8..17
IDENT@8..17 "KKKKKKKKK"
ERROR@17..18 "%"
ERROR@18..19 "$"
ERROR@17..18
ERROR@17..18 "%"
ERROR@18..19
ERROR@18..19 "$"
LIST@19..129
L_BRACK@19..20 "["
ERROR@20..21 "^"
ERROR@21..22 "'"
ERROR@22..23 "$"
ERROR@20..21
ERROR@20..21 "^"
ERROR@21..22
ERROR@21..22 "'"
ERROR@22..23
ERROR@22..23 "$"
PATH_INTERPOLATION@23..129
PATH_START@23..23 ""
PATH_FRAGMENT@23..24 "/"
@ -204,88 +209,168 @@ SOURCE_FILE@0..241
DOLLAR_L_CURLY@24..26 "${"
REF@26..50
IDENT@26..50 "KKKKKKKKKKKKKKKcKKkKKKKK"
ERROR@50..51 "\u{11}"
ERROR@51..52 "\u{11}"
ERROR@52..53 "\u{11}"
ERROR@53..54 "\u{11}"
ERROR@54..55 "\u{11}"
ERROR@55..56 "\u{11}"
ERROR@56..57 "\u{11}"
ERROR@57..58 "\u{11}"
ERROR@58..59 "\u{11}"
ERROR@59..60 "\u{11}"
ERROR@60..61 "\u{11}"
ERROR@61..62 "\u{11}"
ERROR@62..63 "\u{11}"
ERROR@63..64 "\u{11}"
ERROR@64..65 "\u{11}"
ERROR@65..66 "\u{11}"
ERROR@66..67 "\u{11}"
ERROR@67..68 "\u{11}"
ERROR@68..69 "\u{11}"
ERROR@69..70 "\u{11}"
ERROR@70..71 "\u{11}"
ERROR@71..72 "\u{11}"
ERROR@72..73 "\u{11}"
ERROR@73..74 "\u{11}"
ERROR@74..75 "\u{11}"
ERROR@75..76 "\u{11}"
ERROR@76..77 "\u{11}"
ERROR@77..78 "\u{11}"
ERROR@78..79 "\u{11}"
ERROR@79..80 "\u{11}"
ERROR@80..81 "\u{11}"
ERROR@81..82 "\u{11}"
ERROR@82..83 "\u{11}"
ERROR@83..84 "\u{11}"
ERROR@84..85 "\u{11}"
ERROR@85..86 "\u{11}"
ERROR@86..87 "\u{11}"
ERROR@87..88 "\u{11}"
ERROR@88..89 "\u{11}"
ERROR@89..90 "\u{11}"
ERROR@90..91 "\u{11}"
ERROR@91..92 "\u{11}"
ERROR@92..93 "\u{11}"
ERROR@93..94 "\u{11}"
ERROR@94..95 "\u{11}"
ERROR@95..96 "\u{11}"
ERROR@96..97 "\u{11}"
ERROR@97..98 "\u{11}"
ERROR@98..99 "\u{11}"
ERROR@99..100 "\u{11}"
ERROR@100..101 "\u{11}"
ERROR@101..102 "\u{11}"
ERROR@102..103 "\u{11}"
ERROR@103..104 "\u{11}"
ERROR@104..105 "\u{11}"
ERROR@105..106 "\u{11}"
ERROR@106..107 "\u{11}"
ERROR@107..108 "\u{11}"
ERROR@108..109 "\u{11}"
ERROR@109..110 "\u{11}"
ERROR@110..111 "\u{11}"
ERROR@111..112 "\u{11}"
ERROR@112..113 "\u{11}"
ERROR@113..114 "\u{11}"
ERROR@114..115 "\u{11}"
ERROR@115..116 "\u{11}"
ERROR@116..117 "\u{11}"
ERROR@117..118 "\u{11}"
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 "$"
LIST@128..129
L_BRACK@128..129 "["
R_PAREN@129..130 ")"
ERROR@130..131 "^"
ERROR@131..132 "'"
ERROR@132..133 "$"
ERROR@50..51
ERROR@50..51 "\u{11}"
ERROR@51..52
ERROR@51..52 "\u{11}"
ERROR@52..53
ERROR@52..53 "\u{11}"
ERROR@53..54
ERROR@53..54 "\u{11}"
ERROR@54..55
ERROR@54..55 "\u{11}"
ERROR@55..56
ERROR@55..56 "\u{11}"
ERROR@56..57
ERROR@56..57 "\u{11}"
ERROR@57..58
ERROR@57..58 "\u{11}"
ERROR@58..59
ERROR@58..59 "\u{11}"
ERROR@59..60
ERROR@59..60 "\u{11}"
ERROR@60..61
ERROR@60..61 "\u{11}"
ERROR@61..62
ERROR@61..62 "\u{11}"
ERROR@62..63
ERROR@62..63 "\u{11}"
ERROR@63..64
ERROR@63..64 "\u{11}"
ERROR@64..65
ERROR@64..65 "\u{11}"
ERROR@65..66
ERROR@65..66 "\u{11}"
ERROR@66..67
ERROR@66..67 "\u{11}"
ERROR@67..68
ERROR@67..68 "\u{11}"
ERROR@68..69
ERROR@68..69 "\u{11}"
ERROR@69..70
ERROR@69..70 "\u{11}"
ERROR@70..71
ERROR@70..71 "\u{11}"
ERROR@71..72
ERROR@71..72 "\u{11}"
ERROR@72..73
ERROR@72..73 "\u{11}"
ERROR@73..74
ERROR@73..74 "\u{11}"
ERROR@74..75
ERROR@74..75 "\u{11}"
ERROR@75..76
ERROR@75..76 "\u{11}"
ERROR@76..77
ERROR@76..77 "\u{11}"
ERROR@77..78
ERROR@77..78 "\u{11}"
ERROR@78..79
ERROR@78..79 "\u{11}"
ERROR@79..80
ERROR@79..80 "\u{11}"
ERROR@80..81
ERROR@80..81 "\u{11}"
ERROR@81..82
ERROR@81..82 "\u{11}"
ERROR@82..83
ERROR@82..83 "\u{11}"
ERROR@83..84
ERROR@83..84 "\u{11}"
ERROR@84..85
ERROR@84..85 "\u{11}"
ERROR@85..86
ERROR@85..86 "\u{11}"
ERROR@86..87
ERROR@86..87 "\u{11}"
ERROR@87..88
ERROR@87..88 "\u{11}"
ERROR@88..89
ERROR@88..89 "\u{11}"
ERROR@89..90
ERROR@89..90 "\u{11}"
ERROR@90..91
ERROR@90..91 "\u{11}"
ERROR@91..92
ERROR@91..92 "\u{11}"
ERROR@92..93
ERROR@92..93 "\u{11}"
ERROR@93..94
ERROR@93..94 "\u{11}"
ERROR@94..95
ERROR@94..95 "\u{11}"
ERROR@95..96
ERROR@95..96 "\u{11}"
ERROR@96..97
ERROR@96..97 "\u{11}"
ERROR@97..98
ERROR@97..98 "\u{11}"
ERROR@98..99
ERROR@98..99 "\u{11}"
ERROR@99..100
ERROR@99..100 "\u{11}"
ERROR@100..101
ERROR@100..101 "\u{11}"
ERROR@101..102
ERROR@101..102 "\u{11}"
ERROR@102..103
ERROR@102..103 "\u{11}"
ERROR@103..104
ERROR@103..104 "\u{11}"
ERROR@104..105
ERROR@104..105 "\u{11}"
ERROR@105..106
ERROR@105..106 "\u{11}"
ERROR@106..107
ERROR@106..107 "\u{11}"
ERROR@107..108
ERROR@107..108 "\u{11}"
ERROR@108..109
ERROR@108..109 "\u{11}"
ERROR@109..110
ERROR@109..110 "\u{11}"
ERROR@110..111
ERROR@110..111 "\u{11}"
ERROR@111..112
ERROR@111..112 "\u{11}"
ERROR@112..113
ERROR@112..113 "\u{11}"
ERROR@113..114
ERROR@113..114 "\u{11}"
ERROR@114..115
ERROR@114..115 "\u{11}"
ERROR@115..116
ERROR@115..116 "\u{11}"
ERROR@116..117
ERROR@116..117 "\u{11}"
ERROR@117..118
ERROR@117..118 "\u{11}"
ERROR@118..122
REF@118..122
IDENT@118..122 "KKKK"
ERROR@122..123
ERROR@122..123 "%"
ERROR@123..124
ERROR@123..124 "\0"
ERROR@124..125
ERROR@124..125 "\0"
ERROR@125..126
ERROR@125..126 "\0"
ERROR@126..127
ERROR@126..127 "\u{14}"
ERROR@127..128
ERROR@127..128 "$"
ERROR@128..129
LIST@128..129
L_BRACK@128..129 "["
ERROR@129..130
R_PAREN@129..130 ")"
ERROR@130..131
ERROR@130..131 "^"
ERROR@131..132
ERROR@131..132 "'"
ERROR@132..133
ERROR@132..133 "$"
PATH_INTERPOLATION@133..157
PATH_START@133..133 ""
PATH_FRAGMENT@133..134 "/"
@ -293,33 +378,53 @@ SOURCE_FILE@0..241
DOLLAR_L_CURLY@134..136 "${"
REF@136..141
IDENT@136..141 "KKKKK"
ERROR@141..142 "\u{6}"
ERROR@142..143 "\u{6}"
ATTR_SET@143..156
L_CURLY@143..144 "{"
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"
ERROR@149..150 "\0"
ERROR@150..151 "\0"
ERROR@151..152 "\0"
ERROR@152..153 "\0"
ERROR@153..154 "\0"
ERROR@154..155 "\0"
R_CURLY@155..156 "}"
ERROR@141..142
ERROR@141..142 "\u{6}"
ERROR@142..143
ERROR@142..143 "\u{6}"
ERROR@143..156
ATTR_SET@143..156
L_CURLY@143..144 "{"
ATTR_PATH_VALUE@144..146
ATTR_PATH@144..146
NAME@144..146
IDENT@144..146 "YY"
ERROR@146..147
L_CURLY@146..147 "{"
ERROR@147..148
ERROR@147..148 "'"
ERROR@148..149
ERROR@148..149 "\0"
ERROR@149..150
ERROR@149..150 "\0"
ERROR@150..151
ERROR@150..151 "\0"
ERROR@151..152
ERROR@151..152 "\0"
ERROR@152..153
ERROR@152..153 "\0"
ERROR@153..154
ERROR@153..154 "\0"
ERROR@154..155
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"
ERROR@157..158
ERROR@157..158 "\u{1}"
ERROR@158..159
ERROR@158..159 "\0"
ERROR@159..160
ERROR@159..160 "|"
ERROR@160..161
ERROR@160..161 "\0"
ERROR@161..162
ERROR@161..162 "\0"
ERROR@162..163
ERROR@162..163 "\0"
ERROR@163..164
ERROR@163..164 "\0"
ERROR@164..165
ERROR@164..165 "\0"
LIST@165..169
L_BRACK@165..166 "["
REF@166..167
@ -327,20 +432,28 @@ SOURCE_FILE@0..241
ATTR_SET@167..169
L_CURLY@167..168 "{"
R_CURLY@168..169 "}"
R_CURLY@169..170 "}"
PATH_END@170..170 ""
ERROR@169..170
R_CURLY@169..170 "}"
ERROR@170..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 ")"
ERROR@173..174
R_CURLY@173..174 "}"
ERROR@174..174
PATH_END@174..174 ""
ERROR@174..175
ERROR@174..175 "\0"
ERROR@175..176
ERROR@175..176 "\0"
ERROR@176..177
ERROR@176..177 "\0"
ERROR@177..178
R_PAREN@177..178 ")"
LIST@178..182
L_BRACK@178..179 "["
REF@179..180
@ -348,33 +461,47 @@ SOURCE_FILE@0..241
ATTR_SET@180..182
L_CURLY@180..181 "{"
R_CURLY@181..182 "}"
R_CURLY@182..183 "}"
ERROR@182..183
R_CURLY@182..183 "}"
ATTR_SET@183..186
L_CURLY@183..184 "{"
L_CURLY@184..185 "{"
ERROR@184..185
L_CURLY@184..185 "{"
R_CURLY@185..186 "}"
R_CURLY@186..187 "}"
ERROR@186..187
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 "}"
ERROR@190..191
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 "$"
ERROR@210..211
ERROR@210..211 "%"
ERROR@211..212
ERROR@211..212 "\0"
ERROR@212..213
ERROR@212..213 "\0"
ERROR@213..214
ERROR@213..214 "\0"
ERROR@214..215
ERROR@214..215 "\u{14}"
ERROR@215..216
ERROR@215..216 "$"
LIST@216..241
L_BRACK@216..217 "["
PLUS@217..218 "+"
ERROR@218..219 "^"
ERROR@219..220 "'"
ERROR@220..221 "$"
ERROR@217..218
PLUS@217..218 "+"
ERROR@218..219
ERROR@218..219 "^"
ERROR@219..220
ERROR@219..220 "'"
ERROR@220..221
ERROR@220..221 "$"
PATH_INTERPOLATION@221..241
PATH_START@221..221 ""
PATH_FRAGMENT@221..222 "/"
@ -382,15 +509,21 @@ SOURCE_FILE@0..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 "${"
ERROR@232..233
ERROR@232..233 "%"
ERROR@233..234
ERROR@233..234 "$"
ERROR@234..241
LIST@234..241
L_BRACK@234..235 "["
ERROR@235..236
ERROR@235..236 "^"
ERROR@236..237
ERROR@236..237 "'"
ERROR@237..238
ERROR@237..238 "$"
PATH_INTERPOLATION@238..241
PATH_START@238..238 ""
PATH_FRAGMENT@238..239 "/"
DYNAMIC@239..241
DOLLAR_L_CURLY@239..241 "${"