⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpptreeevaluator.cpp

📁 QT 开发环境里面一个很重要的文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 2004-2006 Trolltech ASA. All rights reserved.** Copyright (C) 2001-2004 Roberto Raggi**** This file is part of the qt3to4 porting application of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "rpptreeevaluator.h"#include <QChar>#include <QtDebug>using namespace TokenEngine;namespace Rpp {RppTreeEvaluator::RppTreeEvaluator(){    QByteArray text(" ");    TokenEngine::Token token;    token.start = 0;    token.length = 1;    QVector<TokenEngine::Token> tokenList;    tokenList.append(token);    TokenContainer newLineContainer(text, tokenList, new TokenEngine::GeneratedInfo());    newlineSection= new TokenSection(newLineContainer, 0, 1);}RppTreeEvaluator::~RppTreeEvaluator(){    delete newlineSection;}TokenSectionSequence RppTreeEvaluator::evaluate(const Source *source,                                                DefineMap *activeDefinitions){    m_tokenSections.clear();    m_activeDefinitions = activeDefinitions;    evaluateSource(source);    return TokenSectionSequence(m_tokenSections);}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);}/*    Evaluates and ifsection by selecting which one of the if-elif-else    groups and then evaling that.*/void RppTreeEvaluator::evaluateIfSection(const IfSection *ifSection){    ConditionalDirective *ifGroup = ifSection->ifGroup();    if(evaluateCondition(ifGroup)) {        evaluateConditionalDirective(ifGroup);        return;    }    QVector<ConditionalDirective *> elifGroups = ifSection->elifGroups();    foreach(ConditionalDirective *elifGroup, elifGroups) {        if(evaluateCondition(elifGroup)) {            evaluateConditionalDirective(elifGroup);            return;        }    }    ConditionalDirective *elseGroup = ifSection->elseGroup();    if(elseGroup)        evaluateConditionalDirective(elseGroup);}/*    Evaluate an IncludeDirective by evaluating the Source for the included    file. The source is found by emitting the includeCallback signal, which    must be handled outside RppTreeEvaluator.*/void RppTreeEvaluator::evaluateIncludeDirective(const IncludeDirective *directive){    Source *currentSource = getParentSource(directive);    IncludeType includeType = includeTypeFromDirective(directive);    Source *newSource = 0;    emit includeCallback(newSource, currentSource, directive->filename(), includeType);    Q_ASSERT(newSource);    // If you get an assert here you probably                            // forgot to connect to the includeCallback signal    evaluateSource(newSource);}void RppTreeEvaluator::evaluateDefineDirective(const DefineDirective *directive){    m_tokenSections.append(*newlineSection);    m_activeDefinitions->insert(directive->identifier().fullText(), directive);}void RppTreeEvaluator::evaluateUndefDirective(const UndefDirective *directive){    m_tokenSections.append(*newlineSection);    const QByteArray text = directive->identifier().fullText();    m_activeDefinitions->remove(text);}/*    Evaluate the truth-value of an conditionalDirective*/bool RppTreeEvaluator::evaluateCondition(const ConditionalDirective *conditionalDirective){    if (IfDirective *ifDirective = conditionalDirective->toIfDirective())        return (evaluateExpression(ifDirective->expression()) != 0);    if (ElifDirective *elifDirective = conditionalDirective->toElifDirective())        return (evaluateExpression(elifDirective->expression()) != 0);    if (IfdefDirective *ifdefDirective = conditionalDirective->toIfdefDirective())        return m_activeDefinitions->contains(ifdefDirective->identifier().fullText());    if (IfndefDirective *ifndefDirective = conditionalDirective->toIfndefDirective())        return !m_activeDefinitions->contains(ifndefDirective->identifier().fullText());    else        return false; //error!}/*    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(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()){        return e->condition() ? evaluateExpression(e->leftExpression()) : evaluateExpression(e->rightExpression());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -