authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-15 23:38:40+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-15 23:50:47+03:00
logb2f16d4484d2506d6a1e8a7d9f516f780d7fbd22
treed268fccb56981f6f060d46f73680af77e57e1af9
parenta00fd6e25469a9929defea95425a1c312a68cf0e
signaturelock-open Commit is signed but in an unrecognized format.

fix infinite loop with mismatced bracket


4 files changed, 24 insertions(+), 11 deletions(-)

doc/langref.html.in+5-5
......@@ -10090,7 +10090,7 @@ FnProto &lt;- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? Link
1009010090
1009110091VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
1009210092
10093ContainerField &lt;- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
10093ContainerField &lt;- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
1009410094
1009510095# *** Block Level ***
1009610096Statement
......@@ -10204,7 +10204,7 @@ PrimaryTypeExpr
1020410204 / KEYWORD_error DOT IDENTIFIER
1020510205 / KEYWORD_false
1020610206 / KEYWORD_null
10207 / KEYWORD_promise
10207 / KEYWORD_anyframe
1020810208 / KEYWORD_true
1020910209 / KEYWORD_undefined
1021010210 / KEYWORD_unreachable
......@@ -10348,7 +10348,7 @@ PrefixOp
1034810348
1034910349PrefixTypeOp
1035010350 &lt;- QUESTIONMARK
10351 / KEYWORD_promise MINUSRARROW
10351 / KEYWORD_anyframe MINUSRARROW
1035210352 / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
1035310353 / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
1035410354
......@@ -10495,6 +10495,7 @@ end_of_word &lt;- ![a-zA-Z0-9_] skip
1049510495KEYWORD_align &lt;- 'align' end_of_word
1049610496KEYWORD_allowzero &lt;- 'allowzero' end_of_word
1049710497KEYWORD_and &lt;- 'and' end_of_word
10498KEYWORD_anyframe &lt;- 'anyframe' end_of_word
1049810499KEYWORD_asm &lt;- 'asm' end_of_word
1049910500KEYWORD_async &lt;- 'async' end_of_word
1050010501KEYWORD_await &lt;- 'await' end_of_word
......@@ -10521,7 +10522,6 @@ KEYWORD_null &lt;- 'null' end_of_word
1052110522KEYWORD_or &lt;- 'or' end_of_word
1052210523KEYWORD_orelse &lt;- 'orelse' end_of_word
1052310524KEYWORD_packed &lt;- 'packed' end_of_word
10524KEYWORD_promise &lt;- 'promise' end_of_word
1052510525KEYWORD_pub &lt;- 'pub' end_of_word
1052610526KEYWORD_resume &lt;- 'resume' end_of_word
1052710527KEYWORD_return &lt;- 'return' end_of_word
......@@ -10548,7 +10548,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_asm
1054810548 / KEYWORD_error / KEYWORD_export / KEYWORD_extern / KEYWORD_false
1054910549 / KEYWORD_fn / KEYWORD_for / KEYWORD_if / KEYWORD_inline
1055010550 / KEYWORD_noalias / KEYWORD_null / KEYWORD_or
10551 / KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub
10551 / KEYWORD_orelse / KEYWORD_packed / KEYWORD_anyframe / KEYWORD_pub
1055210552 / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
1055310553 / KEYWORD_struct / KEYWORD_suspend
1055410554 / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try
lib/std/zig/parse.zig+6-3
......@@ -69,8 +69,8 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error
6969/// <- TestDecl ContainerMembers
7070/// / TopLevelComptime ContainerMembers
7171/// / KEYWORD_pub? TopLevelDecl ContainerMembers
72/// / KEYWORD_pub? ContainerField COMMA ContainerMembers
73/// / KEYWORD_pub? ContainerField
72/// / ContainerField COMMA ContainerMembers
73/// / ContainerField
7474/// /
7575fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree, top_level: bool) !Node.Root.DeclList {
7676 var list = Node.Root.DeclList.init(arena);
......@@ -284,7 +284,10 @@ fn findNextContainerMember(it: *TokenIterator) void {
284284 }
285285 },
286286 .LParen, .LBracket, .LBrace => level += 1,
287 .RParen, .RBracket, .RBrace => {
287 .RParen, .RBracket => {
288 if (level != 0) level -= 1;
289 },
290 .RBrace => {
288291 if (level == 0) {
289292 // end of container, exit
290293 putBackToken(it, tok.index);
lib/std/zig/parser_test.zig+10
......@@ -162,6 +162,16 @@ test "recovery: extra '}' at top level" {
162162 });
163163}
164164
165test "recovery: mismatched bracket at top level" {
166 try testError(
167 \\const S = struct {
168 \\ arr: 128]?G
169 \\};
170 , &[_]Error{
171 .ExpectedToken,
172 });
173}
174
165175test "zig fmt: top-level fields" {
166176 try testCanonical(
167177 \\a: did_you_know,
src/parser.cpp+3-3
......@@ -538,8 +538,8 @@ enum ContainerFieldState {
538538// <- TestDecl ContainerMembers
539539// / TopLevelComptime ContainerMembers
540540// / KEYWORD_pub? TopLevelDecl ContainerMembers
541// / KEYWORD_comptime? ContainerField COMMA ContainerMembers
542// / KEYWORD_comptime? ContainerField
541// / ContainerField COMMA ContainerMembers
542// / ContainerField
543543// /
544544static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
545545 AstNodeContainerDecl res = {};
......@@ -862,7 +862,7 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
862862 return res;
863863}
864864
865// ContainerField <- IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
865// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
866866static AstNode *ast_parse_container_field(ParseContext *pc) {
867867 Token *identifier = eat_token_if(pc, TokenIdSymbol);
868868 if (identifier == nullptr)