diff options
Diffstat (limited to 'storage/ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp')
-rw-r--r-- | storage/ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/storage/ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp b/storage/ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp new file mode 100644 index 00000000000..29aa876f669 --- /dev/null +++ b/storage/ndb/src/old_files/client/odbc/codegen/SimpleScan.lpp @@ -0,0 +1,243 @@ +%{ +#include <ctype.h> +#include "SimpleParser.hpp" + +struct SqlKeyword { + const char* m_name; + int m_value; + int m_state; + static const SqlKeyword* find(Ctx& ctx, const char* name, int state); +}; + +%} + +%option c++ +%option yyclass="SimpleParser" +%option stack +%option noyywrap + +space [\040\t\n\r\f] +digit [0-9] +letter [A-Za-z_] +special ("$") +identifier ({letter}({letter}|{digit}|{special})*) +integer {digit}++ +decimal (({digit}*\.{digit}+)|({digit}+\.{digit}*)) +real ((({digit}*\.{digit}+)|({digit}+\.{digit}*)|({digit}+))([Ee][-+]?{digit}+)) + +%s StateEval +%s StateType +%s StatePhys +%x StateString +%x StateQuoted + +%% + +{space} { + } +{identifier} { + const SqlKeyword* key = SqlKeyword::find(m_ctx, (char*)yytext, YYSTATE); + if (key != 0) + return key->m_value; + for (unsigned char* a = (unsigned char*)yytext; *a != 0; a++) { + if (islower(*a)) + *a = toupper(*a); + } + m_yylval.m_string = strcpy(new char[yyleng + 1], yytext); + return T_IDENTIFIER; + } +{integer} { + m_yylval.m_string = strcpy(new char[yyleng + 1], yytext); + return T_LINTEGER; + } +{decimal} { + m_yylval.m_string = strcpy(new char[yyleng + 1], yytext); + return T_LDECIMAL; + } +{real} { + m_yylval.m_string = strcpy(new char[yyleng + 1], yytext); + return T_LREAL; + } +"--".* { + } +"/*" { + int c = 0, d; + while (1) { + d = c; + if ((c = yyinput()) == EOF) { + parseError("unterminated comment"); + yyterminate(); + } + if (d == '*' && c == '/') + break; + } + } +<StateEval>{ +"+" return T_PLUS; +"-" return T_MINUS; +"*" return T_TIMES; +"/" return T_DIVIDE; +"=" return T_EQ; +"!=" return T_NOTEQ; +"^=" return T_NOTEQ; +"<>" return T_NOTEQ; +"<" return T_LT; +"<=" return T_LTEQ; +">" return T_GT; +">=" return T_GTEQ; +"?" m_paramNumber++; return T_QUES; +} + +"." return T_PERIOD; +"," return T_COMMA; +"(" return T_PARENLEFT; +")" return T_PARENRIGHT; +"*" return T_ASTERISK; +"=" return T_ASSIGN; + +"'" { + pushState(StateString); + m_string.assign(""); + } +<StateString>{ +[^']* { + m_string.append(yytext); + } +"''" { + m_string.append("'"); + } +"'" { + m_yylval.m_string = strcpy(new char[m_string.length() + 1], m_string.c_str()); + popState(); + return T_STRING; + } +} + +\" { + pushState(StateQuoted); + m_string.assign(""); + } +<StateQuoted>{ +[^"]* { + m_string.append(yytext); + } +\\\" { + m_string.append("\""); + } +\" { + m_yylval.m_string = strcpy(new char[m_string.length() + 1], m_string.c_str()); + popState(); + return T_IDENTIFIER; + } +} + +%% + +// scan states +int SimpleParser_stateEval = StateEval; +int SimpleParser_stateType = StateType; +int SimpleParser_statePhys = StatePhys; + +// keep sorted + +static const SqlKeyword sqlKeyword[] = { + { "AND", T_AND, -1 }, + { "ASC", T_ASC, -1 }, + { "AUTO_INCREMENT", T_AUTO_INCREMENT, -1 }, + { "BIGINT", T_BIGINT, StateType }, + { "BINARY", T_BINARY, StateType }, + { "BLOB", T_BLOB, StateType }, + { "BY", T_BY, -1 }, + { "CHAR", T_CHAR, StateType }, + { "CLOB", T_CLOB, StateType }, + { "CONSTRAINT", T_CONSTRAINT, -1 }, + { "CREATE", T_CREATE, -1 }, + { "DATETIME", T_DATETIME, StateType }, + { "DEFAULT", T_DEFAULT, -1 }, + { "DELETE", T_DELETE, -1 }, + { "DESC", T_DESC, -1 }, + { "DISTINCT", T_DISTINCT, -1 }, + { "DOUBLE", T_DOUBLE, StateType }, + { "DROP", T_DROP, -1 }, + { "FLOAT", T_FLOAT, StateType }, + { "FOREIGN", T_FOREIGN, -1 }, + { "FROM", T_FROM, -1 }, + { "GROUP", T_GROUP, -1 }, + { "HASH", T_HASH, -1 }, + { "HAVING", T_HAVING, -1 }, + { "IN", T_IN, -1 }, + { "INDEX", T_INDEX, -1 }, + { "INSERT", T_INSERT, -1 }, + { "INT", T_INT, StateType }, + { "INTEGER", T_INTEGER, StateType }, + { "INTO", T_INTO, -1 }, + { "IS", T_IS, -1 }, + { "KEY", T_KEY, -1 }, + { "LARGE", T_LARGE, StatePhys }, + { "LIKE", T_LIKE, -1 }, + { "LIMIT", T_LIMIT, -1 }, + { "LOGGING", T_LOGGING, StatePhys }, + { "LONGBLOB", T_LONGBLOB, StateType }, + { "LONGCLOB", T_LONGCLOB, StateType }, + { "MEDIUM", T_MEDIUM, StatePhys }, + { "NOLOGGING", T_NOLOGGING, StatePhys }, + { "NOT", T_NOT, -1 }, + { "NULL", T_NULL, -1 }, + { "OFFSET", T_OFFSET, -1 }, + { "ON", T_ON, -1 }, + { "OR", T_OR, -1 }, + { "ORDER", T_ORDER, -1 }, + { "PRECISION", T_PRECISION, StateType }, + { "PRIMARY", T_PRIMARY, -1 }, + { "REAL", T_REAL, StateType }, + { "REFERENCES", T_REFERENCES, -1 }, + { "ROWNUM", T_ROWNUM, -1 }, + { "SELECT", T_SELECT, -1 }, + { "SET", T_SET, -1 }, + { "SINGLE", T_SINGLE, StatePhys }, + { "SMALL", T_SMALL, StatePhys }, + { "SMALLINT", T_SMALLINT, StateType }, + { "STORAGE", T_STORAGE, StatePhys }, + { "SYSDATE", T_SYSDATE, -1 }, + { "TABLE", T_TABLE, -1 }, + { "UNIQUE", T_UNIQUE, -1 }, + { "UNSIGNED", T_UNSIGNED, -1 }, + { "UPDATE", T_UPDATE, -1 }, + { "VALUES", T_VALUES, -1 }, + { "VARBINARY", T_VARBINARY, StateType }, + { "VARCHAR", T_VARCHAR, StateType }, + { "WHERE", T_WHERE, -1 }, + { "WRITE", T_WRITE, -1 } +}; + +static const unsigned sqlKeywordCount = sizeof(sqlKeyword) / sizeof(sqlKeyword[0]); + +const SqlKeyword* +SqlKeyword::find(Ctx& ctx, const char* name, int state) +{ + ctx_log4(("find keyword '%s' lex state = %d", name, state)); + const unsigned maxlen = 99; + char buf[maxlen + 1]; + char* a = buf; + const char* b = name; + while (*b != 0) { + if (a >= buf + maxlen) // will not be found + break; + char c = *b++; + if ('a' <= c && c <= 'z') // locale independent + c -= 'a' - 'A'; + *a++ = c; + } + *a = 0; + for (unsigned i = 0; i < sqlKeywordCount; i++) { + const SqlKeyword* key = &sqlKeyword[i]; + if (strcmp(key->m_name, buf) == 0) { + if (key->m_state != -1 && key->m_state != state) + return 0; + return key; + } + } + return 0; +} + +/* vim: set filetype=lex: */ |