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

📄 compiler.cpp

📁 fastdb-2.92的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            }            if (list != NULL) {                 expr = new dbExprNode(dbvmList, list, expr);            }        }        break;      case tkn_not:        pos = currPos;        expr = comparison();        if (expr->type == tpInteger) {             if (expr->cop == dbvmLoadIntConstant) {                 expr->ivalue = ~expr->ivalue;            } else {                expr = new dbExprNode(dbvmNotInt, expr);            }             return expr;        } else if (expr->type == tpBoolean) {             return new dbExprNode(dbvmNotBool, expr);        } else {             error("NOT operator can be applied only to "                  "integer or boolean expressions", pos);        }        break;      case tkn_add:        error("Using of unary plus operator has no sence");        break;      case tkn_sub:        pos = currPos;        expr = term();        if (expr->type == tpInteger) {             if (expr->cop == dbvmLoadIntConstant) {                 expr->ivalue = -expr->ivalue;            } else {                 expr = new dbExprNode(dbvmNegInt, expr);            }            return expr;        } else if (expr->type == tpReal) {             if (expr->cop == dbvmLoadRealConstant) {                 expr->fvalue = -expr->fvalue;            } else {                 expr = new dbExprNode(dbvmNegReal, expr);            }            return expr;        } else {             error("Unary minus can be applied only to "                  "integer or real expressions", pos);        }      default:        error("operand expected");    }    lex = scan();    return expr;}void dbCompiler::error(const char* msg, int pos) {     if (pos < 0) {         if ((pos = currPos-1) < 0) {             pos = 0;        }    } else if (pos < firstPos) {         pos = firstPos;    }    if (pos + offsetWithinStatement >= 0) {         pos += offsetWithinStatement;    }    table->db->handleError(dbDatabase::QueryError, msg, pos);    longjmp(abortCompilation, dbDatabase::QueryError);}void dbCompiler::compileStartFollowPart(dbQuery& query){    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::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;                delete expr;                break;              case dbvmLength:                if (expr->operand[0]->cop == dbvmLoadSelfArray) {                     node->field = expr->operand[0]->ref.field;                    node->expr = NULL;                    delete 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) {             table->db->handleError(dbDatabase::QueryError, "Conditional "                                   "expression should have boolean type\n", 0);            delete expr;            return false;        }        compileStartFollowPart(query);         compileOrderByPart(query);         query.tree  = expr;        query.table = table;        return true;    } else {         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},        {"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},        {"lower",   tkn_lower},        {"not",     tkn_not},        {"null",    tkn_null},        {"or",      tkn_or},        {"order",   tkn_order},        {"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;    }}static void stderrTrace(char* msg){    fputs(msg, stderr);}dbTraceFunctionPtr dbTraceFunction = stderrTrace;void dbTrace(char* message, ...) {    va_list args;    va_start (args, message);    char buffer[1024];    vsprintf(buffer, message, args);    (*dbTraceFunction)(buffer);    va_end(args);}byte* dbMalloc(size_t size){    return (byte*)malloc(size);}void  dbFree(void* p){    free(p);}

⌨️ 快捷键说明

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