compiler.cpp
来自「FastDb是高效的内存数据库系统」· C++ 代码 · 共 1,688 行 · 第 1/5 页
CPP
1,688 行
} else if (fd->type == dbField::tpRectangle) { expr = new dbExprNode(expr != NULL ? dbvmLoadRectangle: dbvmLoadSelfRectangle, fd, expr); } else if (fd->type != dbField::tpStructure) { expr = new dbExprNode((expr != NULL ? dbvmLoadBool : dbvmLoadSelfBool) + fd->type, fd, expr); } lex = scan(); }}dbExprNode* dbCompiler::buildList() { dbExprNode* expr = disjunction(); return new dbExprNode(dbvmList, expr, lex == tkn_comma ? buildList() : NULL);}dbExprNode* dbCompiler::term() { dbFieldDescriptor* fd; dbTableDescriptor* refTable; int cop; int pos = currPos; int prevLex = lex; dbBinding* bp; dbExprNode* expr = NULL; dbUserFunction* func; if ((cop = scan()) == tkn_where) { if (firstPos == 0) { firstPos = currPos; } cop = scan(); // just ignore 'where' keyword } lex = cop; switch (cop) { case tkn_eof: case tkn_order: case tkn_start: case tkn_limit: 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]; int n = 0; do { if (n == nParams) { error("Too many parameters for user defined function"); } dbExprNode* param = expr->operand[0]; 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[n++] = param; expr = expr->operand[1]; } while (expr != NULL); if (n != nParams) { 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::tpRectangle) { expr = new dbExprNode(dbvmLoadSelfRectangle, 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_area: 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_area: if (expr->type == tpRectangle) { cop = dbvmRectangleArea; } else if (expr->type == tpList) { expr = rectangleConstant(expr); cop = dbvmRectangleArea; } else { error("AREA function can be applied only to rectangles", 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(); if (lex == tkn_comma) { expr = new dbExprNode(dbvmList, expr, buildList()); } else if (prevLex == tkn_in) { expr = new dbExprNode(dbvmList, expr); } if (lex != tkn_rpar) { error("')' expected"); } } break; case tkn_not: pos = currPos; expr = comparison(); if (expr->type == tpInteger) { if (expr->cop == dbvmLoadIntConstant) { expr->ivalue = ~expr->ivalue; } else { expr = new dbExprNode(dbvmNotInt, expr); } return expr; } else if (expr->type == tpBoolean) { return new dbExprNode(dbvmNotBool, expr); } else { error("NOT operator can be applied only to " "integer or boolean expressions", pos); } break; case tkn_add: error("Using of unary plus operator has no sence"); break; case tkn_sub: pos = currPos; expr = term(); if (expr->type == tpInteger) { if (expr->cop == dbvmLoadIntConstant) { expr->ivalue = -expr->ivalue; } else { expr = new dbExprNode(dbvmNegInt, expr); } return expr; } else if (expr->type == tpReal) { if (expr->cop == dbvmLoadRealConstant) { expr->fvalue = -expr->fvalue; } else { expr = new dbExprNode(dbvmNegReal, expr); } return expr; } else { error("Unary minus can be applied only to " "integer or real expressions", pos); } default: error("operand expected"); } lex = scan(); return expr;}void dbCompiler::error(const char* msg, int pos) { if (pos < 0) { if ((pos = currPos-1) < 0) { pos = 0; } } else if (pos < firstPos) { pos = firstPos; } if (pos + offsetWithinStatement >= 0) { pos += offsetWithinStatement; } table->db->handleError(dbDatabase::QueryError, msg, pos); longjmp(abortCompilation, dbDatabase::QueryError);}void dbCompiler::compileStartFollowPart(dbQuery& query)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?