zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit b2f16d4484d2506d6a1e8a7d9f516f780d7fbd22 (tree)
parent a00fd6e25469a9929defea95425a1c312a68cf0e
Author: Vexu <git@vexu.eu>
Date:   Fri, 15 May 2020 23:38:40 +0300

fix infinite loop with mismatced bracket

Diffstat:
Mdoc/langref.html.in | 10+++++-----
Mlib/std/zig/parse.zig | 9++++++---
Mlib/std/zig/parser_test.zig | 10++++++++++
Msrc/parser.cpp | 6+++---
4 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/doc/langref.html.in b/doc/langref.html.in @@ -10090,7 +10090,7 @@ FnProto &lt;- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? Link VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON -ContainerField &lt;- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)? +ContainerField &lt;- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)? # *** Block Level *** Statement @@ -10204,7 +10204,7 @@ PrimaryTypeExpr / KEYWORD_error DOT IDENTIFIER / KEYWORD_false / KEYWORD_null - / KEYWORD_promise + / KEYWORD_anyframe / KEYWORD_true / KEYWORD_undefined / KEYWORD_unreachable @@ -10348,7 +10348,7 @@ PrefixOp PrefixTypeOp &lt;- QUESTIONMARK - / KEYWORD_promise MINUSRARROW + / KEYWORD_anyframe MINUSRARROW / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* @@ -10495,6 +10495,7 @@ end_of_word &lt;- ![a-zA-Z0-9_] skip KEYWORD_align &lt;- 'align' end_of_word KEYWORD_allowzero &lt;- 'allowzero' end_of_word KEYWORD_and &lt;- 'and' end_of_word +KEYWORD_anyframe &lt;- 'anyframe' end_of_word KEYWORD_asm &lt;- 'asm' end_of_word KEYWORD_async &lt;- 'async' end_of_word KEYWORD_await &lt;- 'await' end_of_word @@ -10521,7 +10522,6 @@ KEYWORD_null &lt;- 'null' end_of_word KEYWORD_or &lt;- 'or' end_of_word KEYWORD_orelse &lt;- 'orelse' end_of_word KEYWORD_packed &lt;- 'packed' end_of_word -KEYWORD_promise &lt;- 'promise' end_of_word KEYWORD_pub &lt;- 'pub' end_of_word KEYWORD_resume &lt;- 'resume' end_of_word KEYWORD_return &lt;- 'return' end_of_word @@ -10548,7 +10548,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_asm / KEYWORD_error / KEYWORD_export / KEYWORD_extern / KEYWORD_false / KEYWORD_fn / KEYWORD_for / KEYWORD_if / KEYWORD_inline / KEYWORD_noalias / KEYWORD_null / KEYWORD_or - / KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub + / KEYWORD_orelse / KEYWORD_packed / KEYWORD_anyframe / KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection / KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig @@ -69,8 +69,8 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error /// <- TestDecl ContainerMembers /// / TopLevelComptime ContainerMembers /// / KEYWORD_pub? TopLevelDecl ContainerMembers -/// / KEYWORD_pub? ContainerField COMMA ContainerMembers -/// / KEYWORD_pub? ContainerField +/// / ContainerField COMMA ContainerMembers +/// / ContainerField /// / fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree, top_level: bool) !Node.Root.DeclList { var list = Node.Root.DeclList.init(arena); @@ -284,7 +284,10 @@ fn findNextContainerMember(it: *TokenIterator) void { } }, .LParen, .LBracket, .LBrace => level += 1, - .RParen, .RBracket, .RBrace => { + .RParen, .RBracket => { + if (level != 0) level -= 1; + }, + .RBrace => { if (level == 0) { // end of container, exit putBackToken(it, tok.index); diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig @@ -162,6 +162,16 @@ test "recovery: extra '}' at top level" { }); } +test "recovery: mismatched bracket at top level" { + try testError( + \\const S = struct { + \\ arr: 128]?G + \\}; + , &[_]Error{ + .ExpectedToken, + }); +} + test "zig fmt: top-level fields" { try testCanonical( \\a: did_you_know, diff --git a/src/parser.cpp b/src/parser.cpp @@ -538,8 +538,8 @@ enum ContainerFieldState { // <- TestDecl ContainerMembers // / TopLevelComptime ContainerMembers // / KEYWORD_pub? TopLevelDecl ContainerMembers -// / KEYWORD_comptime? ContainerField COMMA ContainerMembers -// / KEYWORD_comptime? ContainerField +// / ContainerField COMMA ContainerMembers +// / ContainerField // / static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) { AstNodeContainerDecl res = {}; @@ -862,7 +862,7 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) { return res; } -// ContainerField <- IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)? +// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)? static AstNode *ast_parse_container_field(ParseContext *pc) { Token *identifier = eat_token_if(pc, TokenIdSymbol); if (identifier == nullptr)