/* * Macro rules format: * "macro_rules" "!" <ident> <macro_body> */ static void parseMacroRules (lexerState *lexer, vString *scope, int parent_kind) { advanceToken(lexer, TRUE); if (lexer->cur_token != '!') return; advanceToken(lexer, TRUE); if (lexer->cur_token != TOKEN_IDENT) return; addTag(lexer->token_str, NULL, K_MACRO, lexer->line, lexer->pos, scope, parent_kind); skipMacro(lexer); }
/* * Rust is very liberal with nesting, so this function is used pretty much for any block */ static void parseBlock (lexerState *lexer, boolean delim, int kind, vString *scope) { int level = 1; if (delim) { if (lexer->cur_token != '{') return; advanceToken(lexer, TRUE); } while (lexer->cur_token != TOKEN_EOF) { if (lexer->cur_token == TOKEN_IDENT) { size_t old_scope_len = vStringLength(scope); if (strcmp(lexer->token_str->buffer, "fn") == 0) { parseFn(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "mod") == 0) { parseMod(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "static") == 0) { parseStatic(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "trait") == 0) { parseTrait(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "type") == 0) { parseType(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "impl") == 0) { parseImpl(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "struct") == 0) { parseStructOrEnum(lexer, scope, kind, TRUE); } else if(strcmp(lexer->token_str->buffer, "enum") == 0) { parseStructOrEnum(lexer, scope, kind, FALSE); } else if(strcmp(lexer->token_str->buffer, "macro_rules") == 0) { parseMacroRules(lexer, scope, kind); } else { advanceToken(lexer, TRUE); if (lexer->cur_token == '!') { skipMacro(lexer); } } resetScope(scope, old_scope_len); } else if (lexer->cur_token == '{') { level++; advanceToken(lexer, TRUE); } else if (lexer->cur_token == '}') { level--; advanceToken(lexer, TRUE); } else if (lexer->cur_token == '\'') { /* Skip over the 'static lifetime, as it confuses the static parser above */ advanceToken(lexer, TRUE); if (lexer->cur_token == TOKEN_IDENT && strcmp(lexer->token_str->buffer, "static") == 0) advanceToken(lexer, TRUE); } else { advanceToken(lexer, TRUE); } if (delim && level <= 0) break; } }
static void tagNameList (tokenInfo* token, int c) { verilogKind localKind; boolean repeat; /* Many keywords can have bit width. * reg [3:0] net_name; * inout [(`DBUSWIDTH-1):0] databus; */ if (c == '(') c = skipPastMatch ("()"); c = skipWhite (c); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '#') { c = vGetc (); if (c == '(') c = skipPastMatch ("()"); } c = skipWhite (c); do { repeat = FALSE; while (c == '`' && c != EOF) { c = skipMacro (c); } if (isIdentifierCharacter (c)) { readIdentifier (token, c); localKind = getKind (token); /* Create tag in case name is not a known kind ... */ if (localKind == K_UNDEFINED) { createTag (token); } /* ... or else continue searching for names */ else { /* Update kind unless it's a port or an ignored keyword */ if (token->kind != K_PORT && localKind != K_IGNORE) { token->kind = localKind; } repeat = TRUE; } } else break; c = skipWhite (vGetc ()); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '=') { c = skipWhite (vGetc ()); if (c == '{') skipPastMatch ("{}"); else { /* Skip until end of current name, kind or parameter list definition */ do c = vGetc (); while (c != EOF && c != ',' && c != ';' && c != ')'); } } if (c == ',') { c = skipWhite (vGetc ()); repeat = TRUE; } } while (repeat); vUngetc (c); }
static void processPortList (int c) { if ((c = skipWhite (c)) == '(') { tokenInfo *token = newToken (); /* Get next non-whitespace character after ( */ c = skipWhite (vGetc ()); while (c != ';' && c != EOF) { if (c == '[') { c = skipPastMatch ("[]"); } else if (c == '(') { c = skipPastMatch ("()"); } else if (c == '{') { c = skipPastMatch ("{}"); } else if (c == '`') { c = skipMacro (c); } else if (c == '=') { /* Search for next port or end of port declaration */ while (c != ',' && c != ')' && c != EOF) { c = skipWhite (vGetc ()); } } else if (isIdentifierCharacter (c)) { readIdentifier (token, c); updateKind (token); if (token->kind == K_UNDEFINED) { /* Only add port name if it is the last keyword. * First keyword can be a dynamic type, like a class name */ c = skipWhite (vGetc ()); if (! isIdentifierCharacter (c) || c == '`') { verbose ("Found port: %s\n", vStringValue (token->name)); token->kind = K_PORT; createTag (token); } } else { c = skipWhite (vGetc ()); } } else { c = skipWhite (vGetc ()); } } if (! isIdentifierCharacter (c)) vUngetc (c); deleteToken (token); } }