%{ /** * bison_parser.y * defines bison_parser.h * outputs bison_parser.c * * Grammar File Spec: http://dinosaur.compilertools.net/bison/bison_6.html * */ /********************************* ** Section 1: C Declarations *********************************/ #include "Statement.h" #include "List.h" #include "bison_parser.h" #include "flex_lexer.h" #include int yyerror(Statement **expression, yyscan_t scanner, const char *msg) { fprintf(stderr, "[Error] SQL Parser: %s\n", msg); return 0; } %} /********************************* ** Section 2: Bison Parser Declarations *********************************/ // Define the names of the created files %output "bison_parser.cpp" %defines "bison_parser.h" // Tell bison to create a reentrant parser %define api.pure full // Specify code that is included in the generated .h and .c files %code requires { #ifndef YYtypeDEF_YY_SCANNER_T #define YYtypeDEF_YY_SCANNER_T typedef void* yyscan_t; #endif } // Define additional parameters for yylex (http://www.gnu.org/software/bison/manual/html_node/Pure-Calling.html) %lex-param { yyscan_t scanner } // Define additional parameters for yyparse %parse-param { Statement **statement } %parse-param { yyscan_t scanner } %define api.token.prefix {SQL_} /********************************* ** Define all data-types (http://www.gnu.org/software/bison/manual/html_node/Union-Decl.html) *********************************/ %union { float number; uint uintnum; char* sval; Statement* statement; SelectStatement* select_statement; TableRef* table; Expr* expr; List* slist; List* explist; List* tbllist; } /********************************* ** Token Definition *********************************/ %token SELECT FROM WHERE GROUP BY HAVING %token JOIN ON INNER OUTER LEFT RIGHT CROSS USING NATURAL %token CREATE TABLE DATABASE INDEX %token AS NOT AND OR NULL %token NAME STRING COMPARISON %token FLOAT %token EQUALS NOTEQUALS LESS GREATER LESSEQ GREATEREQ /********************************* ** Non-Terminal types (http://www.gnu.org/software/bison/manual/html_node/Type-Decl.html) *********************************/ %type statement %type select_statement %type table_name %type from_clause table_ref table_ref_atomic %type expr column_name scalar_exp literal %type comparison_predicate predicate search_condition where_clause %type expr_list group_clause select_list %type table_ref_commalist %% /********************************* ** Section 3: Grammar Definition *********************************/ // Defines our general input. // TODO: Support list of statements input: statement opt_semicolon { *statement = $1; } ; // All types of statements // Atm: only select statements (future: insert, delete, etc...) statement: select_statement { $$ = $1; } | /* empty */ { $$ = NULL; } ; /****************************** ** Select Statements ******************************/ // TODO: join // TODO: limit // TODO: order by select_statement: SELECT select_list from_clause where_clause group_clause { SelectStatement* s = new SelectStatement(); s->select_list = $2; s->from_table = $3; s->where_clause = $4; s->group_by = $5; $$ = s; } ; select_list: '*' { $$ = new List(new Expr(eExprStar)); } | expr_list; from_clause: FROM table_ref { $$ = $2; } ; where_clause: WHERE search_condition { $$ = $2; } | /* empty */ { $$ = NULL; } ; // TODO: having group_clause: GROUP BY expr_list { $$ = $3; } | /* empty */ { $$ = NULL; } ; // TODO: multiple predicates search_condition: predicate ; predicate: comparison_predicate ; comparison_predicate: 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); } ; // TODO: Expression can also be scalar_exp expr: column_name | NAME '(' expr ')' { $$ = makeFunctionRef($1, $3); } ; // TODO: Scalar expressions can also be arithmetic scalar_exp: column_name | literal ; column_name: NAME { $$ = makeColumnRef($1); } ; literal: STRING { $$ = makeStringLiteral($1); } | FLOAT { $$ = makeFloatLiteral($1); } ; opt_semicolon: ';' | /* empty */ ; expr_list: expr { $$ = new List($1); } | expr_list ',' expr { $1->push_back($3); $$ = $1; } ; /****************************** ** Table ******************************/ table_ref: table_ref_atomic | table_ref_atomic ',' table_ref_commalist { $3->push_back($1); auto tbl = new TableRef(eTableCrossProduct); tbl->list = $3; $$ = tbl; } ; table_ref_atomic: table_name { auto tbl = new TableRef(eTableName); tbl->name = $1; $$ = tbl; } | '(' select_statement ')' { auto tbl = new TableRef(eTableSelect); tbl->stmt = $2; $$ = tbl; } ; table_ref_commalist: table_ref_atomic { $$ = new List($1); } | table_ref_commalist ',' table_ref_atomic { $1->push_back($3); $$ = $1; } ; table_name: NAME | NAME '.' NAME ; %% /********************************* ** Section 4: Additional C code *********************************/ /* empty */