void addLogSourceEntry(const QString &text, const TokenContainer &tokenContainer, const int index) { Logger *logger = Logger::instance(); int line = tokenContainer.line(index); int col = tokenContainer.column(index); SourcePointLogEntry *logEntry = new SourcePointLogEntry(QLatin1String("Info"), QLatin1String("Porting"), logger->globalState.value(QLatin1String("currentFileName")), line, col, text); logger->addEntry(logEntry); }
bool GenericTokenReplacement::doReplace(const TokenContainer &tokenContainer, int index, TextReplacements &textReplacements) { QByteArray tokenText = tokenContainer.text(index); if(tokenText == oldToken){ addLogSourceEntry(QString::fromLatin1(tokenText + QByteArray(" -> ") + newToken), tokenContainer, index); TokenEngine::Token token = tokenContainer.token(index); textReplacements.insert(newToken, token.start, token.length); return true; } return false; }
QVector<Type> RppLexer::lex(const TokenContainer &tokenContainer) { QVector<Type> tokenTypes; const int numTokens = tokenContainer.count(); tokenTypes.reserve(numTokens); QByteArray text = tokenContainer.fullText(); m_buffer = text.constData(); for(int t=0; t<numTokens; ++t) { TokenEngine::Token token = tokenContainer.token(t); tokenTypes.append(indentify(token.start, token.length)); } return tokenTypes; }
/* Replace a class name token. If the class name is a scope specifier (a "qualifier") in a qualified name, we check if qualified name will be replaced by a porting rule. If so, we don't do the class name replacement. */ bool ClassNameReplacement::doReplace(const TokenContainer &tokenContainer, int index, TextReplacements &textReplacements) { QByteArray tokenText = tokenContainer.text(index); if(tokenText != oldToken) return false; QualifiedNameParser nameParser(tokenContainer, index); if(nameParser.isPartOfQualifiedName() && nameParser.peek(QualifiedNameParser::Right) != -1) { int nameTokenIndex = nameParser.peek(QualifiedNameParser::Right); QByteArray name = tokenContainer.text(nameTokenIndex); TextReplacements textReplacements; QList<TokenReplacement*> tokenReplacements = PortingRules::instance()->getTokenReplacementRules(); bool changed = false; foreach(TokenReplacement *tokenReplacement, tokenReplacements) { changed = tokenReplacement->doReplace(tokenContainer, nameTokenIndex, textReplacements); if(changed) break; }
void RppTreeEvaluator::evaluateText(const Text *textLine) { const int numTokens = textLine->count(); const TokenContainer tokenContainer = textLine->text().tokenContainer(0); int t = 0; int startTokenRun = 0; while(t < numTokens) { const Token *currentToken = textLine->token(t); int currentContainerIndex = currentToken->index(); //handle macro replacements if(currentToken->toIdToken()) { const int tokenIndex = currentToken->index(); const QByteArray tokenText = tokenContainer.tempText(tokenIndex); if(m_activeDefinitions->contains(tokenText)) { //crate section TokenSection section(tokenContainer, textLine->token(startTokenRun)->index(), t - startTokenRun); m_tokenSections.append(section); //evaluate macro const int oldContainerIndex = currentContainerIndex; TokenContainer evaluatedText = evaluateMacro(tokenContainer, currentContainerIndex); TokenSection evalSection(evaluatedText, 0, evaluatedText.count()); m_tokenSections.append(evalSection); t += currentContainerIndex - oldContainerIndex; startTokenRun = t; } ++t; continue; } //handle comments if(currentToken->toLineComment() || currentToken->toMultiLineComment()) { //create section TokenSection section(tokenContainer, textLine->token(startTokenRun)->index(), t - startTokenRun ); m_tokenSections.append(section); t++; //skip comment startTokenRun = t; t++; continue; } // handle escaped newlines if (currentContainerIndex + 1 < numTokens) { const TokenTempRef tokenRef1 = tokenContainer.tokenTempRef(currentContainerIndex); const TokenTempRef tokenRef2 = tokenContainer.tokenTempRef(currentContainerIndex + 1); // This is i slight hack. We want to check if the next token is a newline token, // but since we don't have any lexical info at this point we just check if it starts // with \r or \n if (tokenRef1.at(0) == '\\' && (tokenRef2.at(0) == '\n' || tokenRef2.at(0) == '\r')) { //create section TokenSection section(tokenContainer, textLine->token(startTokenRun)->index(), t - startTokenRun ); m_tokenSections.append(section); t += 2; startTokenRun = t; t++; continue; } } t++; } //round up any tokens at the end and put them in a section if(t - startTokenRun > 1) { TokenSection section(tokenContainer, textLine->token(startTokenRun)->index(), t - startTokenRun ); m_tokenSections.append(section); } m_tokenSections.append(*newlineSection); }
/* Recursively evaluates an Expression */ int RppTreeEvaluator::evaluateExpression(Expression *expression) { if (IntLiteral *e = expression->toIntLiteral()) { return e->value(); } else if (StringLiteral *e = expression->toStringLiteral()) { return e->value().size(); } else if (MacroReference *e = expression->toMacroReference()) { switch(e->type()) { case MacroReference::DefinedRef: { return m_activeDefinitions->contains(e->name().fullText()) ? 1 : 0; } case MacroReference::ValueRef: { const QByteArray identifier = e->name().fullText(); if (m_activeDefinitions->contains(identifier)) { int token = e->name().containerIndex(0); TokenContainer value = evaluateMacro(e->name().tokenContainer(token), token); return QString(QLatin1String(value.fullText())).toInt(0, 0); } else { return 0; // error } } default: Q_ASSERT(0); } } else if (MacroFunctionReference *e = expression->toMacroFunctionReference()) { Q_UNUSED(e); //TODO handle MacroFunctionReference // DefineDirective *def = e->findDefinition(e->name()); // Q_ASSERT(def->toMacroFunctionDefinition()); // qWarning("not implemented yet"); return 0; } else if (UnaryExpression *e = expression->toUnaryExpression()) { int result = evaluateExpression(e->expression()); switch (e->op()) { case '+': return + result; case '-': return - result; case '!': return ! result; case '~': return ~ result; default: Q_ASSERT(0); } } else if (BinaryExpression *e = expression->toBinaryExpression()) { int v1 = evaluateExpression(e->leftExpression()); int v2 = evaluateExpression(e->rightExpression()); switch (e->op()) { case '/': { return v2 ? v1 / v2 : 0; } //avoid division by zero case '*': return v1 * v2; case '%': { return v2 ? v1 % v2 : 0; } //avoid modulus by zero case '+': return v1 + v2; case '-': return v1 - v2; case '<': return v1 < v2; case '>': return v1 > v2; case '&': return v1 & v2; case '^': return v1 ^ v2; case '|': return v1 | v2; case Expression::LtEqOp: return v1 <= v2; case Expression::GtEqOp: return v1 >= v2; case Expression::EqOp: return v1 == v2; case Expression::NotEqOp: return v1 != v2; case Expression::AndOp: return v1 && v2; case Expression::OrOp: return v1 || v2; case Expression::LShiftOp: return v1 << v2; case Expression::RShiftOp: return v1 >> v2; default: Q_ASSERT(0); } } else if ( ConditionalExpression *e = expression->toConditionalExpression()){