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

📄 parser.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** 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 "parser.h"#include "tokens.h"#include "errors.h"#include <QString>#include <QStringList>#include <QDateTime>#define TT (tokenStream->currentTokenText().data())#define ADVANCE(tk, descr) \{ \  if (tokenStream->lookAhead() != tk) { \    reportError(QString("'%1' expected found '%2'").arg(QString(descr)).arg(QString(tokenStream->currentTokenText()))); \      return false; \  } \  advance(); \}#define ADVANCE_NR(tk, descr) \  do { \    if (tokenStream->lookAhead() != tk) { \        reportError(i18n("'%1' expected found '%2'").arg(QString(descr)).arg(QString(tokenStream->currentTokenText()))); \    } \    else \        advance(); \  } while (0)#define CHECK(tk, descr) \  do { \    if (tokenStream->lookAhead() != tk) { \        return false; \    } \    advance(); \  } while (0)#define MATCH(tk, descr) \  do { \    if (tokenStream->lookAhead() != tk) { \        reportError(Errors::SyntaxError); \        return false; \    } \  } while (0)#define UPDATE_POS(_node, start, end) \  do { \      (_node)->setPosition(start, end); \  } while (0)#define AST_FROM_TOKEN(node, tk) \    AST *node = CreateNode<AST>(m_pool); \    UPDATE_POS(node, (tk), (tk)+1);#define DUMP_AST(node) \  do { \    fprintf(stderr, "\n=================================================\n"); \    for (int i=node->startToken(); i<node->endToken(); ++i) \       fprintf(stderr, "%s", tokenStream->tokenText(i).constData()); \    fprintf(stderr, "\n=================================================\n"); \  } while (0)#define RXX_NO_ERRORQString i18n(QString arg){    return arg;}//@todo remove meenum{    OBJC_CLASS,    OBJC_PROTOCOL,    OBJC_ALIAS};Parser::Parser(){    m_maxProblems = 5;    objcp = false;}Parser::~Parser(){}TranslationUnitAST *Parser::parse(TokenStreamAdapter::TokenStream *p_tokenStream, pool *p){   //tokenStream->rewind(0);    m_pool = p;    tokenStream = p_tokenStream;    TranslationUnitAST *ast = 0;    parseTranslationUnit(ast);    return ast;}/*    Parses a part of the translation unit given by tokenStream. When the number    of nodes in the AST exeeds targetMaxASTnodes, this function will return as    soon as possible. The progress is stored by updating the cursor inside    tokenStream. done is set to true if the parser finished parsing the    tokenStream, and to false otherwise.*/TranslationUnitAST *Parser::parse(TokenStreamAdapter::TokenStream *p_tokenStream, pool *p, int targetMaxASTNodes, bool &done){    m_pool = p;    tokenStream = p_tokenStream;    TranslationUnitAST *ast = 0;    // we always create one node, so target max nodes cannot be < 2.    if (targetMaxASTNodes < 2)        targetMaxASTNodes = 2;    // Advance past whitespace and comment tokens at the start.    while (tokenStream->isHidden(tokenStream->cursor())) {        tokenStream->nextToken();    }    int start = tokenStream->cursor();    AST::N = 0;    m_problems = 0;    ast = CreateNode<TranslationUnitAST>(m_pool);    while (tokenStream->lookAhead() && AST::N < targetMaxASTNodes) {        DeclarationAST *def = 0;        int startDecl = tokenStream->cursor();        if (!parseDeclaration(def)) {            // error recovery            if (startDecl == tokenStream->cursor())                advance(); // skip at least one token            skipUntilDeclaration();        }        ast->addDeclaration(def);    }    UPDATE_POS(ast, start, tokenStream->cursor());    done = tokenStream->tokenAtEnd();    return ast;}bool Parser::reportError(const Error& err){Q_UNUSED(err);#ifndef RXX_NO_ERROR    if (m_problems < m_maxProblems) {        ++m_problems;        int line=0, col=0;        QByteArray fileName;        tokenStream->getTokenStartPosition(tokenStream->cursor(), &line, &col, &fileName);        QString s = tokenStream->currentTokenText();        s = s.left(30).trimmed();        if (s.isEmpty())            s = i18n("<eof>");        if (fileName.isEmpty())            //fileName = m_file->fileName;            fileName = "implement me";        //        m_driver->addProblem(m_driver->currentFileName(), Problem(err.text.arg(s), line, col));        fprintf(stderr, "%s: error %s at line %d column %d\n",                fileName.constData(),                err.text.arg(s).toLatin1().constData(), line, col);    }#endif // RXX_NO_ERROR    return true;}bool Parser::reportError(const QString& msg){Q_UNUSED(msg);#ifndef RXX_NO_ERROR    if (m_problems < m_maxProblems) {        ++m_problems;        int line=0, col=0;        QByteArray fileName;        tokenStream->getTokenStartPosition(tokenStream->cursor(), &line, &col, &fileName);        if (fileName.isEmpty())            //fileName = m_file->fileName;            fileName = "implement me";        //        m_driver->addProblem(m_driver->currentFileName(), Problem(msg, line, col));        fprintf(stderr, "%s: error %s at line %d column %d\n",                fileName.constData(),                msg.toLatin1().constData(), line, col);    }#endif // RXX_NO_ERROR    return true;}void Parser::syntaxError(){    (void) reportError(Errors::SyntaxError);}bool Parser::skipUntil(int token){    while (tokenStream->lookAhead()) {        if (tokenStream->lookAhead() == token)            return true;        advance();    }    return false;}bool Parser::skipUntilDeclaration(){    while (tokenStream->lookAhead()) {        switch(tokenStream->lookAhead()) {        case ';':        case '~':        case Token_scope:        case Token_identifier:        case Token_operator:        case Token_char:        case Token_wchar_t:        case Token_bool:        case Token_short:        case Token_int:        case Token_long:        case Token_signed:        case Token_unsigned:        case Token_float:        case Token_double:        case Token_void:        case Token_extern:        case Token_namespace:        case Token_using:        case Token_typedef:        case Token_asm:        case Token_template:        case Token_export:        case Token_const:       // cv        case Token_volatile:    // cv        case Token_public:        case Token_protected:        case Token_private:        case Token_signals:      // Qt        case Token_slots:        // Qt              return true;        default:            advance();        }    }    return false;}bool Parser::skipUntilStatement(){    while (tokenStream->lookAhead()) {        switch(tokenStream->lookAhead()) {                case ';':                case '{':                case '}':                case Token_const:                case Token_volatile:                case Token_identifier:                case Token_case:                case Token_default:                case Token_if:                case Token_switch:                case Token_while:                case Token_do:                case Token_for:                case Token_break:                case Token_continue:                case Token_return:                case Token_goto:                case Token_try:                case Token_catch:                case Token_throw:                case Token_char:                case Token_wchar_t:                case Token_bool:                case Token_short:                case Token_int:                case Token_long:                case Token_signed:                case Token_unsigned:                case Token_float:                case Token_double:                case Token_void:                case Token_class:                case Token_struct:                case Token_union:                case Token_enum:                case Token_scope:                case Token_template:                case Token_using:                    return true;            default:                  advance();        }    }    return false;}bool Parser::skip(int l, int r){    int count = 0;    while (tokenStream->lookAhead()) {        int tk = tokenStream->lookAhead();        if (tk == l)            ++count;        else if (tk == r)            --count;        else if (l != '{' && (tk == '{' || tk == '}' || tk == ';'))            return false;        if (count == 0)            return true;        advance();    }    return false;}bool Parser::skipCommaExpression(AbstractExpressionAST *&node){#ifndef RXX_NO_PARSE_EXPRESSION    return parseCommaExpression(node);#else    int start = tokenStream->cursor();    AbstractExpressionAST *expr = 0;    if (!skipExpression(expr))        return false;    while (tokenStream->lookAhead() == ',') {        advance();        if (!skipExpression(expr)) {            reportError(i18n("expression expected"));            return false;        }    }    AbstractExpressionAST *ast = CreateNode<AbstractExpressionAST>(m_pool);    UPDATE_POS(ast, start, tokenStream->cursor());    node = ast;    return true;#endif // RXX_NO_PARSE_EXPRESSION}bool Parser::skipExpression(AbstractExpressionAST *&node){#ifndef RXX_NO_PARSE_EXPRESSION    return parseExpression(node);#else    int start = tokenStream->cursor();    int count = 0;    while (tokenStream->lookAhead()) {        int tk = tokenStream->lookAhead();        switch(tk) {        case '(':        case '[':        case '{':            ++count;            advance();            break;        case ']':        case ')':        case '}':            if (count == 0) {                AbstractExpressionAST *ast = CreateNode<AbstractExpressionAST>(m_pool);                UPDATE_POS(ast, start, tokenStream->cursor());                node = ast;                return true;            }            --count;            advance();            break;        case Token_struct:        case Token_union:        case Token_class: {            int c = tokenStream->cursor();            TypeSpecifierAST *spec = 0;            if (!parseClassSpecifier(spec))                tokenStream->rewind(c + 1);        }        break;        case ',':        case ';':        case Token_case:        case Token_default:        case Token_if:        case Token_while:        case Token_do:        case Token_for:        case Token_break:        case Token_continue:        case Token_return:        case Token_goto:        {            if ((tk == ',' || tk == ';') && count > 0) {                advance();                break;            }            AbstractExpressionAST *ast = CreateNode<AbstractExpressionAST>(m_pool);            UPDATE_POS(ast, start, tokenStream->cursor());            node = ast;        }        return true;        default:            advance();        }    }    return false;#endif // RXX_NO_PARSE_EXPRESSION}bool Parser::parseName(NameAST *&node, bool parseTemplateId){    AST *winDeclSpec = 0;    parseWinDeclSpec(winDeclSpec);    int start = tokenStream->cursor();    NameAST *ast = CreateNode<NameAST>(m_pool);    if (tokenStream->lookAhead() == Token_scope) {        ast->setGlobal(true);        advance();    }    int idx = tokenStream->cursor();    while (true) {        ClassOrNamespaceNameAST *n = 0;        if (!parseUnqualifiedName(n))            return false;        if (tokenStream->lookAhead() == Token_scope) {            advance();            ast->addClassOrNamespaceName(n);            if (tokenStream->lookAhead() == Token_template)                advance(); /// skip optional template     #### @todo CHECK        } else if (!parseTemplateId && n) {            tokenStream->rewind(n->startToken());            parseUnqualifiedName(n, parseTemplateId);            ast->setUnqualifiedName(n);            break;        } else {            ast->setUnqualifiedName(n);            break;        }    }    if (idx == tokenStream->cursor())        return false;    UPDATE_POS(ast, start, tokenStream->cursor());    node = ast;    return true;}bool Parser::parseTranslationUnit(TranslationUnitAST *&node){    QTime t;    t.start();    advance();    int start = tokenStream->cursor();    m_problems = 0;    TranslationUnitAST *tun = CreateNode<TranslationUnitAST>(m_pool);    node = tun;    while (tokenStream->lookAhead()) {        DeclarationAST *def = 0;        int startDecl = tokenStream->cursor();        if (!parseDeclaration(def)) {            // error recovery            if (startDecl == tokenStream->cursor())                advance(); // skip at least one token            skipUntilDeclaration();        }        node->addDeclaration(def);    }    UPDATE_POS(node, start, tokenStream->cursor());

⌨️ 快捷键说明

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