From c9df734b836a503dbc09c48bfd54b35facd0f105 Mon Sep 17 00:00:00 2001 From: Yong He Date: Sat, 23 Mar 2024 11:25:51 -0700 Subject: Allow anonymous struct. (#3822) --- source/slang/slang-parser.cpp | 92 ++++++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 24 deletions(-) (limited to 'source/slang/slang-parser.cpp') diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 4522f977d..f7a0376ce 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -4811,8 +4811,15 @@ namespace Slang // Skip completion request token to prevent producing a type named completion request. AdvanceIf(this, TokenType::CompletionRequest); - // TODO: support `struct` declaration without tag - rs->nameAndLoc = expectIdentifier(this); + if (LookAheadToken(TokenType::Identifier)) + { + rs->nameAndLoc = expectIdentifier(this); + } + else + { + rs->nameAndLoc.name = generateName(this); + rs->nameAndLoc.loc = rs->loc; + } return parseOptGenericDecl(this, [&](GenericDecl*) { // We allow for an inheritance clause on a `struct` @@ -5423,6 +5430,27 @@ namespace Slang return statement; } + // Look ahead token, skipping all modifiers. + bool lookAheadTokenAfterModifiers(Parser* parser, const char* token) + { + TokenReader tokenPreview = parser->tokenReader; + for (Index i = 0;; i++) + { + if (tokenPreview.peekToken().getContent() == token) + return true; + else if (auto syntaxDecl = tryLookUpSyntaxDecl(parser, tokenPreview.peekToken().getName())) + { + if (syntaxDecl->syntaxClass.isSubClassOf()) + { + tokenPreview.advanceToken(); + continue; + } + } + break; + } + return false; + } + Stmt* Parser::parseBlockStatement() { if(!beginMatch(this, MatchedTokenType::CurlyBraces)) @@ -5446,12 +5474,44 @@ namespace Slang } Token closingBraceToken; + auto addStmt = [&](Stmt* stmt) + { + if (!body) + { + body = stmt; + } + else if (auto seqStmt = as(body)) + { + seqStmt->stmts.add(stmt); + } + else + { + SeqStmt* newBody = astBuilder->create(); + newBody->loc = blockStatement->loc; + newBody->stmts.add(body); + newBody->stmts.add(stmt); + + body = newBody; + } + }; while (!AdvanceIfMatch(this, MatchedTokenType::CurlyBraces, &closingBraceToken)) { - if (LookAheadToken("struct")) + if (lookAheadTokenAfterModifiers(this, "struct")) { - auto structDecl = ParseStruct(); - AddMember(scopeDecl, structDecl); + auto declBase = ParseDecl(this, scopeDecl); + if (auto declGroup = as(declBase)) + { + for (auto subDecl : declGroup->decls) + { + if (auto varDecl = as(subDecl)) + { + auto declStmt = astBuilder->create(); + declStmt->loc = varDecl->loc; + declStmt->decl = varDecl; + addStmt(declStmt); + } + } + } continue; } else if (AdvanceIf(this, "typedef")) @@ -5468,26 +5528,10 @@ namespace Slang } auto stmt = ParseStatement(); - if(stmt) - { - if (!body) - { - body = stmt; - } - else if (auto seqStmt = as(body)) - { - seqStmt->stmts.add(stmt); - } - else - { - SeqStmt* newBody = astBuilder->create(); - newBody->loc = blockStatement->loc; - newBody->stmts.add(body); - newBody->stmts.add(stmt); - body = newBody; - } - } + if (stmt) + addStmt(stmt); + TryRecover(this); } PopScope(); -- cgit v1.2.3