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

📄 compiler.cpp

📁 最新版本!fastdb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//-< COMPILE.CPP >---------------------------------------------------*--------*
// FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
// (Main Memory Database Management System)                          *   /\|  *
//                                                                   *  /  \  *
//                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
//                          Last update: 15-Jan-99    K.A. Knizhnik  * GARRET *
//-------------------------------------------------------------------*--------*
// Conditional expresion compiler
//-------------------------------------------------------------------*--------*

#define INSIDE_FASTDB

#include "database.h"
#include "array.h"
#include "query.h"
#include "cursor.h"
#include "compiler.h"
#include "symtab.h"

#include <ctype.h>

BEGIN_FASTDB_NAMESPACE

nat1 const dbExprNode::nodeTypes[] = { 
#define DBVM(cop, type, n_opernads, commutative) type,
// in the RAID - we cannot use source file with a '.d' suffix - this clashes
// with the CFW build system (specific to StoreAge build system)).
#ifdef VXWORKS
#include "compiler.dd"
#else
#include "compiler.d"
#endif // VXWORKS
0};

nat1 const dbExprNode::nodeOperands[] = { 
#define DBVM(cop, type, n_operands, commutative) n_operands,
// in the RAID - we cannot use source file with a '.d' suffix - this clashes
// with the CFW build system (specific to StoreAge build system).
#ifdef VXWORKS
#include "compiler.dd"
#else
#include "compiler.d"
#endif // VXWORKS
0};

nat1 const dbExprNode::commutativeOperator[] = { 
#define DBVM(cop, type, n_operands, commutative) commutative,
// in the RAID - we cannot use source file with a '.d' suffix - this clashes
// with the CFW build system (specific to StoreAge build system).
#ifdef VXWORKS
#include "compiler.dd"
#else
#include "compiler.d"
#endif // VXWORKS
0};


bool        dbCompiler::initialized;

dbExprNodeAllocator dbExprNodeAllocator::instance; 

dbExprNodeAllocator::~dbExprNodeAllocator() {
    dbExprNodeSegment* segm = segmentList; 
    while (segm != NULL) { 
        dbExprNodeSegment* next = segm->next;
        delete segm;
        segm = next;
    }
}

inline dbExprNode* dbExprNodeAllocator::allocate()
{
    dbCriticalSection cs(mutex);
    dbExprNode* node = freeNodeList;
    if (node == NULL) {
        dbExprNodeSegment* seg = new dbExprNodeSegment;
        seg->next = segmentList;
        segmentList = seg;
        node = (dbExprNode*)seg->buf;
        dbExprNode* free = NULL;
        for (int i = dbExprNodeSegment::allocationQuantum; --i != 0;) {
            node->next = free;
            free = node++;
        }
        freeNodeList = free;
    } else {
        freeNodeList = node->next;
    }
    return node;
}

void dbExprNodeAllocator::deallocate(dbExprNode* node)
{
    if (node != NULL) { 
        node->next = freeNodeList;
        freeNodeList = node;
    }
}

void dbExprNodeAllocator::reset()
{
    dbExprNode* free = NULL;
    for (dbExprNodeSegment* seg = segmentList; seg != NULL; seg = seg->next)
    {
        dbExprNode* node = (dbExprNode*)seg->buf;
        for (int i = dbExprNodeSegment::allocationQuantum; --i >= 0;) {
            node->next = free;
            free = node++;
         }
    }
    freeNodeList = free;
}

dbExprNode::dbExprNode(dbExprNode* node)
{
    memcpy(this, node, sizeof(*this));
    
    for (int i = nodeOperands[cop]; --i >= 0;) { 
        operand[i] = new dbExprNode(operand[i]);
    }
    if (cop == dbvmLoadStringConstant) { 
        char* s = new char[strlen(svalue.str)+1];
        strcpy(s, svalue.str);
        svalue.str = s;
    } 
}

dbExprNode::~dbExprNode()
{
    if (cop == dbvmLoadStringConstant) { 
        delete[] svalue.str;
#ifdef USE_REGEX
    } else if (cop == dbvmMatchString) { 
        delete regex.opd;
        regfree(&regex.re);
#endif
    } else { 
        for (int i = nodeOperands[cop]; --i >= 0; ) { 
            delete operand[i];
        }
    }
}

