static void tagNameList (const vhdlKind kind, int c) { Assert (isIdentifierCharacter (c)); if (isIdentifierCharacter (c)) { readIdentifier (TagName, c); makeSimpleTag (TagName, VhdlKinds, kind); } }
static void findTag (vString *const name) { int c = '\0'; vhdlKind kind; vStringCopyToLower (Keyword, name); kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl); if (kind == K_UNDEFINED) { c = skipWhite (vGetc ()); vStringCopyS(Lastname,vStringValue(name)); if (c == ':') { c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (name, c); vStringCopyToLower (Keyword, name); lookupKeyword (vStringValue (Keyword), Lang_vhdl); kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl); if (kind == K_PROCESS || kind == K_BLOCK || kind == K_PORT) { makeSimpleTag (Lastname, VhdlKinds, kind); } } } else { vUngetc (c); } } else { if (kind == K_SIGNAL) { while (c!=':') { c = skipWhite (vGetc ()); if (c==',') c = vGetc (); if (isIdentifierCharacter (c)) tagNameList (kind, c); else break; c = vGetc (); } } else if (kind == K_PROCESS || kind == K_BLOCK) { vStringCopyS(TagName,"unnamed"); makeSimpleTag (TagName, VhdlKinds, kind); } else { c = skipWhite (vGetc ()); if (c=='\"') c = vGetc (); if (isIdentifierCharacter (c)) tagNameList (kind, c); } } }
static bool readIdentifier (vString *const name, int c) { vStringClear (name); if (isIdentifierCharacter (c)) { while (isIdentifierCharacter (c)) { vStringPut (name, c); c = vGetc (); } vUngetc (c); } return (bool)(name->length > 0); }
static bool readIdentifier (tokenInfo *const token, int c) { vStringClear (token->name); if (isIdentifierCharacter (c)) { while (isIdentifierCharacter (c)) { vStringPut (token->name, c); c = vGetc (); } vUngetc (c); token->lineNumber = getInputLineNumber (); token->filePosition = getInputFilePosition (); } return (bool)(vStringLength (token->name) > 0); }
static void findTag (vString *const name) { const verilogKind kind = (verilogKind) lookupKeyword (vStringValue (name), Lang_verilog); if (kind != K_UNDEFINED) { int c = skipWhite (vGetc ()); /* 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); if (isIdentifierCharacter (c)) tagNameList (kind, c); } }
static void processTypedef (tokenInfo *const token) { /*Note: At the moment, only identifies typedef name and not its contents */ int c; /* Get identifiers */ c = skipWhite (vGetc ()); while (isIdentifierCharacter (c)) { readIdentifier (token, c); c = skipWhite (vGetc ()); } /* Skip bus width definition */ if (c == '[') { skipPastMatch ("[]"); c = skipWhite (vGetc ()); } /* Skip typedef contents */ if (c == '{') { skipPastMatch ("{}"); c = skipWhite (vGetc ()); } /* Skip past class parameter override */ if (c == '#') { c = skipWhite (vGetc ()); if (c == '(') { skipPastMatch ("()"); } c = skipWhite (vGetc ()); } /* Read new typedef identifier */ if (isIdentifierCharacter (c)) { readIdentifier (token, c); } /* Use last identifier to create tag */ createTag (token); }
static void tagNameList (const verilogKind kind, int c) { vString *name = vStringNew (); bool repeat; Assert (isIdentifierCharacter (c)); do { repeat = false; if (isIdentifierCharacter (c)) { readIdentifier (name, c); makeSimpleTag (name, VerilogKinds, kind); } else break; c = skipWhite (vGetc ()); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '=') { c = skipWhite (vGetc ()); if (c == '{') skipPastMatch ("{}"); else { do c = vGetc (); while (c != ',' && c != ';'); } } if (c == ',') { c = skipWhite (vGetc ()); repeat = true; } else repeat = false; } while (repeat); vStringDelete (name); vUngetc (c); }
static void findVerilogTags (void) { tokenInfo *const token = newToken (); int c = '\0'; currentContext = newToken (); while (c != EOF) { c = vGetc (); c = skipWhite (c); switch (c) { /* Store current block name whenever a : is found * This is used later by any tag type that requires this information * */ case ':': vStringCopy (currentContext->blockName, token->name); break; /* Skip interface modport port declarations */ case '(': if (currentContext && currentContext->lastKind == K_MODPORT) { skipPastMatch ("()"); } break; /* Drop context on prototypes because they don't have an end * statement */ case ';': if (currentContext->scope && currentContext->scope->prototype) { verbose ("Dropping context %s\n", vStringValue (currentContext->name)); currentContext = popToken (currentContext); currentContext->prototype = FALSE; } /* Prototypes end at the end of statement */ if (currentContext->prototype) { currentContext->prototype = FALSE; } break; default : if (isIdentifierCharacter (c)) { readIdentifier (token, c); updateKind (token); findTag (token); } } } deleteToken (token); pruneTokens (currentContext); currentContext = NULL; }
static const unsigned char *parseIdentifier ( const unsigned char *cp, vString *const identifier) { vStringClear (identifier); while (isIdentifierCharacter ((int) *cp)) { vStringPut (identifier, (int) *cp); ++cp; } return cp; }
/***************************************************************************** Starting at ''cp'', parse an identifier into ''identifier''. *****************************************************************************/ const char *Parser_Perl::parseIdentifier (const char *cp, QString *identifier) const { std::string str; while (isIdentifierCharacter ((int)*cp)) { str+=*cp; ++cp; } identifier->append(str.c_str()); return cp; }
IDBKeyPathLexer::TokenType IDBKeyPathLexer::lexIdentifier(String& element) { StringView start = m_remainingText; if (!m_remainingText.isEmpty() && isIdentifierStartCharacter(m_remainingText[0])) m_remainingText = m_remainingText.substring(1); else return TokenError; while (!m_remainingText.isEmpty() && isIdentifierCharacter(m_remainingText[0])) m_remainingText = m_remainingText.substring(1); element = start.substring(0, start.length() - m_remainingText.length()).toString(); return TokenIdentifier; }
IDBKeyPathLexer::TokenType IDBKeyPathLexer::lexIdentifier(String& element) { unsigned start = m_index; if (m_index < m_length && isIdentifierStartCharacter(m_string[m_index])) ++m_index; else return TokenError; while (m_index < m_length && isIdentifierCharacter(m_string[m_index])) ++m_index; element = m_string.substring(start, m_index - start); return TokenIdentifier; }
IDBKeyPathLexer::TokenType IDBKeyPathLexer::lexIdentifier(String& element) { const UChar* start = m_ptr; if (m_ptr < m_end && isIdentifierStartCharacter(*m_ptr)) ++m_ptr; else return TokenError; while (m_ptr < m_end && isIdentifierCharacter(*m_ptr)) ++m_ptr; element = String(start, m_ptr - start); return TokenIdentifier; }
static void findTag (vString *const name) { const verilogKind kind = (verilogKind) lookupKeyword (vStringValue (name), Lang_verilog); if (kind == K_CONSTANT && vStringItem (name, 0) == '`') { /* Bug #961001: Verilog compiler directives are line-based. */ int c = skipWhite (vGetc ()); readIdentifier (name, c); makeSimpleTag (name, VerilogKinds, kind); /* Skip the rest of the line. */ do { c = vGetc(); } while (c != '\n'); vUngetc (c); } else if (kind != K_UNDEFINED) { int c = skipWhite (vGetc ()); /* 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); if (isIdentifierCharacter (c)) tagNameList (kind, c); } }
static int skipMacro (int c) { tokenInfo *token = newToken ();; if (c == '`') { /* Skip keyword */ if (isIdentifierCharacter (c = vGetc ())) { readIdentifier (token, c); c = vGetc (); /* Skip next keyword if macro is `ifdef or `ifndef or `elsif*/ if (strcmp (vStringValue (token->name), "ifdef") == 0 || strcmp (vStringValue (token->name), "ifndef") == 0 || strcmp (vStringValue (token->name), "elsif") == 0) { verbose ("%c\n", c); c = skipWhite (c); readIdentifier (token, c); c = vGetc (); verbose ("Skipping conditional macro %s\n", vStringValue (token->name)); } /* Skip macro functions */ else { c = skipWhite (c); if (c == '(') { c = skipPastMatch ("()"); } } } } deleteToken (token); return c; }
void Parser_Perl::parse() { QString continuation; QString *name=new QString(); QString parent; PerlSymbol *parentSymbol=NULL; const char *line; int line_skip = 0; char const *longStringLiteral = NULL; while ((line = (const char *) fileReadLine ()) != NULL) { const char *cp = line; char const *keyword; //int indent; cp = skipSpace (cp); if (*cp == '\0') /* skip blank line */ continue; /* Skip comment if we are not inside a multi-line string. */ if (*cp == '#' && !longStringLiteral) continue; /* Deal with line continuation. */ if (!line_skip) continuation=""; continuation+=QString(line); //vStringStripTrailing(continuation); cp = line = continuation.toLatin1().data(); cp = skipSpace (cp); line_skip = 0; /* Deal with def and class keywords. */ keyword = findDefinitionOrClass (cp); //printf("LINE_:%s\n",line); if (keyword) { bool found = false; bool is_class = false; if (!strncmp (keyword, "sub ", 4) && isspace(keyword[3])) { cp = skipSpace (keyword + 4); found = true; } else if (!strncmp (keyword, "package", 7) && isspace(keyword[7])) { cp = skipSpace (keyword + 7); found = true; is_class = true; } if (found) { PerlSymbol *symbol = NULL; if (is_class) { symbol = makeClass (cp, 0); parentSymbol=symbol; } else symbol = makeFunction(cp, name, parentSymbol); } } /* Find global and class variables */ #ifdef SHOW_VARIABLES //char const *variable = findVariable(line); char const* variable; if (variable) { const char *start = variable; vStringClear (name); while (isIdentifierCharacter ((int) *start)) { vStringPut (name, (int) *start); ++start; } vStringTerminate (name); PerlSymbol *symbol = NULL; PerlSymbol *parentSymbol = getParent(indent); symbol = new PerlSymbol(parentSymbol, vStringToQString(name)); symbol->setIndent(indent); symbol->setLine(this->getSourceLineNumber()); symbol->setIconType(Symbol::IconVar); } #endif /* Find and parse imports */ #ifdef SHOW_IMPORTS parseImports(line); #endif } /* Clean up all memory we allocated. */ if(name)delete name; }
/***************************************************************************** Skip an identifier. *****************************************************************************/ const char *Parser_Perl::skipIdentifier (const char *cp) { while (isIdentifierCharacter ((int) *cp)) cp++; return cp; }
int Lexer::nextTokenKind() { int token = Parser::Token_INVALID; if ( m_curpos >= m_contentSize ) { return 0; } QChar* it = m_content.data(); it += m_curpos; switch ( state() ) { case VariableValueState: it = ignoreWhitespaceAndComment( it ); m_tokenBegin = m_curpos; if( m_curpos < m_contentSize ) { if( it->unicode() == '\n' ) { popState(); createNewline( m_curpos ); token = Parser::Token_NEWLINE; }else if( it->unicode() == '\\' && isCont(it) ) { pushState(ContState); token = Parser::Token_CONT; }else if( it->unicode() == '"') { it++; m_curpos++; QChar* lastit = it; while( ( it->unicode() != '"' || lastit->unicode() == '\\' && it->unicode() == '"' ) && it->unicode() != '\n' && it->unicode() != '#' && !isCont( it ) && m_curpos < m_contentSize ) { lastit = it; it++; m_curpos++; } if( it->unicode() != '"' && it->unicode() != '#' ) { m_curpos--; } token = Parser::Token_VALUE; if( it->unicode() == '#' ) { m_tokenEnd = m_curpos - 1; do { it++; m_curpos++; }while( it->unicode() != '\n' && m_curpos < m_contentSize ); if( it->unicode() == '\n') { m_curpos--; } return token; } }else if( it->unicode() == '(' ) { unsigned int bracecount = 0; while( ( it->unicode() != ';' || bracecount > 0 ) && it->unicode() != '\n' && !isCont( it ) && m_curpos < m_contentSize ) { if( it->unicode() == '(' ) { bracecount++; }else if( it->unicode() == ')' && bracecount > 0 ) { bracecount--; } ++it; ++m_curpos; } if( it->unicode() != ';' ) { m_curpos--; } token = Parser::Token_VALUE; }else { while( !it->isSpace() && !isCont(it) && it->unicode() != '#' && m_curpos < m_contentSize ) { it++; m_curpos++; } m_curpos--; token = Parser::Token_VALUE; } } break; case FunctionArgState: m_tokenBegin = m_curpos; if( it->unicode() == '\n' ) { createNewline( m_curpos ); token = Parser::Token_NEWLINE; }else if( it->unicode() == '\\' && isCont(it) ) { pushState( ContState ); token = Parser::Token_CONT; }else if( it->unicode() == ',' ) { token = Parser::Token_COMMA; }else if( it->unicode() == ')' ) { popState(); token = Parser::Token_RPAREN; }else { unsigned int parentCount = 0; while( parentCount > 0 || ( it->unicode() != ')' && it->unicode() != ',' ) && m_curpos < m_contentSize ) { if( it->unicode() == ')' ) { parentCount--; }else if( it->unicode() == '(' ) { parentCount++; } ++it; ++m_curpos; } m_curpos--; token = Parser::Token_VALUE; } break; case ContState: it = ignoreWhitespaceAndComment( it ); m_tokenBegin = m_curpos; if( m_curpos < m_contentSize ) { if ( it->unicode() == '\n' ) { createNewline( m_curpos ); token = Parser::Token_NEWLINE; m_tokenEnd = m_curpos; popState(); QChar* temp = it; int newpos = m_curpos; do { temp++; newpos++; if(temp->unicode() == '#' ) { while( temp->unicode() != '\n' && newpos < m_contentSize ) { temp++; newpos++; } createNewline( m_curpos ); temp++; m_curpos = newpos; newpos++; } }while( temp->isSpace() && temp->unicode() != '\n' && m_curpos < m_contentSize ); m_curpos++; return token; } } break; case DefaultState: it = ignoreWhitespaceAndComment( it ); m_tokenBegin = m_curpos; if( m_curpos < m_contentSize ) { if ( isBeginIdentifierCharacter( it ) ) { token = Parser::Token_IDENTIFIER; while ( !it->isSpace() && isIdentifierCharacter( it ) && m_curpos < m_contentSize ) { it++; m_curpos++; } if( !isEndIdentifierCharacter( ( it-1 ) ) ) { token = Parser::Token_INVALID; } m_curpos--; } else { //Now the stuff that will generate a proper token QChar* c2 = m_curpos < m_contentSize ? it + 1 : 0 ; switch ( it->unicode() ) { case '|': token = Parser::Token_OR; break; case '!': token = Parser::Token_EXCLAM; break; case '(': pushState( FunctionArgState ); token = Parser::Token_LPAREN; break; case '{': token = Parser::Token_LBRACE; break; case '}': token = Parser::Token_RBRACE; break; case ':': token = Parser::Token_COLON; break; case '~': if ( c2 && c2->unicode() == '=' ) { pushState( VariableValueState ); m_curpos++; token = Parser::Token_TILDEEQ; } break; case '*': if ( c2 && c2->unicode() == '=' ) { pushState( VariableValueState ); m_curpos++; token = Parser::Token_STAREQ; } break; case '-': if ( c2 && c2->unicode() == '=' ) { pushState( VariableValueState ); m_curpos++; token = Parser::Token_MINUSEQ; } break; case '+': if ( c2 && c2->unicode() == '=' ) { pushState( VariableValueState ); m_curpos++; token = Parser::Token_PLUSEQ; } break; case '=': pushState( VariableValueState ); token = Parser::Token_EQUAL; break; case '\n': createNewline( m_curpos ); token = Parser::Token_NEWLINE; break; default: break; } } } break; default: token = Parser::Token_INVALID; break; } if ( m_curpos >= m_contentSize ) { return 0; } m_tokenEnd = m_curpos; m_curpos++; return token; }
static void processTypedef (tokenInfo *const token) { /*Note: At the moment, only identifies typedef name and not its contents */ int c; /* Get typedef type */ c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (token, c); /* A typedef class is just a prototype */ if (strcmp (vStringValue (token->name), "class") == 0) { currentContext->prototype = TRUE; } } /* Skip remaining identifiers */ c = skipWhite (vGetc ()); while (isIdentifierCharacter (c)) { readIdentifier (token, c); c = skipWhite (vGetc ()); } /* Skip bus width definition */ if (c == '[') { skipPastMatch ("[]"); c = skipWhite (vGetc ()); } /* Skip typedef contents */ if (c == '{') { skipPastMatch ("{}"); c = skipWhite (vGetc ()); } /* Skip past class parameter override */ if (c == '#') { c = skipWhite (vGetc ()); if (c == '(') { skipPastMatch ("()"); c = skipWhite (vGetc ()); } } /* Read typedef name */ if (isIdentifierCharacter (c)) { readIdentifier (token, c); } else { vUngetc (c); } /* Use last identifier to create tag */ createTag (token); }
void Tokenizer::insert(char ch) { bool insert = true; switch (mState) { case BufferState::ErrorState: { // If we are in an error token, switch to ready to // dispense if we encounter a token that is valid to // start an identifier if (canStartToken(ch)) { mReady = true; } } break; case BufferState::SpecialTokenState: { mReady = true; } break; case BufferState::WhiteSpaceState: { // if we are in a white space token, only something // besides a white space token will end our token if (!isWhitespace(ch)) { mReady = true; } } break; case BufferState::VariableOrKeywordState: { // If we are in an identifier, keyword, or condition, // only something besides a valid identifier // character will end the token if (!isIdentifierCharacter(ch)) { mReady = true; } } break; case BufferState::IntConstantState: { if (ch == '.') { mState = BufferState::FloatConstantState; } else if (!isDigit(ch)) { mReady = true; } } break; case BufferState::FloatConstantState: { if (!isDigit(ch)) { mReady = true; } } break; case BufferState::StringConstantState: { if (mEndOfString) { mReady = true; mEndOfString = false; } else if (mEscapeNextChar) { switch (ch) { case 'n': ch = '\n'; break; case 't': ch = '\t'; break; case 'r': ch = '\r'; break; case 'v': ch = '\v'; break; case 'a': ch = '\a'; break; case 'b': ch = '\b'; break; case 'f': ch = '\f'; break; case '\'': case '\"': case '?': case '\\': // do nothing break; default: abort(); break; } mEscapeNextChar = false; } else if (ch == '\"') { mEndOfString = true; } else if (ch == '\\') { mEscapeNextChar = true; insert = false; } } break; case BufferState::CommentState: { // a comment continues until the new line character if (ch == '\n') { mReady = true; } } break; case BufferState::OperatorState: { if (mBuffer.size() == 1 && mBuffer[0] == '-' && isDigit(ch)) { // Negative number special case mState = BufferState::IntConstantState; break; } string s = string(mBuffer.begin(), mBuffer.end()); int before = isOperatorSubstring(s); s.push_back(ch); int after = isOperatorSubstring(s); if (before && !after) { mReady = true; } } break; case BufferState::EmptyState: { // make the mBuffer mState appropriate for whatever we // are adding. mState = bufferType(ch); } break; } if (insert) { mBuffer.push_back(ch); } }
static void findTag (tokenInfo *const token) { if (currentContext->kind != K_UNDEFINED) { /* Drop context, but only if an end token is found */ dropContext (token); } if (token->kind == K_CONSTANT && vStringItem (token->name, 0) == '`') { /* Bug #961001: Verilog compiler directives are line-based. */ int c = skipWhite (vGetc ()); readIdentifier (token, c); createTag (token); /* Skip the rest of the line. */ do { c = vGetc(); } while (c != EOF && c != '\n'); vUngetc (c); } else if (token->kind == K_BLOCK) { /* Process begin..end blocks */ processBlock (token); } else if (token->kind == K_FUNCTION || token->kind == K_TASK) { /* Functions are treated differently because they may also include the * type of the return value. * Tasks are treated in the same way, although not having a return * value.*/ processFunction (token); } else if (token->kind == K_ASSERTION) { if (vStringLength (currentContext->blockName) > 0) { vStringCopy (token->name, currentContext->blockName); createTag (token); skipToSemiColon (); } } else if (token->kind == K_TYPEDEF) { processTypedef (token); } else if (token->kind == K_CLASS) { processClass (token); } else if (token->kind == K_IGNORE && isSingleStatement (token)) { currentContext->singleStat = TRUE; } else if (isVariable (token)) { int c = skipWhite (vGetc ()); tagNameList (token, c); } else if (token->kind != K_UNDEFINED && token->kind != K_IGNORE) { int c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (token, c); while (getKind (token) == K_IGNORE) { c = skipWhite (vGetc ()); readIdentifier (token, c); } createTag (token); /* Get port list if required */ c = skipWhite (vGetc ()); if (c == '(' && hasSimplePortList (token)) { processPortList (c); } else { vUngetc (c); } } } }
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 processClass (tokenInfo *const token) { /*Note: At the moment, only identifies typedef name and not its contents */ int c; tokenInfo *extra; tokenInfo *parameters = NULL; /* Get identifiers */ c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (token, c); c = skipWhite (vGetc ()); } /* Find class parameters list */ if (c == '#') { c = skipWhite (vGetc ()); if (c == '(') { parameters = newToken (); do { c = skipWhite (vGetc ()); readIdentifier (parameters, c); updateKind (parameters); verbose ("Found class parameter %s\n", vStringValue (parameters->name)); if (parameters->kind == K_UNDEFINED) { parameters->kind = K_CONSTANT; parameters = pushToken (parameters, newToken ()); c = vGetc(); while (c != ',' && c != ')' && c != EOF) { c = vGetc(); } } } while (c != ')' && c != EOF); c = vGetc (); parameters = popToken (parameters); } c = skipWhite (vGetc ()); } /* Search for inheritance information */ if (isIdentifierCharacter (c)) { extra = newToken (); readIdentifier (extra, c); c = skipWhite (vGetc ()); if (strcmp (vStringValue (extra->name), "extends") == 0) { readIdentifier (extra, c); vStringCopy (token->inheritance, extra->name); verbose ("Inheritance %s\n", vStringValue (token->inheritance)); } deleteToken (extra); } /* Use last identifier to create tag */ createTag (token); /* Add parameter list */ while (parameters) { createTag (parameters); parameters = popToken (parameters); } }
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); } }