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

📄 compiler.cpp

📁 俄罗斯牛人KK的作品,著名的ORDBMS,这里上传最新的3.39版本源代码.希望了解对象关系数据库的同好,请不要错过.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        memcpy(str, str+1, w-str-1);
                        str[w-str-1] = '\0';
                        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, 

⌨️ 快捷键说明

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