|
@@ -4,6 +4,7 @@
|
|
#include <string.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <cjson/cJSON.h>
|
|
#include <cjson/cJSON.h>
|
|
|
|
+#include <signal.h>
|
|
|
|
|
|
|
|
|
|
extern int yylex();
|
|
extern int yylex();
|
|
@@ -17,6 +18,29 @@ void yyerror(const char* s);
|
|
|
|
|
|
char* catstr(char* s1, char* s2);
|
|
char* catstr(char* s1, char* s2);
|
|
cJSON* jroot;
|
|
cJSON* jroot;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+#define SIMPLE_OP_NODE(res, type, left, right) \
|
|
|
|
+ fprintf(stderr, "SIMPLE_OP_NODE type: %s %s %s\n", (type), cJSON_Print(left), cJSON_Print(right)); \
|
|
|
|
+ cJSON* node = cJSON_CreateObject(); \
|
|
|
|
+ cJSON_AddStringToObject(node, "type", type); \
|
|
|
|
+ cJSON_AddItemToObject(node, "left", left); \
|
|
|
|
+ cJSON_AddItemToObject(node, "right", right); \
|
|
|
|
+ res = node;
|
|
|
|
+
|
|
|
|
+#define SIMPLE_OP_NODE_ONLY_LEFT(res, type, left) \
|
|
|
|
+ fprintf(stderr, "SIMPLE_OP_NODE_ONLY_LEFT type: %s %s %s\n", (type), cJSON_Print(left)); \
|
|
|
|
+ cJSON* node = cJSON_CreateObject(); \
|
|
|
|
+ cJSON_AddStringToObject(node, "type", type); \
|
|
|
|
+ cJSON_AddItemToObject(node, "left", left); \
|
|
|
|
+ res = node;
|
|
|
|
+
|
|
|
|
+#define SIMPLE_TYPE_VALUE_OBJECT(res, type_name, json_type_name, value) \
|
|
|
|
+ cJSON* node = cJSON_CreateObject(); \
|
|
|
|
+ cJSON_AddStringToObject(node, "type", #type_name); \
|
|
|
|
+ cJSON_Add##json_type_name##ToObject(node, "value", value); \
|
|
|
|
+ res = node;
|
|
%}
|
|
%}
|
|
|
|
|
|
%union {
|
|
%union {
|
|
@@ -30,8 +54,8 @@ cJSON* jroot;
|
|
%token IDENTIFIER
|
|
%token IDENTIFIER
|
|
|
|
|
|
%token SELECT FROM WHERE INSERT INTO VALUES DELETE UPDATE SET JOIN CREATE TABLE
|
|
%token SELECT FROM WHERE INSERT INTO VALUES DELETE UPDATE SET JOIN CREATE TABLE
|
|
-%token AS
|
|
|
|
-%token AND OR NOT
|
|
|
|
|
|
+%token AS ON
|
|
|
|
+%token AND OR NOT IN
|
|
%token INT_V FLOAT_V STRING_V // 作为 value 出现的
|
|
%token INT_V FLOAT_V STRING_V // 作为 value 出现的
|
|
%token INT_T FLOAT_T STRING_T // 作为 字面量 type 出现的情况
|
|
%token INT_T FLOAT_T STRING_T // 作为 字面量 type 出现的情况
|
|
|
|
|
|
@@ -42,13 +66,23 @@ cJSON* jroot;
|
|
|
|
|
|
%type <iv> INT_V
|
|
%type <iv> INT_V
|
|
%type <fv> FLOAT_V
|
|
%type <fv> FLOAT_V
|
|
-%type <sv> STRING_V
|
|
|
|
-%type <sv> IDENTIFIER data_type PRIMARY_KEY col_options bin_compare_op bin_logical_op unary_compare_op
|
|
|
|
|
|
+%type <sv> STRING_V NOT
|
|
|
|
+%type <sv> IDENTIFIER data_type PRIMARY_KEY col_options bin_cmp_op bin_logical_op unary_compare_op bin_contains_op
|
|
%type <jv> create_definition create_col_list create_table_stmt data_value
|
|
%type <jv> create_definition create_col_list create_table_stmt data_value
|
|
%type <jv> insert_stmt insert_list
|
|
%type <jv> insert_stmt insert_list
|
|
%type <jv> update_stmt update_list single_assign_item
|
|
%type <jv> update_stmt update_list single_assign_item
|
|
-%type <jv> where_condition_item where_conditions identifier identifier_or_const_value the_whole_where_smt
|
|
|
|
|
|
+%type <jv> where_condition_item where_conditions identifier identifier_or_const_value the_whole_where_smt
|
|
%type <jv> delete_stmt select_stmt select_item select_items
|
|
%type <jv> delete_stmt select_stmt select_item select_items
|
|
|
|
+%type <jv> data_value_list identifier_or_const_value_or_const_value_list
|
|
|
|
+%type <jv> search_expr compare_expr single_expr expr where_expr logical_expr negative_expr
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// %left OR
|
|
|
|
+// %left AND
|
|
|
|
+// %right NOT
|
|
|
|
+// %nonassoc '=' '>' '<'
|
|
|
|
+// %left '+' '-'
|
|
|
|
+// %left '*' '/'
|
|
|
|
|
|
%start statement
|
|
%start statement
|
|
|
|
|
|
@@ -102,7 +136,7 @@ create_col_list: create_definition {
|
|
;
|
|
;
|
|
|
|
|
|
create_definition: IDENTIFIER data_type col_options {
|
|
create_definition: IDENTIFIER data_type col_options {
|
|
- sprintf(stderr, "得列 %s %s with options %s: %d\n", $1, $2, $3, strlen($3));
|
|
|
|
|
|
+ // fprintf(stderr, "得列 %s %s with options %s: %d\n", $1, $2, $3, strlen($3));
|
|
|
|
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(node, "type", "create_column");
|
|
cJSON_AddStringToObject(node, "type", "create_column");
|
|
@@ -151,27 +185,12 @@ insert_list: data_value {
|
|
// printf("迭代\n %s", cJSON_Print($$));
|
|
// printf("迭代\n %s", cJSON_Print($$));
|
|
}
|
|
}
|
|
;
|
|
;
|
|
-data_value: INT_V {
|
|
|
|
- cJSON* node = cJSON_CreateObject();
|
|
|
|
- cJSON_AddStringToObject(node, "type", "int");
|
|
|
|
- cJSON_AddNumberToObject(node, "value", $1);
|
|
|
|
- $$=node;
|
|
|
|
- }
|
|
|
|
- | FLOAT_V {
|
|
|
|
- cJSON* node = cJSON_CreateObject();
|
|
|
|
- cJSON_AddStringToObject(node, "type", "float");
|
|
|
|
- cJSON_AddNumberToObject(node, "value", $1);
|
|
|
|
- $$=node;
|
|
|
|
- }
|
|
|
|
- | STRING_V {
|
|
|
|
- cJSON* node = cJSON_CreateObject();
|
|
|
|
- cJSON_AddStringToObject(node, "type", "string");
|
|
|
|
- cJSON_AddStringToObject(node, "value", $1);
|
|
|
|
- $$=node;
|
|
|
|
- }
|
|
|
|
|
|
+data_value: INT_V {SIMPLE_TYPE_VALUE_OBJECT($$, int, Number, $1);}
|
|
|
|
+ | FLOAT_V {SIMPLE_TYPE_VALUE_OBJECT($$, float, Number, $1);}
|
|
|
|
+ | STRING_V {SIMPLE_TYPE_VALUE_OBJECT($$, string, String, $1);}
|
|
;
|
|
;
|
|
|
|
|
|
-update_stmt: UPDATE IDENTIFIER SET update_list WHERE where_conditions NEWLINE {
|
|
|
|
|
|
+update_stmt: UPDATE IDENTIFIER SET update_list WHERE where_expr NEWLINE {
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(node, "type", "update");
|
|
cJSON_AddStringToObject(node, "type", "update");
|
|
cJSON_AddStringToObject(node, "table_name", $2);
|
|
cJSON_AddStringToObject(node, "table_name", $2);
|
|
@@ -201,7 +220,68 @@ single_assign_item: identifier '=' identifier_or_const_value {
|
|
;
|
|
;
|
|
|
|
|
|
the_whole_where_smt: {$$=cJSON_CreateObject();}
|
|
the_whole_where_smt: {$$=cJSON_CreateObject();}
|
|
- | WHERE where_conditions {$$=$2;};
|
|
|
|
|
|
+ | WHERE where_expr {$$=$2;}
|
|
|
|
+;
|
|
|
|
+
|
|
|
|
+// where 后的条件跟 select 中的有本质区别
|
|
|
|
+// select 中的只是常量或者字段名, 而 where 中的是表达式
|
|
|
|
+
|
|
|
|
+single_expr: identifier {$$=$1;}
|
|
|
|
+ | IDENTIFIER '.' IDENTIFIER {
|
|
|
|
+ cJSON* node = cJSON_CreateObject();
|
|
|
|
+ cJSON_AddStringToObject(node, "type", "table_field");
|
|
|
|
+ cJSON_AddStringToObject(node, "table", $1);
|
|
|
|
+ cJSON_AddStringToObject(node, "field", $3);
|
|
|
|
+ $$=node;
|
|
|
|
+ }
|
|
|
|
+ | data_value {$$=$1;}
|
|
|
|
+ | '(' single_expr ')' {$$=$2;}
|
|
|
|
+;
|
|
|
|
+where_expr: logical_expr {$$=$1;};
|
|
|
|
+;
|
|
|
|
+
|
|
|
|
+compare_expr: compare_expr bin_cmp_op compare_expr {SIMPLE_OP_NODE($$, $2, $1, $3);}
|
|
|
|
+ | single_expr {$$=$1;}
|
|
|
|
+
|
|
|
|
+;
|
|
|
|
+negative_expr: NOT negative_expr {SIMPLE_OP_NODE_ONLY_LEFT($$, "非", $2);}
|
|
|
|
+ | compare_expr {$$=$1;}
|
|
|
|
+;
|
|
|
|
+logical_expr: negative_expr bin_logical_op negative_expr {SIMPLE_OP_NODE($$, $2, $1, $3);}
|
|
|
|
+ | single_expr {$$=$1;}
|
|
|
|
+;
|
|
|
|
+
|
|
|
|
+// expr: compare_expr
|
|
|
|
+// | negative_expr
|
|
|
|
+// | logical_expr
|
|
|
|
+// ;
|
|
|
|
+
|
|
|
|
+// compare_expr: expr bin_cmp_op single_expr
|
|
|
|
+
|
|
|
|
+// expr: expr bin_cmp_op expr {SIMPLE_OP_NODE($$, $2, $1, $3)}
|
|
|
|
+// | expr bin_cmp_op '(' expr ')' {SIMPLE_OP_NODE($$, $2, $1, $4)}
|
|
|
|
+// // | '(' expr ')' {$$=$2;}
|
|
|
|
+// // | NOT expr {SIMPLE_OP_NODE_ONLY_LEFT($$, "非", $2);
|
|
|
|
+// // fprintf(stderr, "非asd %s\n", cJSON_Print($2));
|
|
|
|
+// // }
|
|
|
|
+// ;
|
|
|
|
+// // expr: expr bin_logical_op expr {SIMPLE_OP_NODE($$, $2, $1, $3)}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// expr_list: expr{
|
|
|
|
+// cJSON* node = cJSON_CreateArray();
|
|
|
|
+// cJSON_AddItemToArray(node, $1);
|
|
|
|
+// $$=node;
|
|
|
|
+// }
|
|
|
|
+// | expr_list ',' expr {
|
|
|
|
+// fprintf(stderr, "迭代 expr_list\n %s", cJSON_Print($1));
|
|
|
|
+// cJSON_AddItemToArray($1, $3);
|
|
|
|
+// $$=$1;
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+// expr: expr bin_contains_op '(' expr_list ')' {SIMPLE_OP_NODE($$, $2, $1, $4)}
|
|
|
|
+// | expr bin_contains_op '(' select_stmt ')' {SIMPLE_OP_NODE($$, $2, $1, $4)}
|
|
|
|
+
|
|
|
|
|
|
where_conditions: where_condition_item {
|
|
where_conditions: where_condition_item {
|
|
$$=$1;
|
|
$$=$1;
|
|
@@ -218,6 +298,12 @@ where_conditions: where_condition_item {
|
|
cJSON_AddItemToObject(node, "right", $3);
|
|
cJSON_AddItemToObject(node, "right", $3);
|
|
$$=node;
|
|
$$=node;
|
|
}
|
|
}
|
|
|
|
+ | unary_compare_op where_condition_item {
|
|
|
|
+ cJSON* node = cJSON_CreateObject();
|
|
|
|
+ cJSON_AddStringToObject(node, "type", $1);
|
|
|
|
+ cJSON_AddItemToObject(node, "right", $2);
|
|
|
|
+ $$=node;
|
|
|
|
+ }
|
|
| where_conditions bin_logical_op '(' where_conditions ')' {
|
|
| where_conditions bin_logical_op '(' where_conditions ')' {
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(node, "type", $2);
|
|
cJSON_AddStringToObject(node, "type", $2);
|
|
@@ -226,13 +312,7 @@ where_conditions: where_condition_item {
|
|
cJSON_AddItemToObject(node, "right", $4);
|
|
cJSON_AddItemToObject(node, "right", $4);
|
|
$$=node;
|
|
$$=node;
|
|
}
|
|
}
|
|
- | unary_compare_op where_condition_item {
|
|
|
|
- cJSON* node = cJSON_CreateObject();
|
|
|
|
- cJSON_AddStringToObject(node, "type", $1);
|
|
|
|
- cJSON_AddItemToObject(node, "right", $2);
|
|
|
|
- $$=node;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+
|
|
;
|
|
;
|
|
|
|
|
|
identifier: IDENTIFIER {
|
|
identifier: IDENTIFIER {
|
|
@@ -243,22 +323,44 @@ identifier: IDENTIFIER {
|
|
}
|
|
}
|
|
identifier_or_const_value: identifier {$$=$1;}
|
|
identifier_or_const_value: identifier {$$=$1;}
|
|
| data_value {$$=$1;}
|
|
| data_value {$$=$1;}
|
|
|
|
+;
|
|
|
|
+data_value_list: data_value {
|
|
|
|
+ cJSON* node = cJSON_CreateArray();
|
|
|
|
+ cJSON_AddItemToArray(node, $1);
|
|
|
|
+ $$=node;
|
|
|
|
+ }
|
|
|
|
+ | data_value_list ',' data_value {
|
|
|
|
+ cJSON_AddItemToArray($1, $3);
|
|
|
|
+ $$=$1;
|
|
|
|
+ }
|
|
|
|
+;
|
|
|
|
+identifier_or_const_value_or_const_value_list: identifier_or_const_value{$$=$1;}
|
|
|
|
+ | data_value_list {$$=$1;}
|
|
|
|
|
|
-where_condition_item: identifier_or_const_value bin_compare_op identifier_or_const_value {
|
|
|
|
|
|
+where_condition_item: identifier_or_const_value bin_cmp_op identifier_or_const_value {
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(node, "type", $2);
|
|
cJSON_AddStringToObject(node, "type", $2);
|
|
cJSON_AddItemToObject(node, "left", $1);
|
|
cJSON_AddItemToObject(node, "left", $1);
|
|
cJSON_AddItemToObject(node, "right", $3);
|
|
cJSON_AddItemToObject(node, "right", $3);
|
|
$$=node;
|
|
$$=node;
|
|
- };
|
|
|
|
|
|
+ }
|
|
|
|
+ | identifier_or_const_value bin_contains_op '(' data_value_list ')' {
|
|
|
|
+ cJSON* node = cJSON_CreateObject();
|
|
|
|
+ cJSON_AddStringToObject(node, "type", $2);
|
|
|
|
+ cJSON_AddItemToObject(node, "left", $1);
|
|
|
|
+ cJSON_AddItemToObject(node, "right", $4);
|
|
|
|
+ $$=node;
|
|
|
|
+ }
|
|
|
|
+;
|
|
|
|
|
|
|
|
|
|
-bin_compare_op: '=' {$$ = "相等";}
|
|
|
|
|
|
+bin_cmp_op: '=' {$$ = "相等";}
|
|
| '>' {$$ = "大于";}
|
|
| '>' {$$ = "大于";}
|
|
| '<' {$$ = "小于";}
|
|
| '<' {$$ = "小于";}
|
|
| ">=" {$$ = "大等";}
|
|
| ">=" {$$ = "大等";}
|
|
| "<=" {$$ = "小等";}
|
|
| "<=" {$$ = "小等";}
|
|
| "!=" {$$ = "不等";}
|
|
| "!=" {$$ = "不等";}
|
|
|
|
+ | IN {$$ = "包含于";}
|
|
;
|
|
;
|
|
|
|
|
|
unary_compare_op: NOT {$$ = "非";};
|
|
unary_compare_op: NOT {$$ = "非";};
|
|
@@ -266,6 +368,9 @@ unary_compare_op: NOT {$$ = "非";};
|
|
bin_logical_op: AND {$$ = "且";}
|
|
bin_logical_op: AND {$$ = "且";}
|
|
| OR {$$ = "或";}
|
|
| OR {$$ = "或";}
|
|
|
|
|
|
|
|
+bin_contains_op: IN {$$ = "包含于";}
|
|
|
|
+ | NOT IN {$$ = "不包含于";}
|
|
|
|
+
|
|
delete_stmt: DELETE FROM IDENTIFIER the_whole_where_smt NEWLINE {
|
|
delete_stmt: DELETE FROM IDENTIFIER the_whole_where_smt NEWLINE {
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON* node = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(node, "type", "delete");
|
|
cJSON_AddStringToObject(node, "type", "delete");
|
|
@@ -331,7 +436,7 @@ int main(int ac, char** av) {
|
|
}
|
|
}
|
|
|
|
|
|
void yyerror(const char *s) {
|
|
void yyerror(const char *s) {
|
|
- printf("error: %s at %s\n", s, yytext);
|
|
|
|
|
|
+ fprintf(stderr, "error: %s at %s\n", s, yytext);
|
|
exit(1);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|