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

📄 compiler.cpp

📁 fastdb-2.92的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            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))            {                 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 (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);        } else if (fd->type != dbField::tpStructure) {             expr = new dbExprNode((expr != NULL                                    ? dbvmLoadBool : dbvmLoadSelfBool)                                   + fd->type, fd, expr);        }        lex = scan();    }}dbExprNode* dbCompiler::term() {    dbFieldDescriptor* fd;    dbTableDescriptor* refTable;    int cop;    int pos = currPos;    dbBinding* bp;    dbExprNode* expr = NULL;    dbUserFunction* func;    if ((cop = scan()) == tkn_where) {         if (firstPos == 0) {             firstPos = currPos;        }        cop = scan(); // just ignore 'where' keyword    }    switch (cop) {       case tkn_eof:      case tkn_order:      case tkn_start:        lex = cop;        return new dbExprNode(dbvmVoid);      case tkn_current:        lex = scan();        return field(new dbExprNode(dbvmCurrent), table, NULL);      case tkn_ident:        for (bp = bindings; bp != NULL; bp = bp->next) {             if (name == bp->name) {                 bp->used = true;                lex = scan();                return new dbExprNode(dbvmVariable, (dbExprNode*)0, bp->index);            }        }        if ((fd = table->findSymbol(name)) == NULL) {             if ((func = dbUserFunction::find(name)) != NULL) {                 pos = currPos;                expr = term();                int argType = func->getParameterType();                int nParams =  func->getNumberOfParameters();                if (nParams > 1) {                     if (expr->type != tpList) {                        error("Too few paramters for user defined function");                    }                    dbExprNode* params[3];                    do {                         if (nParams == 0) {                             error("Too many parameters for user defined function");                        }                               dbExprNode* param = expr->operand[1];                        if (param->type != tpInteger && param->type != tpReal && param->type != tpString                            && param->type != tpReference && param->type != tpRawBinary && param->type != tpBoolean)                        {                            error("User function should receive parameters of boolean, integer, real, string, reference or user defined type", pos);                        }                         params[--nParams] = param;                        expr = expr->operand[0];                    } while (expr != NULL);                    if (nParams != 0) {                         error("Too few parameters for user defined function");                    }                       expr = new dbExprNode(dbvmFuncInt2Bool + func->type, func->fptr, params[0], params[1], params[2]);                } else {                     if (argType == tpReal && expr->type == tpInteger) {                         expr = int2real(expr);                    } else if (argType == tpList) {                        if (expr->type != tpInteger && expr->type != tpReal && expr->type != tpString                            && expr->type != tpReference && expr->type != tpRawBinary && expr->type != tpBoolean)                        {                            error("User function should receive parameter of boolean, integer, real, string, reference or user defined type", pos);                        }                     } else if (argType != expr->type) {                         error("Incompatible function argument", pos);                    }                    expr = new dbExprNode(dbvmFuncInt2Bool + func->type, func->fptr, expr);                }                return field(expr, NULL, NULL);            }            error("Field not found", pos);        }        if (fd->type == dbField::tpRawBinary) {             expr = new dbExprNode(dbvmLoadSelfRawBinary, fd);        } else if (fd->type != dbField::tpStructure) {            expr = new dbExprNode(dbvmLoadSelfBool + fd->type, fd);        }         lex = scan();        return field(expr, NULL, fd);      case tkn_exists:        if (scan() == tkn_ident) {             dbBinding var;            var.next = bindings;            var.name = name;            var.used = false;            var.index = nFreeVars++;            bindings = &var;            if (nFreeVars >= maxFreeVars) {                 error("Too many nested EXISTS clauses\n");            }            pos = currPos;            if (scan() != tkn_col) {                 error("':' expected", pos);            }            expr = term();            if (expr->type != tpBoolean) {                 error("Expresion in EXISTS clause should be of boolean type");            }            if (var.used) {                 expr = new dbExprNode(dbvmExists, expr, nFreeVars-1);            }            nFreeVars -= 1;                     assert(bindings == &var);            bindings = var.next;            return expr;        } else {             error("Free variable name expected");        }               break;      case tkn_first:        lex = scan();        return field(new dbExprNode(dbvmFirst), table, NULL);      case tkn_last:        lex = scan();        return field(new dbExprNode(dbvmLast), table, NULL);      case tkn_false:        expr = new dbExprNode(dbvmLoadFalse);        break;      case tkn_true:        expr = new dbExprNode(dbvmLoadTrue);        break;      case tkn_null:        expr = new dbExprNode(dbvmLoadNull);        break;      case tkn_iconst:        expr = new dbExprNode(dbvmLoadIntConstant, ivalue);        break;      case tkn_fconst:        expr = new dbExprNode(dbvmLoadRealConstant, fvalue);        break;      case tkn_sconst:        expr = new dbExprNode(dbvmLoadStringConstant, svalue);         lex = scan();        return field(expr, NULL, NULL);      case tkn_var:        expr = new dbExprNode(dbvmLoadVarBool + varType -                               dbQueryElement::qVarBool, varPtr);        refTable = varRefTable;        lex = scan();        return field(expr, refTable, NULL);      case tkn_abs:      case tkn_length:      case tkn_lower:      case tkn_upper:      case tkn_integer:      case tkn_real:      case tkn_string:        pos = currPos;        expr = term();        switch (cop) {          case tkn_abs:            if (expr->type == tpInteger) {                 cop = dbvmAbsInt;            } else if (expr->type == tpReal) {                 cop = dbvmAbsReal;            } else {                 error("ABS function can be applied only "                      "to integer or real expression", pos);            }            break;          case tkn_length:            if (expr->type == tpArray) {                 cop = dbvmLength;            } else if (expr->type == tpString) {                 cop = dbvmStringLength;            } else {                 error("LENGTH function is defined only for arrays and strings",                      pos);            }             break;          case tkn_integer:            if (expr->type == tpReal) {                 cop = dbvmRealToInt;            } else {                 error("INTEGER function can be applied only to "                      "expression of real type", pos);            }            break;          case tkn_real:            if (expr->type == tpInteger) {                 cop = dbvmIntToReal;            } else {                 error("REAL function can be applied only to "                      "expression of integer type", pos);            }            break;          case tkn_string:            if (expr->type == tpInteger) {                 cop = dbvmIntToString;            } else if (expr->type == tpReal) {                 cop = dbvmRealToString;            } else {                 error("STRING function can be applied only "                      "to integer or real expression", pos);            }            break;          case tkn_lower:            if (expr->type != tpString) {                 error("LOWER function can be applied only to string argument",                      pos);            } else {                 cop = dbvmLowerString;            }            break;          case tkn_upper:            if (expr->type != tpString) {                 error("UPPER function can be applied only to string argument",                      pos);            } else {                 cop = dbvmUpperString;            }            break;          default:            assert(false);        }        return field(new dbExprNode(cop, expr), NULL, NULL);      case tkn_lpar:        {            expr = disjunction();            dbExprNode* list = NULL;            while (lex == tkn_comma) {                 list = new dbExprNode(dbvmList, list, expr);                expr = disjunction();            }            if (lex != tkn_rpar) {                 error("')' expected");

⌨️ 快捷键说明

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