HyriseSQLParser/src/parser/bison_parser.y

379 lines
7.9 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"
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
using namespace hsql;
2014-11-04 00:02:40 +01:00
int yyerror(Statement **stmt, yyscan_t scanner, const char *msg) {
*stmt = new Statement(kStmtError);
(*stmt)->parser_msg = msg;
return 0;
2014-10-09 01:30:22 +02:00
}
%}
/*********************************
** Section 2: Bison Parser Declarations
*********************************/
// Define the names of the created files
2014-10-23 16:29:23 +02:00
%output "bison_parser.cpp"
%defines "bison_parser.h"
// Tell bison to create a reentrant parser
%define api.pure full
2014-10-09 01:30:22 +02:00
2014-10-31 18:24:47 +01:00
// Prefix the parser
%define api.prefix {hsql_}
%define api.token.prefix {SQL_}
// 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
2014-10-31 18:24:47 +01:00
#define YYSTYPE HSQL_STYPE
2014-10-09 01:30:22 +02:00
}
// 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
%parse-param { hsql::Statement **statement }
2014-10-09 01:30:22 +02:00
%parse-param { yyscan_t scanner }
/*********************************
** 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-27 13:54:16 +01:00
double fval;
int64_t ival;
2014-10-09 01:30:22 +02:00
char* sval;
2014-10-27 14:54:15 +01:00
uint uval;
2014-10-09 01:30:22 +02:00
hsql::Statement* statement;
hsql::SelectStatement* select_stmt;
hsql::JoinStatement* join_stmt;
hsql::TableRef* table;
hsql::Expr* expr;
hsql::OrderDescription* order;
hsql::OrderType order_type;
hsql::LimitDescription* limit;
hsql::List<char*>* slist;
hsql::List<hsql::Expr*>* explist;
hsql::List<hsql::TableRef*>* tbllist;
2014-10-09 01:30:22 +02:00
}
2014-10-09 04:46:25 +02:00
/*********************************
** Token Definition
*********************************/
2014-10-27 14:54:15 +01:00
%token SELECT FROM WHERE GROUP BY HAVING ORDER ASC DESC LIMIT
2014-10-23 11:41:44 +02:00
%token JOIN ON INNER OUTER LEFT RIGHT CROSS USING NATURAL
%token CREATE TABLE DATABASE INDEX
2014-10-24 16:10:38 +02:00
%token AS NOT AND OR NULL LIKE
2014-10-09 04:46:25 +02:00
%token <sval> NAME STRING COMPARISON
2014-10-27 13:54:16 +01:00
%token <fval> FLOAT
%token <ival> INT
2014-10-27 14:54:15 +01:00
%token <uval> EQUALS NOTEQUALS LESS GREATER LESSEQ GREATEREQ
/*********************************
** Non-Terminal types (http://www.gnu.org/software/bison/manual/html_node/Type-Decl.html)
*********************************/
2014-10-27 14:54:15 +01:00
%type <statement> statement
%type <select_stmt> select_statement
%type <join_stmt> join_statement
2014-10-27 14:54:15 +01:00
%type <sval> table_name
2014-11-03 23:57:42 +01:00
%type <table> from_clause table_ref table_ref_atomic table_ref_atomic_opt_paren
2014-10-27 14:54:15 +01:00
%type <expr> expr scalar_expr unary_expr binary_expr function_expr star_expr
%type <expr> column_name literal int_literal num_literal
2014-11-04 00:34:32 +01:00
%type <expr> comp_expr where_clause join_condition
2014-10-27 14:54:15 +01:00
%type <explist> expr_list group_clause select_list
%type <tbllist> table_ref_commalist
%type <order> order_by_clause
%type <limit> limit_clause
%type <order_type> order_type
2014-10-24 16:10:38 +02:00
/******************************
** Token Precedence and Associativity
** Precedence: lowest to highest
******************************/
%left OR
%left AND
%right NOT
%right '=' EQUALS NOTEQUALS
%nonassoc '<' '>' LESS GREATER LESSEQ GREATEREQ
%nonassoc NOTNULL
%nonassoc ISNULL
%nonassoc IS /* sets precedence for IS NULL, etc */
%left '+' '-'
%left '*' '/' '%'
%left '^'
/* Unary Operators */
%left '[' ']'
%left '(' ')'
%left '.'
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; }
| join_statement { $$ = $1; }
;
2014-10-09 01:30:22 +02:00
/******************************
** Join Statements
******************************/
join_statement:
2014-11-03 23:57:42 +01:00
table_ref_atomic_opt_paren JOIN table_ref_atomic_opt_paren ON join_condition
{
$$ = new JoinStatement();
2014-11-04 00:34:32 +01:00
$$->left = $1;
$$->right = $3;
$$->join_condition = $5;
$$->join_type = kJoinInner;
}
;
join_condition:
expr
;
/******************************
** Select Statements
******************************/
2014-10-09 01:30:22 +02:00
select_statement:
2014-10-27 14:54:15 +01:00
SELECT select_list from_clause where_clause group_clause order_by_clause limit_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-27 14:54:15 +01:00
s->order = $6;
s->limit = $7;
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:
2014-10-24 16:10:38 +02:00
expr_list
;
2014-10-22 17:18:43 +02:00
2014-10-09 01:30:22 +02:00
from_clause:
FROM table_ref { $$ = $2; }
;
2014-10-09 01:30:22 +02:00
where_clause:
2014-10-24 16:10:38 +02:00
WHERE expr { $$ = $2; }
2014-10-09 04:46:25 +02:00
| /* empty */ { $$ = NULL; }
;
// TODO: having
group_clause:
GROUP BY expr_list { $$ = $3; }
| /* empty */ { $$ = NULL; }
;
2014-10-09 01:30:22 +02:00
2014-10-27 14:54:15 +01:00
order_by_clause:
ORDER BY expr order_type { $$ = new OrderDescription($4, $3); }
| /* empty */ { $$ = NULL; }
order_type:
ASC { $$ = kOrderAsc; }
| DESC { $$ = kOrderDesc; }
| /* empty */ { $$ = kOrderAsc; }
limit_clause:
LIMIT int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; }
| /* empty */ { $$ = NULL; }
2014-10-24 16:10:38 +02:00
/******************************
** Expressions
******************************/
expr_list:
expr { $$ = new List<Expr*>($1); }
| expr_list ',' expr { $1->push_back($3); $$ = $1; }
;
2014-10-24 16:10:38 +02:00
expr:
'(' expr ')' { $$ = $2; }
| scalar_expr
| unary_expr
| binary_expr
| function_expr
;
2014-10-09 01:30:22 +02:00
2014-10-24 16:10:38 +02:00
scalar_expr:
column_name
| star_expr
| literal
;
2014-10-24 16:10:38 +02:00
unary_expr:
2014-10-31 18:05:08 +01:00
'-' expr { $$ = Expr::makeOpUnary(Expr::UMINUS, $2); }
| NOT expr { $$ = Expr::makeOpUnary(Expr::NOT, $2); }
;
2014-10-09 01:30:22 +02:00
2014-10-24 16:10:38 +02:00
binary_expr:
comp_expr
| expr '-' expr { $$ = Expr::makeOpBinary($1, '-', $3); }
| expr '+' expr { $$ = Expr::makeOpBinary($1, '+', $3); }
| expr '/' expr { $$ = Expr::makeOpBinary($1, '/', $3); }
| expr '*' expr { $$ = Expr::makeOpBinary($1, '*', $3); }
2014-10-31 18:05:08 +01:00
| expr AND expr { $$ = Expr::makeOpBinary($1, Expr::AND, $3); }
| expr OR expr { $$ = Expr::makeOpBinary($1, Expr::OR, $3); }
;
2014-10-24 16:10:38 +02:00
comp_expr:
expr EQUALS expr { $$ = Expr::makeOpBinary($1, '=', $3); }
2014-10-31 18:05:08 +01:00
| expr NOTEQUALS expr { $$ = Expr::makeOpBinary($1, Expr::NOT_EQUALS, $3); }
2014-10-24 16:10:38 +02:00
| expr LESS expr { $$ = Expr::makeOpBinary($1, '<', $3); }
| expr GREATER expr { $$ = Expr::makeOpBinary($1, '>', $3); }
2014-10-31 18:05:08 +01:00
| expr LESSEQ expr { $$ = Expr::makeOpBinary($1, Expr::LESS_EQ, $3); }
| expr GREATEREQ expr { $$ = Expr::makeOpBinary($1, Expr::GREATER_EQ, $3); }
2014-10-24 16:10:38 +02:00
;
function_expr:
2014-10-31 18:05:08 +01:00
NAME '(' expr ')' { $$ = Expr::makeFunctionRef($1, $3); }
;
column_name:
2014-10-31 18:05:08 +01:00
NAME { $$ = Expr::makeColumnRef($1); }
;
literal:
2014-10-27 13:54:16 +01:00
STRING { $$ = Expr::makeLiteral($1); }
2014-10-27 14:54:15 +01:00
| num_literal
;
num_literal:
FLOAT { $$ = Expr::makeLiteral($1); }
| int_literal
;
int_literal:
INT { $$ = Expr::makeLiteral($1); }
;
2014-10-24 16:10:38 +02:00
star_expr:
2014-10-27 11:23:31 +01:00
'*' { $$ = new Expr(kExprStar); }
;
/******************************
** Table
******************************/
table_ref:
table_ref_atomic
| table_ref_atomic ',' table_ref_commalist {
$3->push_back($1);
2014-10-27 11:23:31 +01:00
auto tbl = new TableRef(kTableCrossProduct);
tbl->list = $3;
$$ = tbl;
}
;
table_ref_atomic:
table_name {
2014-10-27 11:23:31 +01:00
auto tbl = new TableRef(kTableName);
tbl->name = $1;
$$ = tbl;
}
| '(' select_statement ')' {
2014-10-27 11:23:31 +01:00
auto tbl = new TableRef(kTableSelect);
2014-10-27 12:09:53 +01:00
tbl->select = $2;
$$ = tbl;
}
;
2014-11-03 23:57:42 +01:00
table_ref_commalist:
table_ref_atomic { $$ = new List<TableRef*>($1); }
| table_ref_commalist ',' table_ref_atomic { $1->push_back($3); $$ = $1; }
;
2014-11-03 23:57:42 +01:00
/* For join statements, where a select statement is allowed to be used without parenthesis */
table_ref_atomic_opt_paren:
table_ref_atomic
| select_statement {
auto tbl = new TableRef(kTableSelect);
tbl->select = $1;
$$ = tbl;
}
;
table_name:
NAME
| NAME '.' NAME
;
2014-10-24 16:10:38 +02:00
opt_semicolon:
';'
| /* empty */
;
2014-10-20 22:33:36 +02:00
%%
/*********************************
** Section 4: Additional C code
*********************************/
/* empty */