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

📄 compiler.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{    if (lex != tkn_start) {             return;    }    int pos = currPos;    if (scan() != tkn_from) {         error("FROM expected after START", pos);    }    pos = currPos;    switch (scan()) {       case tkn_first:        query.startFrom = dbCompiledQuery::StartFromFirst;         break;      case tkn_last:        query.startFrom = dbCompiledQuery::StartFromLast;         break;      case tkn_var:        if (varType == dbQueryElement::qVarReference) {             if (varRefTable != table) {                 error("Incompatiable type of reference variable");            }            query.startFrom = dbCompiledQuery::StartFromRef;         } else if (varType == dbQueryElement::qVarArrayOfRef) {            if (varRefTable != table) {                 error("Incompatiable type of array of reference variable");            }            query.startFrom = dbCompiledQuery::StartFromArray;         } else if (varType == dbQueryElement::qVarArrayOfRefPtr) {            if (varRefTable != table) {                 error("Incompatiable type of array of reference variable");            }            query.startFrom = dbCompiledQuery::StartFromArrayPtr;         } else {             error("Reference or array of reference variable expected");        }        query.root = varPtr;        break;      default:        error("FIRST, LAST or reference varaible expected", pos);     }    if ((lex = scan()) == tkn_follow) {         pos = currPos;        if (scan() != tkn_by) {             error("BY expected after FOLLOW", pos);        }        do {             pos = currPos;            if (scan() != tkn_ident) {                 error("Field name expected", pos);            }            dbFieldDescriptor* fd;            if ((fd = table->findSymbol(name)) == NULL) {                 error("Field not found");            }            while (fd->type == dbField::tpStructure) {                 pos = currPos;                if (scan() != tkn_dot) {                     error("'.' expected", pos);                }                pos = currPos;                if (scan() != tkn_ident) {                     error("Field name expected", pos);                }                if ((fd = fd->find(name)) == NULL) {                     error("Field not found");                }            }            if (!(fd->type == dbField::tpReference                   && fd->refTable == table) &&                !(fd->type == dbField::tpArray                   && fd->components->type == dbField::tpReference                  && fd->components->refTable == table))             {                 error("Follow field should be of compatibale reference "                      "or array of reference type");            }            dbFollowByNode* node = new dbFollowByNode;            node->field = fd;            node->next = query.follow; // list should be inverted            query.follow = node;        } while ((lex = scan()) == tkn_comma);     }   }void dbCompiler::deleteNode(dbExprNode* node) {    dbMutex& mutex = dbExprNodeAllocator::instance.getMutex();    dbCriticalSection cs(mutex);    delete node;}void dbCompiler::compileLimitPart(dbQuery& query){     if (lex == tkn_limit) {        int pos = currPos;        size_t l1 = 0;        int4*  lp1 = NULL;        switch (scan()) {          case tkn_iconst:            l1 = (size_t)ivalue;            break;          case tkn_var:            if (varType != dbQueryElement::qVarInt4) {                error("LIMIT parameter should have int4 type", pos);            }            lp1 = (int4*)varPtr;            break;          default:            error("Parameter or integer constant expected", pos);        }        if ((lex = scan()) == tkn_comma) {             pos = currPos;            size_t l2 = 0;            int4*  lp2 = NULL;            switch (scan()) {              case tkn_iconst:                l2 = (size_t)ivalue;                break;              case tkn_var:                if (varType != dbQueryElement::qVarInt4) {                    error("LIMIT parameter should have int4 type", pos);                }                lp2 = (int4*)varPtr;                break;              default:                error("Parameter or integer constant expected", pos);            }            query.stmtLimitStart = l1;            query.stmtLimitStartPtr = lp1;            query.stmtLimitLen = l2;            query.stmtLimitLenPtr = lp2;            lex = scan();        } else {             query.stmtLimitStart = 0;            query.stmtLimitStartPtr = NULL;            query.stmtLimitLen = l1;            query.stmtLimitLenPtr = lp1;        }        query.limitSpecified = true;    }}            void dbCompiler::compileOrderByPart(dbQuery& query){    if (lex == tkn_order) {             dbOrderByNode** opp = &query.order;        int pos = currPos;        if (scan() != tkn_by) {            error("BY expected after ORDER", pos);        }        int parentheses = 0;        do {            pos = currPos;            int tkn = scan();            if (tkn == tkn_lpar) {                parentheses += 1;            } else {                ungetToken(tkn);            }            dbExprNode* expr = disjunction();            dbOrderByNode* node = new dbOrderByNode;            switch (expr->cop) {               case dbvmLoadSelfBool:              case dbvmLoadSelfInt1:              case dbvmLoadSelfInt2:              case dbvmLoadSelfInt4:              case dbvmLoadSelfInt8:              case dbvmLoadSelfReal4:              case dbvmLoadSelfReal8:              case dbvmLoadSelfString:              case dbvmLoadSelfArray:              case dbvmLoadSelfReference:              case dbvmLoadSelfRawBinary:                assert(expr->ref.field != NULL);                node->field = expr->ref.field;                node->expr = NULL;                deleteNode(expr);                break;              case dbvmLength:                if (expr->operand[0]->cop == dbvmLoadSelfArray) {                     node->field = expr->operand[0]->ref.field;                    node->expr = NULL;                    deleteNode(expr);                    break;                                    }                // no break              default:                if (expr->type > tpReference) {                     error("Expressions in ORDER BY part should have scalar type", pos);                }                 node->field = NULL;                node->expr = expr;            }            node->table = table;            node->ascent = true;            *opp = node;            opp = &node->next;            *opp = NULL;            if (lex == tkn_desc) {                node->ascent = false;                lex = scan();            } else if (lex == tkn_asc) {                lex = scan();            }             if (lex == tkn_rpar) {                 if (--parentheses < 0) {                     error("Unbalanced parentheses ");                }                lex = scan();            }        } while (lex == tkn_comma);    }}dbExprNode* dbCompiler::compileExpression(dbTableDescriptor* table, char const* expr, int startPos){    TRACE_MSG(("Compile expression %s for table %s\n", table->name));        if (setjmp(abortCompilation) == 0) {         this->table = table;        bindings = NULL;        nFreeVars = 0;        dbQueryElement elem(dbQueryElement::qExpression, expr, NULL);         queryElement = &elem;        currPos = firstPos = 0;        offsetWithinStatement = startPos;        return disjunction();     } else {        return NULL;    }}bool dbCompiler::compile(dbTableDescriptor* table, dbQuery& query){    TRACE_MSG(("Compile query for table %s\n", table->name));    query.destroy();     if (setjmp(abortCompilation) == 0) {         this->table = table;        bindings = NULL;        nFreeVars = 0;        queryElement = query.elements;        currPos = firstPos = 0;        hasToken  = false;        offsetWithinStatement = query.pos;        dbExprNode* expr = disjunction();         if (expr->type != tpBoolean && expr->type != tpVoid) {             error("Conditional expression should have boolean type\n");        }        compileStartFollowPart(query);         compileOrderByPart(query);         compileLimitPart(query);        if (lex != tkn_eof) {             error("START, ORDER BY or LIMIT expected");        }        query.tree = expr;        query.table = table;        return true;    } else {         dbMutex& mutex = dbExprNodeAllocator::instance.getMutex();        dbCriticalSection cs(mutex);        for (dbOrderByNode *op = query.order, *nop; op != NULL; op = nop) {            nop = op->next;            delete op;        }        for (dbFollowByNode *fp = query.follow, *nfp; fp != NULL; fp = nfp) {            nfp = fp->next;            delete fp;        }        return false;    }}dbCompiler::dbCompiler() {    static struct {         char* name;        int   tag;    } keywords[] = {         {"all",     tkn_all},        {"abs",     tkn_abs},        {"and",     tkn_and},        {"area",    tkn_area},        {"asc",     tkn_asc},        {"between", tkn_between},        {"by",      tkn_by},        {"current", tkn_current},        {"desc",    tkn_desc},        {"escape",  tkn_escape},        {"exists",  tkn_exists},        {"first",   tkn_first},        {"false",   tkn_false},        {"follow",  tkn_follow},        {"from",    tkn_from},        {"in",      tkn_in},        {"is",      tkn_is},        {"integer", tkn_integer},        {"insert",  tkn_insert},        {"into",    tkn_into},        {"last",    tkn_last},        {"length",  tkn_length},        {"like",    tkn_like},        {"limit",   tkn_limit},        {"lower",   tkn_lower},#ifdef USE_REGEX        {"match",   tkn_match},#endif        {"not",     tkn_not},        {"null",    tkn_null},        {"or",      tkn_or},        {"order",   tkn_order},        {"overlaps",tkn_overlaps},        {"real",    tkn_real},        {"select",  tkn_select},        {"start",   tkn_start},        {"string",  tkn_string},        {"table",   tkn_table},        {"true",    tkn_true},        {"upper",   tkn_upper},        {"where",   tkn_where}    };    if (!initialized) {         for (unsigned i = 0; i < itemsof(keywords); i++) {             dbSymbolTable::add(keywords[i].name, keywords[i].tag, FASTDB_CLONE_ANY_IDENTIFIER);            }        initialized = true;    }}void dbInheritedAttribute::removeTemporaries(){    for (dbStringValue *next, *s = tempStrings; s != NULL; s = next) {         next = s->next;        delete s;    }}END_FASTDB_NAMESPACE

⌨️ 快捷键说明

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