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

📄 compiler.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    return left;}inline dbExprNode* int2real(dbExprNode* expr) {    if (expr->cop == dbvmLoadIntConstant) {         expr->fvalue = (real8)expr->ivalue;        expr->cop = dbvmLoadRealConstant;        expr->type = tpReal;    } else {         expr = new dbExprNode(dbvmIntToReal, expr);    }    return expr;}void dbCompiler::compare(dbExprNode* expr, dbExprNode* list){    dbExprNode* selector = expr;    for (int n = 1; list != NULL; n++) {         dbExprNode* elem = list->operand[0];        dbExprNode* tail = list->operand[1];        int cop = dbvmVoid;        int rawBinarySize = 0;        void* rawBinaryComparator = NULL;        if (expr->type == tpInteger) {             if (elem->type == tpReal) {                 expr = int2real(expr);                cop = dbvmEqReal;            } else if (elem->type == tpReference) {                expr = new dbExprNode(dbvmIntToReference, expr);                cop = dbvmEqReference;            } else if (elem->type == tpInteger) {                 cop = dbvmEqInt;            }        } else if (expr->type == tpReal) {            if (elem->type == tpReal) {                 cop = dbvmEqReal;            } else if (elem->type == tpInteger) {                 cop = dbvmEqReal;                elem = int2real(elem);            }        } else if (expr->type == tpString && elem->type == tpString) {            cop = dbvmEqString;        } else if (expr->type == tpReference && (elem->type == tpReference || elem->type == tpInteger)) {            if (elem->type == tpInteger) {                elem = new dbExprNode(dbvmIntToReference, elem);            }            cop = dbvmEqReference;        } else if (expr->type == tpBoolean && elem->type == tpBoolean) {            cop = dbvmEqBool;        } else if (expr->type == tpRawBinary && elem->type == tpRawBinary) {            cop = dbvmEqBinary;            if ((expr->cop == dbvmLoadSelfRawBinary || expr->cop == dbvmLoadRawBinary)                 && expr->ref.field != NULL)            {                rawBinarySize = expr->ref.field->dbsSize;                rawBinaryComparator = (void*)expr->ref.field->comparator;            } else if ((elem->cop == dbvmLoadSelfRawBinary || elem->cop == dbvmLoadRawBinary)                        && elem->ref.field != NULL)            {                rawBinarySize = elem->ref.field->dbsSize;                rawBinaryComparator = (void*)elem->ref.field->comparator;            } else {                 error("Operations with raw binary types should include at least one record field");            }        }        if (cop == dbvmVoid) {             char buf[256];            sprintf(buf, "Expression %d in right part of IN operator have "                    "incompatible type", n);            error(buf);        } else {             list->type = tpBoolean;            if (tail != NULL) {                 expr = new dbExprNode(cop, expr, elem, rawBinarySize);                expr->func.fptr = rawBinaryComparator;                list->operand[0] = expr;                list->cop = dbvmOrBool;                expr = new dbExprNode(selector);            } else {                 list->operand[1] = elem;                list->operand[0] = expr;                list->cop = cop;                list->offs = rawBinarySize;                list->func.fptr = rawBinaryComparator;            }        }        list = tail;    }}dbExprNode* dbCompiler::rectangleConstant(dbExprNode* head){    rectangle r;    for (int i = 0; i < RECTANGLE_DIMENSION*2; i++) {         if (head == NULL) {             error("Bad rectangle constant");        }        dbExprNode* elem = head->operand[0];        dbExprNode* tail = head->operand[1];        if (elem->type == tpReal) {                                     r.boundary[i] = (coord_t)elem->fvalue;        } else if (elem->type == tpInteger) {              r.boundary[i] = (coord_t)elem->ivalue;        } else {             error("Bad rectangle constant");        }        head = tail;    }    if (head != NULL) {         error("Bad rectangle constant");    }    return new dbExprNode(dbvmLoadRectangleConstant, r);}dbExprNode* dbCompiler::comparison(){    int leftPos = currPos;    dbExprNode *left, *right;    left = addition();    int cop = lex;    if (cop == tkn_eq || cop == tkn_ne || cop == tkn_gt || cop == tkn_ge        || cop == tkn_le || cop == tkn_lt || cop == tkn_between || cop == tkn_overlaps        || cop == tkn_like || cop == tkn_match || cop == tkn_not || cop == tkn_is || cop == tkn_in)    {        int rightPos = currPos;        bool notOp = false;        if (cop == tkn_not) {             notOp = true;            cop = scan();            if (cop != tkn_like && cop != tkn_match && cop != tkn_between && cop != tkn_in) {                 error("LIKE, MATCH, BETWEEN or IN expected", rightPos);            }             rightPos = currPos;        } else if (cop == tkn_is) {            if (left->type != tpReference) {                 error("IS [NOT] NULL predicate can be applied only to "                      "references", rightPos);            }             rightPos = currPos;            if ((cop = scan()) == tkn_null) {                 left = new dbExprNode(dbvmIsNull, left);            } else if (cop == tkn_not) {                 rightPos = currPos;                if (scan() == tkn_null) {                     left = new dbExprNode(dbvmNotBool,                                           new dbExprNode(dbvmIsNull, left));                } else {                     error("NULL expected", rightPos);                }            } else {                 error("[NOT] NULL expected", rightPos);            }             lex = scan();            return left;        }               right = addition();        if (cop == tkn_in) {             int type;            switch (right->type) {              case tpArray:                switch (right->cop) {                   case dbvmLoadVarArrayOfOid:                  case dbvmLoadVarArrayOfOidPtr:                    type = dbField::tpReference;                    break;                  case dbvmLoadVarArrayOfInt4:                  case dbvmLoadVarArrayOfInt4Ptr:                    type = dbField::tpInt4;                    break;                  case dbvmLoadVarArrayOfInt8:                  case dbvmLoadVarArrayOfInt8Ptr:                    type = dbField::tpInt8;                    break;                  default:                    type = right->ref.field->components->type;                }                if ((left->type == tpBoolean && type == dbField::tpBool)                     || (left->type == tpInteger                         && (type == dbField::tpInt1                             || type == dbField::tpInt2                            || type == dbField::tpInt4                             || type == dbField::tpInt8))                    || (left->type == tpReal                         && (type == dbField::tpReal4                            || type == dbField::tpReal8))                    || (left->type == tpString && type == dbField::tpString)                    || ((left->type == tpRectangle || left->type == tpList) && type == dbField::tpRectangle)                    || ((left->type == tpReference || left->type == tpInteger)                        && type == dbField::tpReference))                {                    if (left->type == tpInteger && type == dbField::tpReference) {                         left = new dbExprNode(dbvmIntToReference, left);                    }                    if (type == dbField::tpRectangle) {                         if (left->type == tpList) {                             left = rectangleConstant(left);                        }                        left = new dbExprNode(dbvmInArrayRectangle, left, right);                    } else {                         left = new dbExprNode(dbvmInArrayBool + type, left, right);                    }                } else {                    error("Type of selective expression of IN operator doesn't"                          " match type of the array");                }                break;              case tpString:                if (left->type == tpString) {                     left = new dbExprNode(dbvmInString, left, right);                } else {                     error("Left operand of IN expression hasn't string type");                }                break;              case tpRectangle:                if (left->type == tpRectangle) {                    if (IS_CONSTANT(left->cop)) {                        left = new dbExprNode(dbvmGeRectangle, right, left);                    } else {                         left = new dbExprNode(dbvmLeRectangle, left, right);                    }                } else if (left->type == tpList) {                    left = new dbExprNode(dbvmGeRectangle, right, rectangleConstant(left));                } else {                    error("Left operand of IN expression hasn't rectangle type");                }                break;                        case tpList:                if (left->type == tpRectangle) {                    left = new dbExprNode(dbvmLeRectangle, left, rectangleConstant(right));                } else {                     compare(left, right);                    left = right;                }                break;              default:                error("List of expressions or array expected", rightPos);            }        } else if (cop == tkn_between) {             int andPos = currPos;            if (lex != tkn_and) {                 error("AND expected");            }            dbExprNode* right2 = addition();            if (left->type == tpReal                 || right->type == tpReal || right2->type == tpReal)            {                if (left->type == tpInteger) {                     left = int2real(left);                } else if (left->type != tpReal) {                     error("operand of BETWEEN operator should be of "                          "integer, real or string type", leftPos);                }                if (right->type == tpInteger) {                    right = int2real(right);                } else if (right->type != tpReal) {                     error("operand of BETWEEN operator should be of "                          "integer, real or string type", rightPos);                }                if (right2->type == tpInteger) {                    right2 = int2real(right2);                } else if (right2->type != tpReal) {                     error("operand of BETWEEN operator should be of "                          "integer, real or string type", andPos);                }                left = new dbExprNode(dbvmBetweenReal, left, right, right2);            }             else if (left->type == tpInteger && right->type == tpInteger                      && right2->type == tpInteger)            {                               left = new dbExprNode(dbvmBetweenInt, left, right, right2);            }            else if (left->type == tpString && right->type == tpString                      && right2->type == tpString)            {                left = new dbExprNode(dbvmBetweenString, left, right, right2);            }            else if (left->type == tpRawBinary && right->type == tpRawBinary                     && right2->type == tpRawBinary)            {                int rawBinarySize = 0;                void* rawBinaryComparator = NULL;                if ((left->cop == dbvmLoadSelfRawBinary || left->cop == dbvmLoadRawBinary)                     && left->ref.field != NULL)                {                    rawBinarySize = left->ref.field->dbsSize;                    rawBinaryComparator = (void*)left->ref.field->comparator;                } else {                     error("Operations with raw binary types should include at least one record field");                }                left = new dbExprNode(dbvmBetweenBinary, left, right, right2);                left->offs = rawBinarySize;                left->func.fptr = rawBinaryComparator;            }            else {                 error("operands of BETWEEN operator should be of "                      "integer, real or string type", rightPos);            }#ifdef USE_REGEX        } else if (cop == tkn_match) {            if (left->type != tpString) {                error("left operands of MATCH operator should be of string type", leftPos);            }            if (right->cop != dbvmLoadStringConstant) {                 error("right operand of MATCH operator should be string constant", rightPos);            }            dbExprNode* expr = new dbExprNode(dbvmMatchString);            expr->regex.opd = left;            left = expr;            if (regcomp(&left->regex.re, (char*)right->svalue.str, REG_EXTENDED|REG_ICASE|REG_NOSUB) != 0) {                 error("invalid regular expression", rightPos);            }#endif        } else if (cop == tkn_like) {              if (left->type != tpString || right->type != tpString) {                 error("operands of LIKE operator should be of "                      "string type", rightPos);            }            if (lex == tkn_escape) {                 rightPos = currPos;                if (scan() != tkn_sconst) {                     error("String literal espected after ESCAPE", rightPos);                }                lex = scan();                left = new dbExprNode(dbvmLikeEscapeString, left, right,                           new dbExprNode(dbvmLoadStringConstant, svalue));            } else {                 if (right->cop == dbvmLoadStringConstant) {                    char* str = right->svalue.str;                    char* w = findWildcard(str);                    if (w == NULL) {                         left = new dbExprNode(dbvmEqString, left, right);                    } else if (w == str && *w == '%'                                && (w = findWildcard(str+1)) != NULL && *w == '%' && *(w+1) == '\0')                     {                        memcpy(str, str+1, w-str-1);                        str[w-str-1] = '\0';

⌨️ 快捷键说明

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