diff --git a/source/esql.l b/source/esql.l index 4bcf7a8..060ee57 100644 --- a/source/esql.l +++ b/source/esql.l @@ -10,6 +10,8 @@ using namespace std; extern Database * db; +int state_buffer; + string sql = ""; extern YY_BUFFER_STATE esql__scan_string (const char * yystr); @@ -19,10 +21,12 @@ extern int esql_parse (void); %option noyywrap %option nodefault -%x SQL TEST +%x SQL DECLARE +%x EAT2COLON ws [ \t\r\v\f] wsnl [ \t\r\v\f\n] +identifier [a-zA-Z_$][a-zA-Z_0-9$]* %% @@ -54,11 +58,29 @@ EXEC{wsnl}+SQL{wsnl}+ { } { -CONNECT\ TO { return CONNECT; } -AS { return AS; } ; { BEGIN INITIAL; return END; } . { esql_lval.strval = yytext; return CHAR; } \n { ; } + +CONNECT{wsnl}+TO { return CONNECT; } +AS { return AS; } + +BEGIN{wsnl}+DECLARE{wsnl}+SECTION{wsnl}*; { BEGIN DECLARE; return DECLARE_START; } +} + +{ +const { ECHO; } // XXX: this is no good +extern|static { ECHO; } +{identifier} { ECHO; return IDENTIFIER; } +\*|\[.*\] { ECHO; return PTR; } += { BEGIN EAT2COLON; ECHO; state_buffer = DECLARE; } +{wsnl} { ECHO; } +EXEC{wsnl}+SQL{wsnl}+END{wsnl}+DECLARE{wsnl}+SECTION{wsnl}*; { BEGIN INITIAL; return DECLARE_END; } +} + +{ +; { ECHO; BEGIN state_buffer; } +.|\n { ECHO; } } %% diff --git a/source/esql.y b/source/esql.y index dc4f250..db1a02f 100644 --- a/source/esql.y +++ b/source/esql.y @@ -1,8 +1,9 @@ -%code { +%code provides { #include #include extern FILE * esql_out; +extern int esql_errno; #define ECHOS(s) do { \ const char * const ss = s; \ @@ -28,6 +29,8 @@ void esql_error(const char *s); using namespace std; +int esql_errno; + %} %union { @@ -35,37 +38,64 @@ using namespace std; char* strval; } -%token CONNECT AS -%token CHAR +%token CONNECT AS DECLARE_START DECLARE_END +%token CHAR IDENTIFIER PTR %token END %type statement substatemt string +%type pointer + +%initial-action { + ECHOS(db->top()); +} %% sql: %empty | sql connect | sql statement + | sql declaration + ; + +declaration: DECLARE_START var DECLARE_END + ; + +var: %empty + | IDENTIFIER pointer IDENTIFIER { + db->declare($1, $3); + } + ; + +pointer: %empty { $$ = 0; } + | pointer PTR { $$ = $1 + 1; } ; connect: CONNECT string AS string END { - ECHOS(db->connect($2, $4)); + ECHOS(db->connect($2, $4)); } ; statement: substatemt END { - ECHOS(db->exec($$)); + const char * const e = db->exec((string() + $$ + ';').c_str()); + if(!e) { break; } + ECHOS(e); } ; -substatemt: string - | substatemt string +// pretty sure this could be all on the stack +substatemt: string { $$ = strdup((string() + $1).c_str()); free($1); } + | substatemt string { $$ = strdup((string() + $1 + $2).c_str()); free($1); } ; -string: CHAR - | string CHAR +string: CHAR { $$ = strdup((string() + $1).c_str()); } + | string CHAR { $$ = strdup((string() + $1 + $2).c_str()); free($1); } ; %% void esql_error(const char * msg) { - fprintf(stderr, "\033[1m%s:%d:\033[0m \033[31m%s\033[0m\n", esql_filename, esql_lineno, msg); + fprintf(stderr, "\033[1m%s:%d:\033[0m \033[31m%s\033[0m\n", + esql_filename, + esql_lineno, + msg + ); + esql_errno = 1; }