From 3cb24ce3b310a282ed41c09847aac3c809eb31f7 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 5 Jan 2019 12:19:50 -0500 Subject: [PATCH] Continue work separating parser into clean library module. --- Makefile.am | 2 +- lib.c | 45 ++++++++++++++++++++++++++++++++ main.c | 52 +++++++++++++++++++++++++++++++++++++ sql-parser.h | 7 +++++ sql.y | 73 +--------------------------------------------------- yyl.h | 38 +++++++++++++++++++++++++++ 6 files changed, 144 insertions(+), 73 deletions(-) create mode 100644 lib.c create mode 100644 main.c create mode 100644 yyl.h diff --git a/Makefile.am b/Makefile.am index ee62ca7..c8cdcfa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,7 +29,7 @@ EXTRA_DIST = sql.y sql.l \ ok9.sql \ ok10.sql -sql_SOURCES = exec.c sql-parser.h +sql_SOURCES = exec.c lib.c main.c sql-parser.h yyl.h sql_LDADD = @JANSSON_LIBS@ nodist_sql_SOURCES = sql.c sql.tab.c sql.tab.h sql.lex.h diff --git a/lib.c b/lib.c new file mode 100644 index 0000000..2a0a308 --- /dev/null +++ b/lib.c @@ -0,0 +1,45 @@ + +#include +#include +#include +#include + +#include "sql.tab.h" +#include "yyl.h" +#include "sql.lex.h" +#include "sql-parser.h" + +struct psql_state *psql_new(void) +{ + struct psql_state *st = calloc(1, sizeof(*st)); + if (!st) + return NULL; + + if (yylex_init_extra(st, &st->scanner)) { + free(st); + return NULL; + } + + return st; +} + +void psql_free(struct psql_state *st) +{ + if (!st) + return; + + yylex_destroy(st->scanner); + + free(st); +} + +void psql_set_input(struct psql_state *pstate, FILE *in_f) +{ + yyset_in(in_f, pstate->scanner); +} + +int psql_parse(struct psql_state *pstate) +{ + return yyparse(pstate->scanner, pstate); +} + diff --git a/main.c b/main.c new file mode 100644 index 0000000..2517ac8 --- /dev/null +++ b/main.c @@ -0,0 +1,52 @@ + +#include +#include +#include + +#include "sql.tab.h" +#include "yyl.h" +#include "sql.lex.h" +#include "sql-parser.h" + +extern char *filename; + +int +main(int ac, char **av) +{ + FILE *in_f; + struct psql_state *pstate; + + if(ac > 1 && !strcmp(av[1], "-d")) { + yydebug = 1; ac--; av++; // TODO: move global into lib (layering issue) + } + + pstate = psql_new(); + if (!pstate) + abort(); + + if(ac > 1) { + if((in_f = fopen(av[1], "r")) == NULL) { + perror(av[1]); + exit(1); + } + filename = av[1]; + } else { + filename = "(stdin)"; + in_f = stdin; + } + + psql_set_input(pstate, in_f); + + int res = psql_parse(pstate); + + psql_free(pstate); + + if (!res) { + printf("{\"result\":true}\n"); + return 0; + } else { + printf("{\"result\":false}\n"); + return 1; + } +} /* main */ + diff --git a/sql-parser.h b/sql-parser.h index c8dccf4..cef4574 100644 --- a/sql-parser.h +++ b/sql-parser.h @@ -1,6 +1,8 @@ #ifndef __SQL_PARSER_H__ #define __SQL_PARSER_H__ +#include + enum sqlp_col_attribs { SCA_NOTNULL = (1 << 0), SCA_DEF_STR = (1 << 1), @@ -56,6 +58,11 @@ struct psql_state { yyscan_t scanner; }; +extern struct psql_state *psql_new(void); +extern void psql_free(struct psql_state *st); +extern void psql_set_input(struct psql_state *st, FILE *f); +extern int psql_parse(struct psql_state *st); + extern void sqlp_alias(struct psql_state *pstate, const char *alias); extern void sqlp_assign(struct psql_state *pstate, const char *db_name, const char *name); extern void sqlp_assign_at(struct psql_state *pstate, const char *name); diff --git a/sql.y b/sql.y index 0eaba10..0e54cf9 100644 --- a/sql.y +++ b/sql.y @@ -30,39 +30,7 @@ %code requires { char *filename; -typedef struct YYLTYPE { - int first_line; - int first_column; - int last_line; - int last_column; - char *filename; -} YYLTYPE; -# define YYLTYPE_IS_DECLARED 1 - -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - (Current).filename = YYRHSLOC (Rhs, 1).filename; \ - } \ - else \ - { /* empty RHS */ \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - (Current).filename = NULL; \ - } \ - while (0) - -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif +#include "yyl.h" struct psql_state; } @@ -1020,42 +988,3 @@ lyyerror(YYLTYPE t, const char *s, ...) fprintf(stderr, "\n"); } -int -main(int ac, char **av) -{ - FILE *in_f; - struct psql_state pstate; - - if(ac > 1 && !strcmp(av[1], "-d")) { - yydebug = 1; ac--; av++; - } - - memset(&pstate, 0, sizeof(pstate)); - if (yylex_init_extra(&pstate, &pstate.scanner)) - return 1; - - if(ac > 1) { - if((in_f = fopen(av[1], "r")) == NULL) { - perror(av[1]); - exit(1); - } - filename = av[1]; - } else { - filename = "(stdin)"; - in_f = stdin; - } - - yyset_in(in_f, pstate.scanner); - - int res = yyparse(pstate.scanner, &pstate); - - yylex_destroy(pstate.scanner); - - if (!res) { - printf("{\"result\":true}\n"); - return 0; - } else { - printf("{\"result\":false}\n"); - return 1; - } -} /* main */ diff --git a/yyl.h b/yyl.h new file mode 100644 index 0000000..47b03ec --- /dev/null +++ b/yyl.h @@ -0,0 +1,38 @@ +#ifndef __YYL_H__ +#define __YYL_H__ + +typedef struct YYLTYPE { + int first_line; + int first_column; + int last_line; + int last_column; + char *filename; +} YYLTYPE; +# define YYLTYPE_IS_DECLARED 1 + +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + (Current).filename = YYRHSLOC (Rhs, 1).filename; \ + } \ + else \ + { /* empty RHS */ \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + (Current).filename = NULL; \ + } \ + while (0) + +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +#endif // __YYL_H__