Continue work separating parser into clean library module.

This commit is contained in:
Jeff Garzik 2019-01-05 12:19:50 -05:00
parent e0d92a4749
commit 3cb24ce3b3
6 changed files with 144 additions and 73 deletions

View File

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

45
lib.c Normal file
View File

@ -0,0 +1,45 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <jansson.h>
#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);
}

52
main.c Normal file
View File

@ -0,0 +1,52 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#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 */

View File

@ -1,6 +1,8 @@
#ifndef __SQL_PARSER_H__
#define __SQL_PARSER_H__
#include <stdio.h>
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);

73
sql.y
View File

@ -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 */

38
yyl.h Normal file
View File

@ -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__