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

📄 rpp.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 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 "rpp.h"#include "rppexpressionbuilder.h"using namespace TokenEngine;namespace Rpp{Preprocessor::Preprocessor(){}Source *Preprocessor::parse(const TokenEngine::TokenContainer &tokenContainer,                            const QVector<Type> &tokenTypeList, TypedPool<Item> *memoryPool){    m_memoryPool = memoryPool;    Source *m_source = createNode<Source>(m_memoryPool); //node whith no parent    m_tokenContainer = tokenContainer;    m_tokenTypeList = tokenTypeList;    lexerTokenIndex = 0;    numTokens = m_tokenContainer.count();    if(m_tokenContainer.count() != tokenTypeList.count()) {        emit error("Error", "Internal error in preprocessor: Number of tokens is not equal to number of types in type list");        return m_source;    }    if(tokenTypeList.isEmpty()) {    //    emit error("Warning:", "Trying to parse empty source file");        return m_source;    }    Q_ASSERT(m_source->toItemComposite());    parseGroup(m_source);    return m_source;}// group-part// group group-partbool Preprocessor::parseGroup(Item *group){    Q_ASSERT(group->toItemComposite());    bool gotGroup = false;    while(lexerTokenIndex < numTokens) {        if (!parseGroupPart(group))            break;        gotGroup = true;    }    return gotGroup;}//if-section        (# if / # ifdef / #ifndef )//control-line      ( #include / etc )//# non-directive   ( # text newline//text-line         (text newline )bool Preprocessor::parseGroupPart(Item *group){    //cout << "parse group part" << endl;    Q_ASSERT(group->toItemComposite());    //look up first significant token    Type token = lookAhead();    if(token == Token_eof)        return false;    //look for '#'    if(token != Token_preproc)        return parseTextLine(group);    //look up first significant token after the '#'    token = lookAheadSkipHash();    if(token == Token_eof)        return false;    // Check if we are at the end of a group. This is not an neccesarely an    // error, it happens when we reach an #endif for example.    if (token == Token_directive_elif || token == Token_directive_else ||        token == Token_directive_endif)        return false;    // if-section?    if(token == Token_directive_if || token == Token_directive_ifdef ||        token == Token_directive_ifndef)        return parseIfSection(group);    // control-line?    if (token == Token_directive_define)        return parseDefineDirective(group);    if (token ==  Token_directive_undef)        return parseUndefDirective(group);    if (token ==  Token_directive_include)        return parseIncludeDirective(group);    if (token == Token_directive_error)        return parseErrorDirective(group);    if (token ==  Token_directive_pragma)        return parsePragmaDirective(group);    return parseNonDirective(group);}// if-section -> if-group elif-groups[opt] else-group[opt] endif-linebool Preprocessor::parseIfSection(Item *group){   // cout << "parse if section" << endl ;    Q_ASSERT(group->toItemComposite());    IfSection *ifSection = createNode<IfSection>(m_memoryPool, group);    group->toItemComposite()->add(ifSection);    if (!parseIfGroup(ifSection))        return false;    Type type = lookAheadSkipHash();    if(type == Token_directive_elif)        if(!parseElifGroups(ifSection))            return false;    type = lookAheadSkipHash();    if(type == Token_directive_else)        if(!parseElseGroup(ifSection))            return false;    return parseEndifLine(ifSection);}bool Preprocessor::parseNonDirective(Item *group){ //  cout << "parsenondirective" << endl;    Q_ASSERT(group->toItemComposite());    TokenSection tokenSection = readLine();    if(tokenSection.count() == 0)        return false;    NonDirective *nonDirective = createNode<NonDirective>(m_memoryPool, group);    group->toItemComposite()->add(nonDirective);    nonDirective->setTokenSection(tokenSection);    return true;}bool Preprocessor::parseTextLine(Item *group){    //cout << "parsetextline" << endl;    Q_ASSERT(group->toItemComposite());    const TokenSection tokenSection = readLine();   // cout << tokenSection.fullText().constData() << endl;    if(tokenSection.count() == 0)        return false;    Text *text = createNode<Text>(m_memoryPool, group);    group->toItemComposite()->add(text);    text->setTokenSection(tokenSection);    // Create Token-derived nodes and atach to text    QVector<Token *> tokens;    tokens.reserve(tokenSection.count());    for (int t = 0; t < tokenSection.count(); ++t) {        Token *node = 0;        const int containerIndex = tokenSection.containerIndex(t);        switch(m_tokenTypeList.at(containerIndex)) {            case Token_identifier:            case Token_defined:            case Token_directive_if:            case Token_directive_elif:            case Token_directive_else:            case Token_directive_undef:            case Token_directive_endif:            case Token_directive_ifdef:            case Token_directive_ifndef:            case Token_directive_define:            case Token_directive_include:                node = createNode<IdToken>(m_memoryPool, text);            break;            case Token_line_comment:                node = createNode<LineComment>(m_memoryPool, text);            break;            case Token_multiline_comment:                node = createNode<MultiLineComment>(m_memoryPool, text);            break;            case Token_whitespaces:            case Token_char_literal:            case Token_string_literal:            default:                node = createNode<NonIdToken>(m_memoryPool, text);            break;        }        Q_ASSERT(node);        node->setToken(containerIndex);        tokens.append(node);    }    text->setTokens(tokens);    return true;}// if-group -> ifDirective// if-group -> ifdefDirevtive// if-group -> ifndefDirevtivebool Preprocessor::parseIfGroup(IfSection *ifSection){    //  cout << "parse if group" << endl;    Q_ASSERT(ifSection->toItemComposite());    bool result;    const Type type = lookAheadSkipHash();    if (type == Token_directive_ifdef) {        IfdefDirective *d = createNode<IfdefDirective>(m_memoryPool, ifSection);        result = parseIfdefLikeDirective(d);        ifSection->setIfGroup(d);    } else if (type == Token_directive_ifndef) {        IfndefDirective *d = createNode<IfndefDirective>(m_memoryPool, ifSection);        result = parseIfdefLikeDirective(d);        ifSection->setIfGroup(d);    } else  if (type == Token_directive_if) {        IfDirective *d = createNode<IfDirective>(m_memoryPool, ifSection);        result = parseIfLikeDirective(d);        ifSection->setIfGroup(d);    } else {        result = false;    }    return result;}bool Preprocessor::parseElifGroups(IfSection *ifSection){    //cout << "parse ElifGroups" << endl;    bool gotElif = false;    while(lookAheadSkipHash() == Token_directive_elif ) {        if (!parseElifGroup(ifSection))            break;        gotElif = true;    }    return gotElif;}bool Preprocessor::parseElifGroup(IfSection *ifSection){    //cout << "parse ElifGroup" << endl;    ElifDirective *elifDirective = createNode<ElifDirective>(m_memoryPool, ifSection);    ifSection->addElifGroup(elifDirective);    return parseIfLikeDirective(elifDirective);}bool Preprocessor::parseElseGroup(IfSection *ifSection){    //cout << "parse else group" << endl;    TokenSection tokenSection = readLine();    if(tokenSection.count() == 0)        return false;    ElseDirective *elseDirective = createNode<ElseDirective>(m_memoryPool, ifSection);    ifSection->setElseGroup(elseDirective);    elseDirective->setTokenSection(tokenSection);    parseGroup(elseDirective);    return true;}//# endif newlinebool Preprocessor::parseEndifLine(IfSection *ifSection){    //cout << "parse endifline" << endl;    TokenSection tokenSection = readLine();    if(tokenSection.count() == 0)        return false;    EndifDirective *endifDirective = createNode<EndifDirective>(m_memoryPool, ifSection);    ifSection->setEndifLine(endifDirective);    endifDirective->setTokenSection(tokenSection);    return true;}//parses an "ifdef-like" directive, like #ifdef and #ifndef :)//# ifdef identifier newline group[opt]bool Preprocessor::parseIfdefLikeDirective(IfdefLikeDirective *node){    Q_ASSERT(node->toItemComposite());    const TokenSection tokenSection = readLine();    const QVector<int> cleanedLine = cleanTokenRange(tokenSection);    if(cleanedLine.count() < 3)        return false;    node->setTokenSection(tokenSection);    node->setIdentifier(TokenList(m_tokenContainer, QVector<int>() << cleanedLine.at(2)));    parseGroup(node);    return true;}//# if constant-expression newline group[opt]bool Preprocessor::parseIfLikeDirective(IfLikeDirective *node){    //cout << "parse if-like directive" << endl;    Q_ASSERT(node->toItemComposite());    TokenSection tokenSection = readLine();    QVector<int> cleanedSection = cleanTokenRange(tokenSection);    if(cleanedSection.count() < 3)        return false;    cleanedSection.erase(cleanedSection.begin(), cleanedSection.begin() + 2); //remove # and if    cleanedSection.pop_back(); //remove endl;    const TokenList sectionList(m_tokenContainer, cleanedSection);    ExpressionBuilder expressionBuilder(sectionList, m_tokenTypeList, m_memoryPool);    Expression *expr = expressionBuilder.parse();    node->setTokenSection(tokenSection);    node->setExpression(expr);    parseGroup(node);    return true;}/*   # define identifier                               replacement-list new-line   # define identifier lparen identifier-list[opt] ) replacement-list new-line   # define identifier lparen ... )                  replacement-list new-line   # define identifier lparen identifier-list, ... ) replacement-list new-line*/bool Preprocessor::parseDefineDirective(Item *group){    Q_ASSERT(group->toItemComposite());    const TokenSection line = readLine();    const QVector<int> cleanedLine = cleanTokenRange(line);    if(cleanedLine.count() < 3)        return false;    // get identifier

⌨️ 快捷键说明

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