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

📄 compiler.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        right->svalue.len -= 2;                        left = new dbExprNode(dbvmInString, right, left);                    } else {                        left = new dbExprNode(dbvmLikeString, left, right);                    }                } else {                    left = new dbExprNode(dbvmLikeString, left, right);                }            }        } else if (cop == tkn_overlaps) {            if (left->type == tpRectangle && right->type == tpRectangle) {                if (IS_CONSTANT(left->cop)) {                    left = new dbExprNode(dbvmOverlapsRectangle, right, left);                } else {                     left = new dbExprNode(dbvmOverlapsRectangle, left, right);                }            } else if (left->type == tpList && right->type == tpRectangle) {                 left = new dbExprNode(dbvmOverlapsRectangle, right, rectangleConstant(left));            } else if (left->type == tpRectangle && right->type == tpList) {                 left = new dbExprNode(dbvmOverlapsRectangle, left, rectangleConstant(right));            } else {                 error("operands of OVERLAPS operator should be of rectangle type", leftPos);            }               } 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 == tpRectangle && right->type == tpRectangle) {                left = new dbExprNode(dbvmEqRectangle + cop-tkn_eq, left, right);            } else if (left->type == tpList && right->type == tpRectangle) {                 left = new dbExprNode(dbvmEqRectangle + cop-tkn_eq, rectangleConstant(left), right);            } else if (left->type == tpRectangle && right->type == tpList) {                 left = new dbExprNode(dbvmEqRectangle + cop-tkn_eq, left, rectangleConstant(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 == tpRectangle || right->type == tpRectangle) {            if (cop == tkn_add) {                 if (left->type == tpRectangle || right->type == tpRectangle) {                    left = new dbExprNode(dbvmAddRectangle, left, right);                } else if (left->type == tpRectangle || right->type == tpList) {                    left = new dbExprNode(dbvmAddRectangle, left, rectangleConstant(right));                } else if (right->type == tpRectangle || left->type == tpList) {                    left = new dbExprNode(dbvmAddRectangle, rectangleConstant(left), right);                } else {                    error("Rectangle can be added only with rectangle", rightPos);                }             } else {                error("Operation - is not defined for rectangles", rightPos);            }            } 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);            }            if (right->type == tpInteger) {                 cop = dbvmPowerRealInt;            } else if (right->type != tpReal) {                     error("operands of arithmetic operator should be of "                          "integer or real type", rightPos);            }            left = new dbExprNode(cop, left, right);        } else if (left->type == tpInteger && right->type == tpInteger) {             left = new dbExprNode(dbvmPowerInt, left, right);        } else {             error("operands of arithmentic operator should be of "                  "integer or real type", rightPos);        }    }        return left;}dbExprNode* dbCompiler::userDefinedOperator() {     dbExprNode* left = term();    while (lex == tkn_ident) {         dbUserFunction* func = dbUserFunction::find(name);        if (func != NULL) {             int nParams =  func->getNumberOfParameters();            if (nParams != 2) {                 error("Only function with two arguments can be used as operator", currPos);            }            int rightPos = currPos;            dbExprNode* right = term();            if ((left->type != tpInteger && left->type != tpReal && left->type != tpString                 && left->type != tpReference && left->type != tpRawBinary && left->type != tpBoolean)                || (right->type != tpInteger && right->type != tpReal && right->type != tpString                    && right->type != tpReference && right->type != tpRawBinary && right->type != tpBoolean))            {                                error("User function should receive parameter of boolean, integer, real, string, reference or user defined type", rightPos);            }             left = new dbExprNode(dbvmFuncInt2Bool + func->type, func->fptr, left, right);        } else {             break;        }    }    return left;}dbExprNode* dbCompiler::field(dbExprNode* expr, dbTableDescriptor* refTable,                              dbFieldDescriptor* fd) {    int pos;    while (true) {         switch (lex) {          case tkn_dot:             pos = currPos;            if (scan() != tkn_ident) {                 error("identifier expected", pos);            }            if (fd != NULL && fd->type == dbField::tpStructure) {                 if ((fd = fd->find(name)) == NULL) {                     error("Field not found");                }            } else {                 assert(expr != NULL);                if (expr->type != tpReference) {                     error("Left operand of '.' should be "                          "structure or reference", pos);                }                if (refTable == NULL) {                     refTable = fd->refTable;                }                if (refTable == NULL) {                    refTable = fd->refTable;                }                if (refTable == NULL || (fd = refTable->findSymbol(name)) == NULL) {                     error("Field not found");                }                refTable = NULL;                expr = new dbExprNode(dbvmDeref, expr);            }            break;          case tkn_lbr:            if (expr == NULL ||                 (expr->type != tpArray && expr->type != tpString && expr->type != tpRectangle))            {                 error("Index can be applied only to arrays");            } else {                 dbExprNode* index = disjunction();                if (lex != tkn_rbr) {                     error("']' expected");                }                if (index->type != tpInteger && index->type != tpFreeVar) {                    error("Index should have integer type");                }                                if (expr->type == tpString) {                     lex = scan();                    return new dbExprNode(dbvmCharAt, expr, index);                } if (expr->type == tpRectangle) {                    lex = scan();                    return new dbExprNode(dbvmRectangleCoord, expr, index);                }                if (fd == NULL) {                     // variable of array of reference type                    expr = new dbExprNode(dbvmGetAt,expr,index,sizeof(oid_t));                } else {                     if (refTable == NULL) {                         refTable = fd->refTable;                    }                    fd = fd->components;                    expr = new dbExprNode(dbvmGetAt, expr, index, fd->dbsSize);                }            }            break;          default:            if (expr == NULL) {                 error("'.' expected");            }            return expr;        }               if (fd == NULL) {             expr = new dbExprNode(dbvmLoadReference, expr, 0);         } else if (fd->type == dbField::tpRawBinary) {            expr = new dbExprNode(expr != NULL ? dbvmLoadRawBinary : dbvmLoadSelfRawBinary,                                   fd, expr);

⌨️ 快捷键说明

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