📄 compiler.cpp
字号:
} if (list != NULL) { expr = new dbExprNode(dbvmList, list, expr); } } 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){ if (lex != tkn_start) { return; } int pos = currPos; if (scan() != tkn_from) { error("FROM expected after START", pos); } pos = currPos; switch (scan()) { case tkn_first: query.startFrom = dbCompiledQuery::StartFromFirst; break; case tkn_last: query.startFrom = dbCompiledQuery::StartFromLast; break; case tkn_var: if (varType == dbQueryElement::qVarReference) { if (varRefTable != table) { error("Incompatiable type of reference variable"); } query.startFrom = dbCompiledQuery::StartFromRef; } else if (varType == dbQueryElement::qVarArrayOfRef) { if (varRefTable != table) { error("Incompatiable type of array of reference variable"); } query.startFrom = dbCompiledQuery::StartFromArray; } else if (varType == dbQueryElement::qVarArrayOfRefPtr) { if (varRefTable != table) { error("Incompatiable type of array of reference variable"); } query.startFrom = dbCompiledQuery::StartFromArrayPtr; } else { error("Reference or array of reference variable expected"); } query.root = varPtr; break; default: error("FIRST, LAST or reference varaible expected", pos); } if ((lex = scan()) == tkn_follow) { pos = currPos; if (scan() != tkn_by) { error("BY expected after FOLLOW", pos); } do { pos = currPos; if (scan() != tkn_ident) { error("Field name expected", pos); } dbFieldDescriptor* fd; if ((fd = table->findSymbol(name)) == NULL) { error("Field not found"); } while (fd->type == dbField::tpStructure) { pos = currPos; if (scan() != tkn_dot) { error("'.' expected", pos); } pos = currPos; if (scan() != tkn_ident) { error("Field name expected", pos); } if ((fd = fd->find(name)) == NULL) { error("Field not found"); } } if (!(fd->type == dbField::tpReference && fd->refTable == table) && !(fd->type == dbField::tpArray && fd->components->type == dbField::tpReference && fd->components->refTable == table)) { error("Follow field should be of compatibale reference " "or array of reference type"); } dbFollowByNode* node = new dbFollowByNode; node->field = fd; node->next = query.follow; // list should be inverted query.follow = node; } while ((lex = scan()) == tkn_comma); } }void dbCompiler::compileOrderByPart(dbQuery& query){ if (lex == tkn_order) { dbOrderByNode** opp = &query.order; int pos = currPos; if (scan() != tkn_by) { error("BY expected after ORDER", pos); } int parentheses = 0; do { pos = currPos; int tkn = scan(); if (tkn == tkn_lpar) { parentheses += 1; } else { ungetToken(tkn); } dbExprNode* expr = disjunction(); dbOrderByNode* node = new dbOrderByNode; switch (expr->cop) { case dbvmLoadSelfBool: case dbvmLoadSelfInt1: case dbvmLoadSelfInt2: case dbvmLoadSelfInt4: case dbvmLoadSelfInt8: case dbvmLoadSelfReal4: case dbvmLoadSelfReal8: case dbvmLoadSelfString: case dbvmLoadSelfArray: case dbvmLoadSelfReference: case dbvmLoadSelfRawBinary: assert(expr->ref.field != NULL); node->field = expr->ref.field; node->expr = NULL; delete expr; break; case dbvmLength: if (expr->operand[0]->cop == dbvmLoadSelfArray) { node->field = expr->operand[0]->ref.field; node->expr = NULL; delete expr; break; } // no break default: if (expr->type > tpReference) { error("Expressions in ORDER BY part should have scalar type", pos); } node->field = NULL; node->expr = expr; } node->table = table; node->ascent = true; *opp = node; opp = &node->next; *opp = NULL; if (lex == tkn_desc) { node->ascent = false; lex = scan(); } else if (lex == tkn_asc) { lex = scan(); } if (lex == tkn_rpar) { if (--parentheses < 0) { error("Unbalanced parentheses "); } lex = scan(); } } while (lex == tkn_comma); }}dbExprNode* dbCompiler::compileExpression(dbTableDescriptor* table, char const* expr, int startPos){ TRACE_MSG(("Compile expression %s for table %s\n", table->name)); if (setjmp(abortCompilation) == 0) { this->table = table; bindings = NULL; nFreeVars = 0; dbQueryElement elem(dbQueryElement::qExpression, expr, NULL); queryElement = &elem; currPos = firstPos = 0; offsetWithinStatement = startPos; return disjunction(); } else { return NULL; }}bool dbCompiler::compile(dbTableDescriptor* table, dbQuery& query){ TRACE_MSG(("Compile query for table %s\n", table->name)); query.destroy(); if (setjmp(abortCompilation) == 0) { this->table = table; bindings = NULL; nFreeVars = 0; queryElement = query.elements; currPos = firstPos = 0; hasToken = false; offsetWithinStatement = query.pos; dbExprNode* expr = disjunction(); if (expr->type != tpBoolean && expr->type != tpVoid) { table->db->handleError(dbDatabase::QueryError, "Conditional " "expression should have boolean type\n", 0); delete expr; return false; } compileStartFollowPart(query); compileOrderByPart(query); query.tree = expr; query.table = table; return true; } else { for (dbOrderByNode *op = query.order, *nop; op != NULL; op = nop) { nop = op->next; delete op; } for (dbFollowByNode *fp = query.follow, *nfp; fp != NULL; fp = nfp) { nfp = fp->next; delete fp; } return false; }}dbCompiler::dbCompiler() { static struct { char* name; int tag; } keywords[] = { {"all", tkn_all}, {"abs", tkn_abs}, {"and", tkn_and}, {"asc", tkn_asc}, {"between", tkn_between}, {"by", tkn_by}, {"current", tkn_current}, {"desc", tkn_desc}, {"escape", tkn_escape}, {"exists", tkn_exists}, {"first", tkn_first}, {"false", tkn_false}, {"follow", tkn_follow}, {"from", tkn_from}, {"in", tkn_in}, {"is", tkn_is}, {"integer", tkn_integer}, {"insert", tkn_insert}, {"into", tkn_into}, {"last", tkn_last}, {"length", tkn_length}, {"like", tkn_like}, {"lower", tkn_lower}, {"not", tkn_not}, {"null", tkn_null}, {"or", tkn_or}, {"order", tkn_order}, {"real", tkn_real}, {"select", tkn_select}, {"start", tkn_start}, {"string", tkn_string}, {"table", tkn_table}, {"true", tkn_true}, {"upper", tkn_upper}, {"where", tkn_where} }; if (!initialized) { for (unsigned i = 0; i < itemsof(keywords); i++) { dbSymbolTable::add(keywords[i].name, keywords[i].tag, FASTDB_CLONE_ANY_IDENTIFIER); } initialized = true; }}void dbInheritedAttribute::removeTemporaries(){ for (dbStringValue *next, *s = tempStrings; s != NULL; s = next) { next = s->next; delete s; }}static void stderrTrace(char* msg){ fputs(msg, stderr);}dbTraceFunctionPtr dbTraceFunction = stderrTrace;void dbTrace(char* message, ...) { va_list args; va_start (args, message); char buffer[1024]; vsprintf(buffer, message, args); (*dbTraceFunction)(buffer); va_end(args);}byte* dbMalloc(size_t size){ return (byte*)malloc(size);}void dbFree(void* p){ free(p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -