first working version of a query parser.
parent
f8b04626f2
commit
23434e765e
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
yacc -t -d query.yacc && lex query.lex && gcc -g *.c
|
|
@ -0,0 +1,36 @@
|
|||
// -*- go -*-
|
||||
|
||||
// definitions
|
||||
|
||||
%{
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
%}
|
||||
|
||||
|
||||
// rules
|
||||
%union
|
||||
{
|
||||
node Node
|
||||
}
|
||||
%type <node> hello
|
||||
%%
|
||||
|
||||
hello: 'hello'
|
||||
{
|
||||
// whatever
|
||||
}
|
||||
|
||||
// subroutines
|
||||
%%
|
||||
type Lexer int
|
||||
|
||||
func (self *Lexer) Lex(yylval *query_SymType) int {
|
||||
fmt.Printf("got %v\n", yylval)
|
||||
return 0;
|
||||
}
|
||||
|
||||
func (self *Lexer) Error(e error) {
|
||||
fmt.Printf("Error: %s\n", err)
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,24 @@
|
|||
%{
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "query_types.h"
|
||||
#include "y.tab.h"
|
||||
%}
|
||||
|
||||
%option reentrant
|
||||
%option bison-bridge
|
||||
%option noyywrap
|
||||
%%
|
||||
|
||||
; { return *yytext; }
|
||||
from { return FROM; }
|
||||
where { return WHERE; }
|
||||
select { return SELECT; }
|
||||
= { return *yytext; }
|
||||
[a-zA-Z][a-zA-Z0-9]* { yylval->string = strdup(yytext); return NAME; }
|
||||
[0-9]+ { yylval->i = atoi(yytext); return INT_VALUE; }
|
||||
\'.*\' {
|
||||
yytext[yyleng-1] = '\0';
|
||||
yylval->string = strdup(yytext+1);
|
||||
return STRING_VALUE;
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include "query_types.h"
|
||||
%}
|
||||
|
||||
%union {
|
||||
char *string;
|
||||
int i;
|
||||
from *f;
|
||||
where *w;
|
||||
value *v;
|
||||
}
|
||||
|
||||
// debugging
|
||||
%debug
|
||||
|
||||
// declare that we want a reentrant parser
|
||||
%define api.pure
|
||||
%parse-param {query *q}
|
||||
%parse-param {void *scanner}
|
||||
%lex-param {void *scanner}
|
||||
|
||||
%token SELECT FROM WHERE EQUAL
|
||||
%token <string> NAME STRING_VALUE
|
||||
%token <i> INT_VALUE
|
||||
|
||||
%type <f> FROM_CLAUSE
|
||||
%type <string> TABLE_NAME
|
||||
%type <string> FIELD_NAME
|
||||
%type <w> WHERE_CLAUSE
|
||||
%type <v> FIELD_VALUE
|
||||
%start QUERY
|
||||
|
||||
%%
|
||||
QUERY: SELECT FROM_CLAUSE WHERE_CLAUSE ';'
|
||||
{
|
||||
q->f = $2;
|
||||
q->w = $3;
|
||||
}
|
||||
|
||||
FROM_CLAUSE: FROM TABLE_NAME
|
||||
{
|
||||
$$ = malloc(sizeof(from));
|
||||
$$->table = $2;
|
||||
}
|
||||
|
||||
WHERE_CLAUSE: WHERE FIELD_NAME '=' FIELD_VALUE
|
||||
{
|
||||
$$ = malloc(sizeof(where));
|
||||
$$->column_name = $2;
|
||||
$$->op = OP_EQUAL;
|
||||
$$->v = $4;
|
||||
}
|
||||
|
||||
TABLE_NAME: NAME
|
||||
FIELD_NAME: NAME
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
FIELD_VALUE:
|
||||
STRING_VALUE
|
||||
{
|
||||
$$ = malloc(sizeof(value));
|
||||
$$->svalue = $1;
|
||||
}
|
||||
|
|
||||
INT_VALUE
|
||||
{
|
||||
$$ = malloc(sizeof(value));
|
||||
$$->ivalue = $1;
|
||||
}
|
||||
|
||||
%%
|
||||
void *yy_scan_string(char *, void *);
|
||||
void yy_delete_buffer(void *, void *);
|
||||
|
||||
void
|
||||
close_query (query *q) {
|
||||
free(q->w->column_name);
|
||||
free(q->w->v->svalue);
|
||||
free(q->w->v);
|
||||
free(q->w);
|
||||
|
||||
free(q->f->table);
|
||||
free(q->f);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
/* yydebug = 1; */
|
||||
void *scanner;
|
||||
yylex_init(&scanner);
|
||||
query q;
|
||||
void *buffer = yy_scan_string("select from t where foo = '5' ;", scanner);
|
||||
yyparse (&q, scanner);
|
||||
yy_delete_buffer(buffer, scanner);
|
||||
printf("table name: %s\n", q.f->table);
|
||||
printf("where column: %s, value: %s\n", q.w->column_name, q.w->v->svalue);
|
||||
yylex_destroy(scanner);
|
||||
close_query(&q);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int yyerror(query *q, void *s, char *err) {
|
||||
fprintf(stderr, "error: %s\n", err);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
typedef struct {
|
||||
char *table;
|
||||
} from;
|
||||
|
||||
typedef enum {
|
||||
OP_EQUAL
|
||||
} operation_t;
|
||||
|
||||
typedef union {
|
||||
int ivalue;
|
||||
char *svalue;
|
||||
} value;
|
||||
|
||||
typedef struct {
|
||||
char *column_name;
|
||||
operation_t op;
|
||||
value *v;
|
||||
} where;
|
||||
|
||||
typedef struct {
|
||||
from *f;
|
||||
where *w;
|
||||
char *error;
|
||||
} query;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,86 @@
|
|||
/* A Bison parser, made by GNU Bison 2.5. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
SELECT = 258,
|
||||
FROM = 259,
|
||||
WHERE = 260,
|
||||
EQUAL = 261,
|
||||
NAME = 262,
|
||||
STRING_VALUE = 263,
|
||||
INT_VALUE = 264
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define SELECT 258
|
||||
#define FROM 259
|
||||
#define WHERE 260
|
||||
#define EQUAL 261
|
||||
#define NAME 262
|
||||
#define STRING_VALUE 263
|
||||
#define INT_VALUE 264
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
{
|
||||
|
||||
/* Line 2068 of yacc.c */
|
||||
#line 6 "query.yacc"
|
||||
|
||||
char *string;
|
||||
int i;
|
||||
from *f;
|
||||
where *w;
|
||||
value *v;
|
||||
|
||||
|
||||
|
||||
/* Line 2068 of yacc.c */
|
||||
#line 78 "y.tab.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue