1/* 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1996-2009 Oracle. All rights reserved. 5 * 6 */ 7 8#include "db_sql.h" 9 10extern void bdb_create_database(Token *, Parse *pParse); 11 12static void 13preparserSyntaxError(t, pParse) 14 Token *t; 15 Parse *pParse; 16{ 17 sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", t); 18 pParse->parseError = 1; 19} 20 21/* 22 * The pre-parser is invoked for each token found by the lexical 23 * analyzer. It passes most tokens on to the main SQLite parser 24 * unchanged; however it maintains its own state machine so that it 25 * can notice certain sequences of tokens. In particular, it catches 26 * CREATE DATABASE, which is a sequence that the SQLite parser does 27 * not recognize. 28 */ 29void preparser(pEngine, tokenType, token, pParse) 30 void *pEngine; 31 int tokenType; 32 Token token; 33 Parse *pParse; 34{ 35 static enum preparserState { 36 IDLE = 0, GOT_CREATE = 1, GOT_DATABASE = 2, GOT_NAME = 3 37 } state = IDLE; 38 39 switch (state) { 40 41 case IDLE: 42 43 if (tokenType == TK_CREATE) 44 state = GOT_CREATE; 45 else /* pass token to sqlite parser -- the common case */ 46 sqlite3Parser(pEngine, tokenType, 47 pParse->sLastToken, pParse); 48 break; 49 50 case GOT_CREATE: 51 52 if (tokenType == TK_DATABASE) 53 state = GOT_DATABASE; 54 else { /* return to idle, pass the CREATE token, then 55 * the current token to the sqlite parser */ 56 state = IDLE; 57 sqlite3Parser(pEngine, TK_CREATE, 58 pParse->sLastToken, pParse); 59 sqlite3Parser(pEngine, tokenType, 60 pParse->sLastToken, pParse); 61 } 62 break; 63 64 case GOT_DATABASE: 65 66 if (tokenType == TK_ID) { 67 state = GOT_NAME; 68 bdb_create_database(&token, pParse); 69 } else 70 preparserSyntaxError(&token, pParse); 71 72 break; 73 74 case GOT_NAME: 75 76 if (tokenType == TK_SEMI) 77 state = IDLE; 78 else 79 preparserSyntaxError(&token, pParse); 80 break; 81 } 82} 83