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

📄 preprocessor.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            else#endif                symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem);        }    }    symbols += Symbol(); // eof symbol    return symbols;}void Preprocessor::substituteMacro(const MacroName &macro, Symbols &substituted, MacroSafeSet safeset){    Symbols saveSymbols = symbols;    int saveIndex = index;    symbols = macros.value(macro).symbols;    index = 0;    safeset += macro;    substituteUntilNewline(substituted, safeset);    symbols = saveSymbols;    index = saveIndex;}void Preprocessor::substituteUntilNewline(Symbols &substituted, MacroSafeSet safeset){    while (hasNext()) {        Token token = next();        if (token == PP_IDENTIFIER) {            MacroName macro = symbol();            if (macros.contains(macro) && !safeset.contains(macro)) {                substituteMacro(macro, substituted, safeset);                continue;            }        } else if (token == PP_DEFINED) {            test(PP_LPAREN);            next(PP_IDENTIFIER);            Symbol definedOrNotDefined = symbol();            definedOrNotDefined.token = macros.contains(definedOrNotDefined)? PP_MOC_TRUE : PP_MOC_FALSE;            substituted += definedOrNotDefined;            test(PP_RPAREN);            continue;        } else if (token == PP_NEWLINE) {            substituted += symbol();            break;        }        substituted += symbol();    }}class PP_Expression : public Parser{public:    int value() { index = 0; return unary_expression_lookup() ?  conditional_expression() : 0; }    int conditional_expression();    int logical_OR_expression();    int logical_AND_expression();    int inclusive_OR_expression();    int exclusive_OR_expression();    int AND_expression();    int equality_expression();    int relational_expression();    int shift_expression();    int additive_expression();    int multiplicative_expression();    int unary_expression();    bool unary_expression_lookup();    int primary_expression();    bool primary_expression_lookup();};int PP_Expression::conditional_expression(){    int value = logical_OR_expression();    if (test(PP_QUESTION)) {        int alt1 = conditional_expression();        int alt2 = test(PP_COLON) ? conditional_expression() : 0;        return value ? alt1 : alt2;    }    return value;}int PP_Expression::logical_OR_expression(){    int value = logical_AND_expression();    if (test(PP_OROR))        return logical_OR_expression() || value;    return value;}int PP_Expression::logical_AND_expression(){    int value = inclusive_OR_expression();    if (test(PP_ANDAND))        return logical_AND_expression() && value;    return value;}int PP_Expression::inclusive_OR_expression(){    int value = exclusive_OR_expression();    if (test(PP_OR))        return value | inclusive_OR_expression();    return value;}int PP_Expression::exclusive_OR_expression(){    int value = AND_expression();    if (test(PP_HAT))        return value ^ exclusive_OR_expression();    return value;}int PP_Expression::AND_expression(){    int value = equality_expression();    if (test(PP_AND))        return value & AND_expression();    return value;}int PP_Expression::equality_expression(){    int value = relational_expression();    switch (next()) {    case PP_EQEQ:        return value == equality_expression();    case PP_NE:        return value != equality_expression();    default:        prev();        return value;    }}int PP_Expression::relational_expression(){    int value = shift_expression();    switch (next()) {    case PP_LANGLE:        return value < relational_expression();    case PP_RANGLE:        return value > relational_expression();    case PP_LE:        return value <= relational_expression();    case PP_GE:        return value >= relational_expression();    default:        prev();        return value;    }}int PP_Expression::shift_expression(){    int value = additive_expression();    switch (next()) {    case PP_LTLT:        return value << shift_expression();    case PP_GTGT:        return value >> shift_expression();    default:        prev();        return value;    }}int PP_Expression::additive_expression(){    int value = multiplicative_expression();    switch (next()) {    case PP_PLUS:        return value + additive_expression();    case PP_MINUS:        return value - additive_expression();    default:        prev();        return value;    }}int PP_Expression::multiplicative_expression(){    int value = unary_expression();    switch (next()) {    case PP_STAR:        return value * multiplicative_expression();    case PP_PERCENT:    {        int remainder = multiplicative_expression();        return remainder ? value % remainder : 0;    }    case PP_SLASH:    {        int div = multiplicative_expression();        return div ? value / div : 0;    }    default:        prev();        return value;    };}int PP_Expression::unary_expression(){    switch (next()) {    case PP_PLUS:        return unary_expression();    case PP_MINUS:        return -unary_expression();    case PP_NOT:        return !unary_expression();    case PP_TILDE:        return ~unary_expression();    case PP_MOC_TRUE:        return 1;    case PP_MOC_FALSE:        return 0;    default:        prev();        return primary_expression();    }}bool PP_Expression::unary_expression_lookup(){    Token t = lookup();    return (primary_expression_lookup()            || t == PP_PLUS            || t == PP_MINUS            || t == PP_NOT            || t == PP_TILDE            || t == PP_DEFINED);}int PP_Expression::primary_expression(){    int value;    if (test(PP_LPAREN)) {        value = conditional_expression();        test(PP_RPAREN);    } else {        next();        value = lexem().toInt(0, 0);    }    return value;}bool PP_Expression::primary_expression_lookup(){    Token t = lookup();    return (t == PP_IDENTIFIER            || t == PP_INTEGER_LITERAL            || t == PP_FLOATING_LITERAL            || t == PP_MOC_TRUE            || t == PP_MOC_FALSE            || t == PP_LPAREN);}int Preprocessor::evaluateCondition(){    PP_Expression expression;    expression.currentFilenames = currentFilenames;    substituteUntilNewline(expression.symbols);    return expression.value();}void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed){    currentFilenames.push(filename);    preprocessed.reserve(preprocessed.size() + symbols.size());    while (hasNext()) {        Token token = next();        switch (token) {        case PP_INCLUDE:        {            int lineNum = symbol().lineNum;            QByteArray include;            bool local = false;            if (test(PP_STRING_LITERAL)) {                local = lexem().startsWith('\"');                include = unquotedLexem();            } else                continue;            until(PP_NEWLINE);            // #### stringery            QFileInfo fi;            if (local)                fi.setFile(QFileInfo(QString::fromLocal8Bit(filename)).dir(), QString::fromLocal8Bit(include));            for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) {                const IncludePath &p = Preprocessor::includes.at(j);                if (p.isFrameworkPath) {                    const int slashPos = include.indexOf('/');                    if (slashPos == -1)                        continue;                    QByteArray frameworkCandidate = include.left(slashPos);                    frameworkCandidate.append(".framework/Headers/");                    fi.setFile(QString::fromLocal8Bit(p.path + "/" + frameworkCandidate), QString::fromLocal8Bit(include.mid(slashPos + 1)));                } else {                    fi.setFile(QString::fromLocal8Bit(p.path), QString::fromLocal8Bit(include));                }            }            if (!fi.exists() || fi.isDir())                continue;            include = fi.filePath().toLocal8Bit();            if (Preprocessor::preprocessedIncludes.contains(include))                continue;            Preprocessor::preprocessedIncludes.insert(include);            QFile file(QString::fromLocal8Bit(include));            if (!file.open(QFile::ReadOnly))                continue;            QByteArray input = file.readAll();            file.close();            if (input.isEmpty())                continue;            Symbols saveSymbols = symbols;            int saveIndex = index;            // phase 1: get rid of backslash-newlines            input = cleaned(input);            // phase 2: tokenize for the preprocessor            symbols = tokenize(input);            input.clear();            index = 0;            // phase 3: preprocess conditions and substitute macros            preprocessed += Symbol(0, MOC_INCLUDE_BEGIN, include);            preprocess(include, preprocessed);            preprocessed += Symbol(lineNum, MOC_INCLUDE_END, include);            symbols = saveSymbols;            index = saveIndex;            continue;        }        case PP_DEFINE:        {            next(IDENTIFIER);            QByteArray name = lexem();            int start = index;            until(PP_NEWLINE);            Macro macro;            macro.symbols.reserve(index - start - 1);            for (int i = start; i < index - 1; ++i)                macro.symbols += symbols.at(i);            macros.insert(name, macro);            continue;        }        case PP_UNDEF: {            next(IDENTIFIER);            QByteArray name = lexem();            until(PP_NEWLINE);            macros.remove(name);            continue;        }        case PP_IDENTIFIER:        {//             if (macros.contains(symbol()))//                 ;        }            // we _could_ easily substitute macros by the following            // four lines, but we choose not to.            /*            if (macros.contains(sym.lexem())) {                preprocessed += substitute(macros, symbols, i);                continue;            }            */            break;        case PP_HASH:            until(PP_NEWLINE);            continue; // skip unknown preprocessor statement        case PP_IFDEF:        case PP_IFNDEF:        case PP_IF:            while (!evaluateCondition()) {                if (!skipBranch())                    break;                if (test(PP_ELIF)) {                } else {                    until(PP_NEWLINE);                    break;                }            }            continue;        case PP_ELIF:        case PP_ELSE:            skipUntilEndif();            // fall through        case PP_ENDIF:            until(PP_NEWLINE);            continue;        case SIGNALS:        case SLOTS: {            Symbol sym = symbol();            if (macros.contains("QT_NO_KEYWORDS"))                sym.token = IDENTIFIER;            else                sym.token = (token == SIGNALS ? Q_SIGNALS_TOKEN : Q_SLOTS_TOKEN);            preprocessed += sym;        } continue;        default:            break;        }        preprocessed += symbol();    }    currentFilenames.pop();}Symbols Preprocessor::preprocessed(const QByteArray &filename, FILE *file){    QFile qfile;    qfile.open(file, QFile::ReadOnly);    QByteArray input = qfile.readAll();    if (input.isEmpty())        return symbols;        // phase 1: get rid of backslash-newlines    input = cleaned(input);    // phase 2: tokenize for the preprocessor    symbols = tokenize(input);#if 0    for (int j = 0; j < symbols.size(); ++j)        fprintf(stderr, "line %d: %s(%s)\n",               symbols[j].lineNum,               symbols[j].lexem().constData(),               tokenTypeName(symbols[j].token));#endif    // phase 3: preprocess conditions and substitute macros    Symbols result;    preprocess(filename, result);#if 0    for (int j = 0; j < result.size(); ++j)        fprintf(stderr, "line %d: %s(%s)\n",               result[j].lineNum,               result[j].lexem().constData(),               tokenTypeName(result[j].token));#endif    return result;}void Preprocessor::until(Token t){    while(hasNext() && next() != t)        ;}

⌨️ 快捷键说明

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