slightly more capable parsing
This commit is contained in:
parent
9296b01d19
commit
714952004b
@ -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}+ {
|
||||
}
|
||||
|
||||
<SQL>{
|
||||
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; }
|
||||
}
|
||||
|
||||
<DECLARE>{
|
||||
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; }
|
||||
}
|
||||
|
||||
<EAT2COLON>{
|
||||
; { ECHO; BEGIN state_buffer; }
|
||||
.|\n { ECHO; }
|
||||
}
|
||||
|
||||
%%
|
||||
|
@ -1,8 +1,9 @@
|
||||
%code {
|
||||
%code provides {
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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 <strval> CHAR
|
||||
%token CONNECT AS DECLARE_START DECLARE_END
|
||||
%token <strval> CHAR IDENTIFIER PTR
|
||||
%token <strval> END
|
||||
|
||||
%type <strval> statement substatemt string
|
||||
%type <intval> 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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user