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

📄 compiler.cpp

📁 fastdb-2.92的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        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 (list->operand[0] != NULL) {             expr = new dbExprNode(cop, expr, elem, rawBinarySize);            expr->func.fptr = rawBinaryComparator;            list->operand[1] = expr;            list->cop = dbvmOrBool;        } else {             list->operand[0] = expr;            list->cop = cop;            list->offs = rawBinarySize;            list->func.fptr = rawBinaryComparator;        }    }    return ++n;}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_like || 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_between && cop != tkn_in) {                 error("LIKE, 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:                type = (right->cop == dbvmLoadVarArray || right->cop == dbvmLoadVarArrayPtr)                     ? dbField::tpReference                      : 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 == tpReference || left->type == tpInteger)                        && type == dbField::tpReference))                {                    if (left->type == tpInteger && type == dbField::tpReference) {                         left = new dbExprNode(dbvmIntToReference, left);                    }                    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 tpList:                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);            }        } 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 {                 left = new dbExprNode(dbvmLikeString, left, right);            }        } else {             if (left->type == tpReal || right->type == tpReal) {                 if (left->type == tpInteger) {                     left = int2real(left);                } else if (left->type != tpReal) {                     error("operands of relation operator should be of "                          "intger, real or string type", leftPos);                }                if (right->type == tpInteger) {                     right = int2real(right);                } else if (right->type != tpReal) {                     error("operands of relation operator should be of "                          "intger, real or string type", rightPos);                }                left = new dbExprNode(dbvmEqReal + cop - tkn_eq, left, right);            } else if (left->type == tpInteger && right->type == tpInteger) {                 left = new dbExprNode(dbvmEqInt + cop - tkn_eq, left, right);            } else if (left->type == tpString && right->type == tpString) {                 left = new dbExprNode(dbvmEqString + cop-tkn_eq, left, right);            } else if ((left->type == tpReference || left->type == tpInteger)                        && (right->type == tpReference || right->type == tpInteger))             {                if (cop != tkn_eq && cop != tkn_ne) {                    error("References can be checked only for equality",                          rightPos);                }                if (left->type == tpInteger) {                     left = new dbExprNode(dbvmIntToReference, left);                } else if (right->type == tpInteger) {                     right = new dbExprNode(dbvmIntToReference, right);                }                left = new dbExprNode(dbvmEqReference+cop-tkn_eq, left, right);            } else if (left->type == tpBoolean && right->type == tpBoolean) {                 if (cop != tkn_eq && cop != tkn_ne) {                     error("Boolean variables can be checked only for equality",                          rightPos);                }                left = new dbExprNode(dbvmEqBool + cop - tkn_eq, left, right);            } else if (left->type == tpRawBinary && right->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 if ((right->cop == dbvmLoadSelfRawBinary || right->cop == dbvmLoadRawBinary)                            && right->ref.field != NULL)                {                    rawBinarySize = right->ref.field->dbsSize;                    rawBinaryComparator = (void*)right->ref.field->comparator;                } else {                     error("Operations with raw binary types should include at least one record field");                }                left = new dbExprNode(dbvmEqBinary + cop - tkn_eq, left, right, rawBinarySize);                left->func.fptr = rawBinaryComparator;            } else {                 error("operands of relation operator should be of "                      "integer, real or string type", rightPos);            }            //            // Optimization for applying indices: if operation is             // commuatative and left operand is constant then swap operands            //            if (IS_CONSTANT(left->operand[0]->cop)) {                 right = left->operand[1];                left->operand[1] = left->operand[0];                left->operand[0] = right;                left->cop = dbExprNode::commutativeOperator[left->cop];            }           }        if (notOp) {             left = new dbExprNode(dbvmNotBool, left);        }    }    return left;}dbExprNode* dbCompiler::addition() {     int leftPos = currPos;    dbExprNode* left = multiplication();    while (lex == tkn_add || lex == tkn_sub) {         int cop = lex;        int rightPos = currPos;        dbExprNode* right = multiplication();        if (left->type == tpReal || right->type == tpReal) {             if (left->type == tpInteger) {                 left = int2real(left);            } else if (left->type != tpReal) {                 error("operands of arithmetic operators should be of "                      "integer or real type", leftPos);            }            if (right->type == tpInteger) {                 right = int2real(right);            } else if (right->type != tpReal) {                 error("operands of arithmetic operator should be of "                      "integer or real type", rightPos);            }            left = new dbExprNode(cop==tkn_add ? dbvmAddReal : dbvmSubReal,                                  left, right);        } else if (left->type == tpInteger && right->type == tpInteger) {             left = new dbExprNode(cop==tkn_add ? dbvmAddInt : dbvmSubInt,                                  left, right);        } else if (left->type == tpString && right->type == tpString) {             if (cop == tkn_add) {                 left = new dbExprNode(dbvmStringConcat, left, right);            } else {                 error("Operation - is not defined for strings", rightPos);            }        } else {             error("operands of arithmentic operator should be of "                  "integer or real type", rightPos);        }        leftPos = rightPos;    }    return left;}dbExprNode* dbCompiler::multiplication() {     int leftPos = currPos;    dbExprNode* left = power();    while (lex == tkn_mul || lex == tkn_div) {         int cop = lex;        int rightPos = currPos;        dbExprNode* right = power();        if (left->type == tpReal || right->type == tpReal) {             if (left->type == tpInteger) {                 left = int2real(left);            } else if (left->type != tpReal) {                 error("operands of arithmetic operators should be of "                      "integer or real type", leftPos);            }            if (right->type == tpInteger) {                 right = int2real(right);            } else if (right->type != tpReal) {                     error("operands of arithmetic operator should be of "                          "integer or real type", rightPos);            }            left = new dbExprNode(cop==tkn_mul ? dbvmMulReal : dbvmDivReal,                                  left, right);        } else if (left->type == tpInteger && right->type == tpInteger) {             left = new dbExprNode(cop==tkn_mul ? dbvmMulInt : dbvmDivInt,                                  left, right);        } else {             error("operands of arithmentic operator should be of "                  "integer or real type", rightPos);        }        leftPos = rightPos;    }    return left;}dbExprNode* dbCompiler::power() {     int leftPos = currPos;    dbExprNode* left = userDefinedOperator();    if (lex == tkn_power) {         int rightPos = currPos;        dbExprNode* right = power();        if (left->type == tpReal || right->type == tpReal) {             int cop = dbvmPowerReal;            if (left->type == tpInteger) {                 left = int2real(left);            } else if (left->type != tpReal) {                 error("operands of arithmetic operators should be of "                      "integer or real type", leftPos);            }

⌨️ 快捷键说明

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