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

📄 tokenize.c

📁 sqlite数据库管理系统开放源码
💻 C
📖 第 1 页 / 共 2 页
字号:
      if( z[i] ) i++;      *tokenType = TK_STRING;      return i;    }    case '.': {      *tokenType = TK_DOT;      return 1;    }    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9': {      *tokenType = TK_INTEGER;      for(i=1; isdigit(z[i]); i++){}      if( z[i]=='.' && isdigit(z[i+1]) ){        i += 2;        while( isdigit(z[i]) ){ i++; }        *tokenType = TK_FLOAT;      }      if( (z[i]=='e' || z[i]=='E') &&           ( isdigit(z[i+1])             || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))           )      ){        i += 2;        while( isdigit(z[i]) ){ i++; }        *tokenType = TK_FLOAT;      }      return i;    }    case '[': {      for(i=1; z[i] && z[i-1]!=']'; i++){}      *tokenType = TK_ID;      return i;    }    case '?': {      *tokenType = TK_VARIABLE;      return 1;    }    default: {      if( (*z&0x80)==0 && !isIdChar[*z] ){        break;      }      for(i=1; (z[i]&0x80)!=0 || isIdChar[z[i]]; i++){}      *tokenType = sqliteKeywordCode((char*)z, i);      return i;    }  }  *tokenType = TK_ILLEGAL;  return 1;}/*** Run the parser on the given SQL string.  The parser structure is** passed in.  An SQLITE_ status code is returned.  If an error occurs** and pzErrMsg!=NULL then an error message might be written into ** memory obtained from malloc() and *pzErrMsg made to point to that** error message.  Or maybe not.*/int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){  int nErr = 0;  int i;  void *pEngine;  int tokenType;  int lastTokenParsed = -1;  sqlite *db = pParse->db;  extern void *sqliteParserAlloc(void*(*)(int));  extern void sqliteParserFree(void*, void(*)(void*));  extern int sqliteParser(void*, int, Token, Parse*);  db->flags &= ~SQLITE_Interrupt;  pParse->rc = SQLITE_OK;  i = 0;  pEngine = sqliteParserAlloc((void*(*)(int))malloc);  if( pEngine==0 ){    sqliteSetString(pzErrMsg, "out of memory", (char*)0);    return 1;  }  pParse->sLastToken.dyn = 0;  pParse->zTail = zSql;  while( sqlite_malloc_failed==0 && zSql[i]!=0 ){    assert( i>=0 );    pParse->sLastToken.z = &zSql[i];    assert( pParse->sLastToken.dyn==0 );    pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType);    i += pParse->sLastToken.n;    switch( tokenType ){      case TK_SPACE:      case TK_COMMENT: {        if( (db->flags & SQLITE_Interrupt)!=0 ){          pParse->rc = SQLITE_INTERRUPT;          sqliteSetString(pzErrMsg, "interrupt", (char*)0);          goto abort_parse;        }        break;      }      case TK_ILLEGAL: {        sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1,            pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0);        nErr++;        goto abort_parse;      }      case TK_SEMI: {        pParse->zTail = &zSql[i];        /* Fall thru into the default case */      }      default: {        sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse);        lastTokenParsed = tokenType;        if( pParse->rc!=SQLITE_OK ){          goto abort_parse;        }        break;      }    }  }abort_parse:  if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){    if( lastTokenParsed!=TK_SEMI ){      sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse);      pParse->zTail = &zSql[i];    }    sqliteParser(pEngine, 0, pParse->sLastToken, pParse);  }  sqliteParserFree(pEngine, free);  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){    sqliteSetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc),                    (char*)0);  }  if( pParse->zErrMsg ){    if( pzErrMsg && *pzErrMsg==0 ){      *pzErrMsg = pParse->zErrMsg;    }else{      sqliteFree(pParse->zErrMsg);    }    pParse->zErrMsg = 0;    if( !nErr ) nErr++;  }  if( pParse->pVdbe && pParse->nErr>0 ){    sqliteVdbeDelete(pParse->pVdbe);    pParse->pVdbe = 0;  }  if( pParse->pNewTable ){    sqliteDeleteTable(pParse->db, pParse->pNewTable);    pParse->pNewTable = 0;  }  if( pParse->pNewTrigger ){    sqliteDeleteTrigger(pParse->pNewTrigger);    pParse->pNewTrigger = 0;  }  if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){    pParse->rc = SQLITE_ERROR;  }  return nErr;}/*** Token types used by the sqlite_complete() routine.  See the header** comments on that procedure for additional information.*/#define tkEXPLAIN 0#define tkCREATE  1#define tkTEMP    2#define tkTRIGGER 3#define tkEND     4#define tkSEMI    5#define tkWS      6#define tkOTHER   7/*** Return TRUE if the given SQL string ends in a semicolon.**** Special handling is require for CREATE TRIGGER statements.** Whenever the CREATE TRIGGER keywords are seen, the statement** must end with ";END;".**** This implementation uses a state machine with 7 states:****   (0) START     At the beginning or end of an SQL statement.  This routine**                 returns 1 if it ends in the START state and 0 if it ends**                 in any other state.****   (1) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of **                 a statement.****   (2) CREATE    The keyword CREATE has been seen at the beginning of a**                 statement, possibly preceeded by EXPLAIN and/or followed by**                 TEMP or TEMPORARY****   (3) NORMAL    We are in the middle of statement which ends with a single**                 semicolon.****   (4) TRIGGER   We are in the middle of a trigger definition that must be**                 ended by a semicolon, the keyword END, and another semicolon.****   (5) SEMI      We've seen the first semicolon in the ";END;" that occurs at**                 the end of a trigger definition.****   (6) END       We've seen the ";END" of the ";END;" that occurs at the end**                 of a trigger difinition.**** Transitions between states above are determined by tokens extracted** from the input.  The following tokens are significant:****   (0) tkEXPLAIN   The "explain" keyword.**   (1) tkCREATE    The "create" keyword.**   (2) tkTEMP      The "temp" or "temporary" keyword.**   (3) tkTRIGGER   The "trigger" keyword.**   (4) tkEND       The "end" keyword.**   (5) tkSEMI      A semicolon.**   (6) tkWS        Whitespace**   (7) tkOTHER     Any other SQL token.**** Whitespace never causes a state transition and is always ignored.*/int sqlite_complete(const char *zSql){  u8 state = 0;   /* Current state, using numbers defined in header comment */  u8 token;       /* Value of the next token */  /* The following matrix defines the transition from one state to another  ** according to what token is seen.  trans[state][token] returns the  ** next state.  */  static const u8 trans[7][8] = {                     /* Token:                                                */     /* State:       **  EXPLAIN  CREATE  TEMP  TRIGGER  END  SEMI  WS  OTHER */     /* 0   START: */ {       1,      2,    3,       3,   3,    0,  0,     3, },     /* 1 EXPLAIN: */ {       3,      2,    3,       3,   3,    0,  1,     3, },     /* 2  CREATE: */ {       3,      3,    2,       4,   3,    0,  2,     3, },     /* 3  NORMAL: */ {       3,      3,    3,       3,   3,    0,  3,     3, },     /* 4 TRIGGER: */ {       4,      4,    4,       4,   4,    5,  4,     4, },     /* 5    SEMI: */ {       4,      4,    4,       4,   6,    5,  5,     4, },     /* 6     END: */ {       4,      4,    4,       4,   4,    0,  6,     4, },  };  while( *zSql ){    switch( *zSql ){      case ';': {  /* A semicolon */        token = tkSEMI;        break;      }      case ' ':      case '\r':      case '\t':      case '\n':      case '\f': {  /* White space is ignored */        token = tkWS;        break;      }      case '/': {   /* C-style comments */        if( zSql[1]!='*' ){          token = tkOTHER;          break;        }        zSql += 2;        while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }        if( zSql[0]==0 ) return 0;        zSql++;        token = tkWS;        break;      }      case '-': {   /* SQL-style comments from "--" to end of line */        if( zSql[1]!='-' ){          token = tkOTHER;          break;        }        while( *zSql && *zSql!='\n' ){ zSql++; }        if( *zSql==0 ) return state==0;        token = tkWS;        break;      }      case '[': {   /* Microsoft-style identifiers in [...] */        zSql++;        while( *zSql && *zSql!=']' ){ zSql++; }        if( *zSql==0 ) return 0;        token = tkOTHER;        break;      }      case '"':     /* single- and double-quoted strings */      case '\'': {        int c = *zSql;        zSql++;        while( *zSql && *zSql!=c ){ zSql++; }        if( *zSql==0 ) return 0;        token = tkOTHER;        break;      }      default: {        if( isIdChar[(u8)*zSql] ){          /* Keywords and unquoted identifiers */          int nId;          for(nId=1; isIdChar[(u8)zSql[nId]]; nId++){}          switch( *zSql ){            case 'c': case 'C': {              if( nId==6 && sqliteStrNICmp(zSql, "create", 6)==0 ){                token = tkCREATE;              }else{                token = tkOTHER;              }              break;            }            case 't': case 'T': {              if( nId==7 && sqliteStrNICmp(zSql, "trigger", 7)==0 ){                token = tkTRIGGER;              }else if( nId==4 && sqliteStrNICmp(zSql, "temp", 4)==0 ){                token = tkTEMP;              }else if( nId==9 && sqliteStrNICmp(zSql, "temporary", 9)==0 ){                token = tkTEMP;              }else{                token = tkOTHER;              }              break;            }            case 'e':  case 'E': {              if( nId==3 && sqliteStrNICmp(zSql, "end", 3)==0 ){                token = tkEND;              }else if( nId==7 && sqliteStrNICmp(zSql, "explain", 7)==0 ){                token = tkEXPLAIN;              }else{                token = tkOTHER;              }              break;            }            default: {              token = tkOTHER;              break;            }          }          zSql += nId-1;        }else{          /* Operators and special symbols */          token = tkOTHER;        }        break;      }    }    state = trans[state][token];    zSql++;  }  return state==0;}

⌨️ 快捷键说明

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