HyriseSQLParser/src/bison/bison_parser.y

254 lines
5.2 KiB
Plaintext
Raw Normal View History

2014-10-09 01:30:22 +02:00
%{
/**
* bison_parser.y
* defines bison_parser.h
* outputs bison_parser.c
*
* Grammar File Spec: http://dinosaur.compilertools.net/bison/bison_6.html
*
2014-10-09 01:30:22 +02:00
*/
/*********************************
** Section 1: C Declarations
*********************************/
2014-10-09 01:30:22 +02:00
#include "Statement.h"
#include "List.h"
2014-10-16 15:35:38 +02:00
#include "bison_parser.h"
#include "flex_lexer.h"
2014-10-09 01:30:22 +02:00
#include <stdio.h>
2014-10-09 01:30:22 +02:00
int yyerror(Statement **expression, yyscan_t scanner, const char *msg) {
fprintf(stderr, "[Error] SQL Parser: %s\n", msg);
return 0;
2014-10-09 01:30:22 +02:00
}
%}
/*********************************
** Section 2: Bison Parser Declarations
*********************************/
// Define the names of the created files
%output "bison_parser.c"
%defines "bison_parser.h"
// Tell bison to create a reentrant parser
%define api.pure full
2014-10-09 01:30:22 +02:00
// Specify code that is included in the generated .h and .c files
2014-10-09 01:30:22 +02:00
%code requires {
2014-10-20 22:33:36 +02:00
#ifndef YYtypeDEF_YY_SCANNER_T
#define YYtypeDEF_YY_SCANNER_T
2014-10-09 01:30:22 +02:00
typedef void* yyscan_t;
#endif
}
// Define additional parameters for yylex (http://www.gnu.org/software/bison/manual/html_node/Pure-Calling.html)
2014-10-09 01:30:22 +02:00
%lex-param { yyscan_t scanner }
// Define additional parameters for yyparse
2014-10-09 01:30:22 +02:00
%parse-param { Statement **statement }
%parse-param { yyscan_t scanner }
2014-10-22 16:30:45 +02:00
%define api.token.prefix {SQL_}
/*********************************
** Define all data-types (http://www.gnu.org/software/bison/manual/html_node/Union-Decl.html)
*********************************/
2014-10-09 01:30:22 +02:00
%union {
2014-10-09 04:46:25 +02:00
float number;
uint uintnum;
2014-10-09 01:30:22 +02:00
char* sval;
Statement* statement;
SelectStatement* select_statement;
TableRef* table;
2014-10-09 04:09:47 +02:00
Expr* expr;
2014-10-09 01:30:22 +02:00
List<char*>* slist;
2014-10-09 04:09:47 +02:00
List<Expr*>* explist;
2014-10-09 01:30:22 +02:00
}
2014-10-09 04:46:25 +02:00
/*********************************
** Token Definition
*********************************/
%token SELECT FROM GROUP BY WHERE NOT AND OR
2014-10-09 04:46:25 +02:00
%token <sval> NAME STRING COMPARISON
%token <number> FLOAT
%token <uintnum> EQUALS NOTEQUALS LESS GREATER LESSEQ GREATEREQ
/*********************************
** Non-Terminal types (http://www.gnu.org/software/bison/manual/html_node/Type-Decl.html)
*********************************/
2014-10-09 01:30:22 +02:00
%type <statement> statement
%type <select_statement> select_statement
2014-10-09 04:46:25 +02:00
%type <sval> table_name
%type <table> from_clause table_exp
2014-10-09 04:46:25 +02:00
%type <expr> expr column_name scalar_exp literal
%type <expr> comparison_predicate predicate search_condition where_clause
%type <slist> table_ref_commalist
2014-10-22 17:18:43 +02:00
%type <explist> expr_list group_clause select_list
2014-10-09 01:30:22 +02:00
%%
/*********************************
** Section 3: Grammar Definition
*********************************/
2014-10-09 01:30:22 +02:00
// Defines our general input.
// TODO: Support list of statements
2014-10-20 22:33:36 +02:00
input:
statement opt_semicolon { *statement = $1; }
;
2014-10-09 01:30:22 +02:00
// All types of statements
// Atm: only select statements (future: insert, delete, etc...)
statement:
select_statement { $$ = $1; }
| /* empty */ { $$ = NULL; }
;
2014-10-09 01:30:22 +02:00
/******************************
** Select Statements
******************************/
2014-10-09 01:30:22 +02:00
// TODO: join
// TODO: limit
// TODO: order by
2014-10-09 01:30:22 +02:00
select_statement:
2014-10-22 17:18:43 +02:00
SELECT select_list from_clause where_clause group_clause
2014-10-20 22:33:36 +02:00
{
2014-10-09 01:30:22 +02:00
SelectStatement* s = new SelectStatement();
2014-10-20 22:33:36 +02:00
s->select_list = $2;
s->from_table = $3;
s->where_clause = $4;
s->group_by = $5;
2014-10-09 01:30:22 +02:00
$$ = s;
}
;
2014-10-09 01:30:22 +02:00
2014-10-22 17:18:43 +02:00
select_list:
'*' { $$ = new List<Expr*>(makeColumnRef("*")); }
| expr_list;
2014-10-09 01:30:22 +02:00
from_clause:
FROM table_exp { $$ = $2; }
;
2014-10-09 01:30:22 +02:00
where_clause:
2014-10-09 04:46:25 +02:00
WHERE search_condition { $$ = $2; }
| /* empty */ { $$ = NULL; }
;
// TODO: having
group_clause:
GROUP BY expr_list { $$ = $3; }
| /* empty */ { $$ = NULL; }
;
2014-10-09 01:30:22 +02:00
// TODO: comma_list with mixed table names and select statements
table_exp:
2014-10-20 22:33:36 +02:00
table_ref_commalist {
2014-10-09 01:30:22 +02:00
TableRef* t = new TableRef(eTableName);
2014-10-20 22:33:36 +02:00
t->table_names = $1;
2014-10-09 01:30:22 +02:00
$$ = t;
}
| '(' select_statement ')' {
2014-10-09 01:30:22 +02:00
TableRef* t = new TableRef(eTableSelect);
2014-10-20 22:33:36 +02:00
t->stmt = $2;
2014-10-09 01:30:22 +02:00
$$ = t;
}
;
2014-10-09 01:30:22 +02:00
// TODO: multiple predicates
search_condition:
predicate
;
predicate:
comparison_predicate
;
2014-10-09 01:30:22 +02:00
comparison_predicate:
2014-10-22 16:30:45 +02:00
scalar_exp EQUALS scalar_exp { $$ = makePredicate($1, SQL_EQUALS, $3); }
| scalar_exp NOTEQUALS scalar_exp { $$ = makePredicate($1, SQL_NOTEQUALS, $3); }
| scalar_exp LESS scalar_exp { $$ = makePredicate($1, SQL_LESS, $3); }
| scalar_exp GREATER scalar_exp { $$ = makePredicate($1, SQL_GREATER, $3); }
| scalar_exp LESSEQ scalar_exp { $$ = makePredicate($1, SQL_LESSEQ, $3); }
| scalar_exp GREATEREQ scalar_exp { $$ = makePredicate($1, SQL_GREATEREQ, $3); }
;
2014-10-09 01:30:22 +02:00
// TODO: Expression can also be scalar_exp
expr:
2014-10-09 04:46:25 +02:00
column_name
| NAME '(' expr ')' { $$ = makeFunctionRef($1, $3); }
;
// TODO: Scalar expressions can also be arithmetic
scalar_exp:
column_name
| literal
;
column_name:
2014-10-09 04:46:25 +02:00
NAME { $$ = makeColumnRef($1); }
;
table_name:
NAME
| NAME '.' NAME
;
literal:
2014-10-09 04:46:25 +02:00
STRING { $$ = makeStringLiteral($1); }
| FLOAT { $$ = makeFloatLiteral($1); }
;
opt_semicolon:
2014-10-20 22:33:36 +02:00
';'
| /* empty */
;
/******************************
** Lists
******************************/
expr_list:
expr { $$ = new List<Expr*>($1); }
| expr_list ',' expr { $1->push_back($3); $$ = $1; }
;
// TODO: add table_ref to include names and select queries
table_ref_commalist:
table_name { $$ = new List<char*>($1); }
| table_ref_commalist ',' table_name { $1->push_back($3); $$ = $1; }
;
2014-10-20 22:33:36 +02:00
%%
/*********************************
** Section 4: Additional C code
*********************************/
/* empty */