slightly more capable parsing

This commit is contained in:
anon 2024-05-30 14:29:33 +02:00
parent 9296b01d19
commit 714952004b
2 changed files with 65 additions and 13 deletions

View File

@ -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; }
}
%%

View File

@ -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;
}