From 592d427f7a303ffa3eee86784dddac2db7b0f38c Mon Sep 17 00:00:00 2001 From: Pedro Date: Wed, 8 Oct 2014 17:55:07 -0700 Subject: [PATCH] refactored grammar. now includes where clause --- src/build_and_run.sh | 4 +- src/lex_lexer.l | 20 ++++++- src/lex_parser.y | 138 ++++++++++++++++++++++++++++++------------- src/lib/Expression.h | 3 +- src/sql_tests.cpp | 2 +- 5 files changed, 122 insertions(+), 45 deletions(-) diff --git a/src/build_and_run.sh b/src/build_and_run.sh index 6546901..2ea2e9a 100644 --- a/src/build_and_run.sh +++ b/src/build_and_run.sh @@ -4,5 +4,5 @@ make clean make tests ./bin/tests -make execution -./bin/sql_execution "SELECT col1, col2 FROM table GROUP BY col1;" \ No newline at end of file +# make execution +# ./bin/sql_execution "SELECT col1, col2 FROM table GROUP BY col1;" \ No newline at end of file diff --git a/src/lex_lexer.l b/src/lex_lexer.l index ced2c3b..766a3e9 100644 --- a/src/lex_lexer.l +++ b/src/lex_lexer.l @@ -31,7 +31,19 @@ using namespace std; SELECT TOK(SELECT) FROM TOK(FROM) GROUP TOK(GROUP) -BY TOK(BY) +BY TOK(BY) +WHERE TOK(WHERE) +NOT TOK(NOT) +AND TOK(AND) +OR TOK(OR) + + +"=" | +"<>" | +"<" | +">" | +"<=" | +">=" TOK(COMPARISON) [-+*/(),.;] TOK(yytext[0]) @@ -40,6 +52,12 @@ BY TOK(BY) "."[0-9]* TOK(INTNUM) [A-Za-z][A-Za-z0-9_]* { + yylval->sval = strdup(yytext); + return NAME; +} + + +'[^'\n]*' { yylval->sval = strdup(yytext); return STRING; } diff --git a/src/lex_parser.y b/src/lex_parser.y index 67b00e3..edd8e0d 100644 --- a/src/lex_parser.y +++ b/src/lex_parser.y @@ -48,73 +48,131 @@ typedef void* yyscan_t; List* explist; } -%token SELECT FROM GROUP BY INTNUM -%token STRING +%token SELECT FROM GROUP BY WHERE NOT AND OR +%token INTNUM COMPARISON STRING +%token NAME %type statement %type select_statement -%type from_clause -%type string_list -%type expr_list group_clause +%type column_name table_name +%type
from_clause table_exp %type expr; +%type table_ref_commalist +%type expr_list group_clause %% input: - statement opt_semicolon { *statement = $1; }; - - -opt_semicolon: - ';' | ; - + statement opt_semicolon { *statement = $1; } + ; statement: - select_statement { $$ = $1; } - | { $$ = NULL; }; + select_statement { $$ = $1; } + | /* empty */ { $$ = NULL; } + ; + + select_statement: - SELECT expr_list from_clause group_clause + SELECT expr_list from_clause where_clause group_clause { SelectStatement* s = new SelectStatement(); s->_select_list = $2; s->_from_table = $3; - s->_group_by = $4; + s->_group_by = $5; $$ = s; - }; + } + ; -expr_list: - expr { $$ = new List($1); } - | expr_list ',' expr { $1->push_back($3); $$ = $1; }; + +from_clause: + FROM table_exp { $$ = $2; } + ; + +where_clause: + WHERE search_condition + | /* empty */ + ; + +group_clause: + GROUP BY expr_list { $$ = $3; } + | /* empty */ { $$ = NULL; } + ; + + + +table_exp: + table_ref_commalist { + TableRef* t = new TableRef(eTableName); + t->_table_names = $1; + $$ = t; + } + | '(' select_statement ')' { + TableRef* t = new TableRef(eTableSelect); + t->_stmt = $2; + $$ = t; + } + ; + + +search_condition: + predicate + ; + +predicate: + comparison_predicate + ; + +comparison_predicate: + scalar_exp COMPARISON scalar_exp + ; expr: - STRING { $$ = new Expression($1); } - | STRING '(' STRING ')' { $$ = new Expression($3, $1); }; + column_name { $$ = new Expression($1); } + | NAME '(' column_name ')' { $$ = new Expression($3, $1); } + ; -from_clause: - FROM string_list - { - TableRef* t = new TableRef(eTableName); - t->_table_names = $2; - $$ = t; - } - | FROM '(' select_statement ')' - { - TableRef* t = new TableRef(eTableSelect); - t->_stmt = $3; - $$ = t; - }; + +/* Lists */ +expr_list: + expr { $$ = new List($1); } + | expr_list ',' expr { $1->push_back($3); $$ = $1; } + ; -group_clause: - GROUP BY expr_list { $$ = $3; } - | { $$ = NULL; }; +// TODO: add table_ref to include names and select queries +table_ref_commalist: + table_name { $$ = new List($1); } + | table_ref_commalist ',' table_name { $1->push_back($3); $$ = $1; } + ; +/* / Lists */ -string_list: - STRING { $$ = new List($1); } - | string_list ',' STRING { $1->push_back($3); $$ = $1; } +column_name: + NAME + ; + +table_name: + NAME + | NAME '.' NAME + ; + +literal: + STRING + | INTNUM + ; + +scalar_exp: + column_name + | literal + ; + +opt_semicolon: + ';' + | /* empty */ + ; %% \ No newline at end of file diff --git a/src/lib/Expression.h b/src/lib/Expression.h index 690e1c2..66440c5 100644 --- a/src/lib/Expression.h +++ b/src/lib/Expression.h @@ -1,11 +1,12 @@ #ifndef __EXPRESSION_H__ #define __EXPRESSION_H__ +#include class Expression { public: - Expression(char* name) : name(name) {}; + Expression(char* name) : name(name), func_name(NULL) {}; Expression(char* name, char* func_name) : name(name), func_name(func_name) {}; char* name; diff --git a/src/sql_tests.cpp b/src/sql_tests.cpp index 68a71d0..e82e818 100644 --- a/src/sql_tests.cpp +++ b/src/sql_tests.cpp @@ -17,7 +17,7 @@ void SelectTest1() { printf("Test: SelectTest1... "); fflush(stdout); - const char* sql = "SELECT age, name, address from table;"; + const char* sql = "SELECT age, name, address from table WHERE age > 12.5;"; Statement* stmt = SQLParser::parseSQL(sql); ASSERT(stmt != NULL); ASSERT(stmt->_type == eSelect);