int dbCompiler::scan() 
{
    char ch;
    char *p, *q;
    int  i, n, value;
    char buf[maxStrLen+1];

    if (hasToken) { 
        hasToken = false;
        return lex;
    }
   nextElement:
    if (queryElement == NULL) { 
        return tkn_eof;
    }
    if (queryElement->type != dbQueryElement::qExpression) {
        varType = queryElement->type;
        varPtr = queryElement->ptr;
        varRefTable = queryElement->ref;
        if (varRefTable != NULL) { 
            varRefTable = table->db->lookupTable(varRefTable);
        }
        queryElement = queryElement->next;
        return tkn_var;
    } 
    p = q = (char*)queryElement->ptr + currPos;
    
    do { 
        ch = *p++;
        if (ch == '\n') { 
            offsetWithinStatement = (char*)queryElement->ptr - p;
            firstPos = 0;
        }
    } while (isspace(byte(ch)));
    currPos += p - q;

    switch (ch) { 
      case '\0':
        if ((queryElement = queryElement->next) == NULL) { 
            return tkn_eof;
        }
        currPos = 0;
        goto nextElement;
      case '+':
        return tkn_add;
      case '-':
        if (*p == '-') { 
            // ANSI comments
            q = p;
            do { 
                p += 1;
            } while (*p != '\n' && *p != '\0');
            currPos += p - q;
            goto nextElement;
        }
        return tkn_sub;
      case '*':
        return tkn_mul;
      case '/':
        return tkn_div;
      case '.':
        return tkn_dot;
      case ',':
        return tkn_comma;
      case '(':
        return tkn_lpar;
      case ')':
        return tkn_rpar;
      case '[':
        return tkn_lbr;
      case ']':
        return tkn_rbr;
      case ':':
        return tkn_col;
      case '^':
        return tkn_power;
      case '<':
        if (*p == '=') { 
            currPos += 1;
            return tkn_le;
        } else if (*p == '>') { 
            currPos += 1;
            return tkn_ne;
        }
        return tkn_lt;
      case '>':
        if (*p == '=') { 
            currPos += 1;
            return tkn_ge;
        }
        return tkn_gt;
      case '=':
        return tkn_eq;
      case '!':
        if (*p != '=') { 
            error("Invalid token '!'");
        } 
        currPos += 1;
        return tkn_ne;
      case '|':
        if (*p != '|') { 
            error("Invalid token '|'");
        } 
        currPos += 1;
        return tkn_add;
      case '\'':
        q = p;
        i = 0; 
        while (true) { 
            if (*p == '\'') { 
                if (*++p != '\'') { 
                    break;
                }
            } else if (*p == '\0') { 
                error("Unterminated character constant");
            }
            if (i == maxStrLen) { 
                error("String constant too long");
            }
            buf[i++] = *p++;
        }
        buf[i++] = '\0';
        currPos += p - q;
        svalue.str = new char[i];
        strcpy(svalue.str, buf);
        svalue.len = i;
        return tkn_sconst;
      case '#':
        ivalue = 0;
        q = p;
        while (true) { 
            ch = *p++;
            if (ch >= '0' && ch <= '9') { 
                ivalue = (ivalue << 4) + ch-'0';
            } else if (ch >= 'a' && ch <= 'f') {
                ivalue = (ivalue << 4) + ch-'a'+10;
            } else if (ch >= 'A' && ch <= 'F') {
                ivalue = (ivalue << 4) + ch-'A'+10;
            } else { 
                currPos += p - q - 1; 
                return tkn_iconst;
            }
        }
      case '0': case '1': case '2': case '3': case '4': 
      case '5': case '6': case '7': case '8': case '9':
        value = ch - '0';
        for (q = p; isdigit(*(byte*)p); p++) { 
            value = value*10 + *p - '0';
        }
        if (*p == '.' || *p == 'e' || *p == 'E') { 
            if (sscanf(q-1, "%lf%n", &fvalue, &n) != 1) { 
                error("Bad floating point constant");
            }
            currPos += n - 1;
            return tkn_fconst;
        } else if (p - q >= 9) { 
            if (sscanf(q-1, INT8_FORMAT "%n", &ivalue, &n) != 1) { 
                error("Bad integer constant");
            }
            currPos += n - 1;
            return tkn_iconst;
        } else { 
            currPos += p - q; 
            ivalue = value;
            return tkn_iconst;
        }
      default:
        if (isalpha(ch) || ch == '$' || ch == '_') { 
            i = 0;
            do { 
                if (i == maxStrLen) { 
                    error("Name too long");
                }
                buf[i++] = ch;
                ch = *p++;
            } while (isalnum(ch) || ch == '$' || ch == '_');
            buf[i] = '\0';
            name = buf;
            currPos += i - 1;
        } else { 
            error("Invalid symbol");
        } 
        return dbSymbolTable::add(name, tkn_ident);
   }
}

dbExprNode* dbCompiler::disjunction()
{
    dbExprNode* left = conjunction();
    if (lex == tkn_or) { 
        int pos = currPos;
        dbExprNode* right = disjunction();
        if (left->type == tpInteger && right->type == tpInteger) { 
            left = new dbExprNode(dbvmOrInt, left, right);
        } else if (left->type == tpBoolean && right->type == tpBoolean) { 
            left = new dbExprNode(dbvmOrBool, left, right);
        } else { 
            error("Bad operands for OR operator", pos);
        }
    }

⌨️ 快捷键说明

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