ソースを参照

完成 in list

myuan 2 年 前
コミット
c912f93214
3 ファイル変更48 行追加53 行削除
  1. 20 20
      run_test.py
  2. 2 1
      src/calc.l
  3. 26 32
      src/calc.y

+ 20 - 20
run_test.py

@@ -22,7 +22,8 @@ async def assert_sql(sql, target):
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
     )
-    stdout, stderr = await p.communicate()
+    stdout, stderr = await asyncio.wait_for(p.communicate(), timeout=5)
+
     if b"error" in stdout:
         print(stdout.decode("utf-8"))
         print(datetime.now(), "-" * 40)
@@ -36,6 +37,7 @@ async def assert_sql(sql, target):
     open("/tmp/temp/test.py", "wb").write(
         f'"{sql}"\n\n'.encode("utf-8")
         + orjson.dumps(output, option=orjson.OPT_INDENT_2)
+        + (b"\n\n" + stderr).replace(b"\n", b"\n# ")
     )
     assert (
         output == target
@@ -295,15 +297,15 @@ async def assert_sqls():
                 "type": "delete",
                 "table_name": "tb1",
                 "where": {
-                    "type": "",
+                    "type": "",
                     "left": {
-                        "type": "相等",
-                        "left": {"type": "identifier", "value": "c1"},
-                        "right": {"type": "int", "value": 1},
-                    },
-                    "right": {
-                        "type": "或",
+                        "type": "且",
                         "left": {
+                            "type": "相等",
+                            "left": {"type": "identifier", "value": "c1"},
+                            "right": {"type": "int", "value": 1},
+                        },
+                        "right": {
                             "type": "或",
                             "left": {
                                 "type": "相等",
@@ -316,11 +318,11 @@ async def assert_sqls():
                                 "right": {"type": "int", "value": 3},
                             },
                         },
-                        "right": {
-                            "type": "相等",
-                            "left": {"type": "identifier", "value": "c4"},
-                            "right": {"type": "string", "value": "'asd'"},
-                        },
+                    },
+                    "right": {
+                        "type": "相等",
+                        "left": {"type": "identifier", "value": "c4"},
+                        "right": {"type": "string", "value": "'asd'"},
                     },
                 },
             }
@@ -359,9 +361,7 @@ async def assert_sqls():
         ],
     )
     await assert_sql(
-        """SELECT Sname
-            FROM Student
-            WHERE Sno IN (1,2,3) and 2 not in (3, 4, 5) or not 3 in (1, 2);""",
+        """SELECT Sname FROM Student WHERE Sno IN (1,2) and c in (3, 4, 5);""",
         [
             {
                 "type": "select",
@@ -380,12 +380,11 @@ async def assert_sqls():
                         "right": [
                             {"type": "int", "value": 1},
                             {"type": "int", "value": 2},
-                            {"type": "int", "value": 3},
                         ],
                     },
                     "right": {
-                        "type": "包含于",
-                        "left": {"type": "int", "value": 2},
+                        "type": "包含于",
+                        "left": {"type": "identifier", "value": "c"},
                         "right": [
                             {"type": "int", "value": 3},
                             {"type": "int", "value": 4},
@@ -396,6 +395,7 @@ async def assert_sqls():
             }
         ],
     )
+
     await assert_sql(
         """SELECT Sname
 FROM Student
@@ -435,7 +435,7 @@ async def restart():
 async def watch_src():
     async for changes in awatch("src"):
         print(datetime.now(), "re run...")
-        await asyncio.wait_for(on_modified(changes), 20)
+        await asyncio.wait_for(on_modified(changes), 10)
 
 
 async def main():

+ 2 - 1
src/calc.l

@@ -18,9 +18,10 @@ extern YYSTYPE yylval;
 %%
 
 [ \t\n]	;
+['][a-zA-Z][a-zA-Z0-9]*[']	    {cp_yylval_and_return(STRING_V);}
+
 [0-9]+\.[0-9]+ 	{yylval.fv = atof(yytext); return FLOAT_V;}
 [0-9]+		    {yylval.iv = atoi(yytext); return INT_V;}
-['][a-zA-Z][a-zA-Z0-9]*[']	    {cp_yylval_and_return(STRING_V);}
 
 
 "CREATE"	{return CREATE;}

+ 26 - 32
src/calc.y

@@ -76,16 +76,16 @@ cJSON* jroot;
 %type <jv> create_definition create_col_list create_table_stmt data_value
 %type <jv> insert_stmt insert_list 
 %type <jv> update_stmt update_list single_assign_item
-%type <jv> where_condition_item identifier identifier_or_const_value the_whole_where_smt 
+%type <jv> where_condition_item identifier identifier_or_const_value 
 %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 op_where_expr expr_list
+%type <jv> search_expr compare_expr single_expr expr where_expr logical_expr negative_expr op_where_expr expr_list contains_expr
 
 
-// %left OR
-// %left AND
-// %right NOT
-// %nonassoc '=' '>' '<'
+%left OR
+%left AND
+%right NOT
+%nonassoc '=' '>' '<'
 // %left '+' '-'
 // %left '*' '/'
 
@@ -224,12 +224,6 @@ single_assign_item: identifier '=' identifier_or_const_value {
 	}
 ;
 
-the_whole_where_smt: {$$=cJSON_CreateObject();}
-	| WHERE where_expr {$$=$2;}
-;
-
-// where 后的条件跟 select 中的有本质区别
-// select 中的只是常量或者字段名, 而 where 中的是表达式
 
 single_expr: identifier {$$=$1;}
 	| IDENTIFIER '.' IDENTIFIER {
@@ -246,7 +240,6 @@ where_expr: logical_expr {
 		MEET_JSON(logical_expr from where_expr, $1);
 		$$=$1;
 	}
-	| '(' where_expr ')' {$$=$2;}
 ;
 op_where_expr: {$$=cJSON_CreateObject();} 
 	| WHERE where_expr {$$=$2;}
@@ -255,21 +248,32 @@ compare_expr: compare_expr bin_cmp_op compare_expr {
 	fprintf(stderr, "compare_expr %s\n", $2);
 	SIMPLE_OP_NODE($$, $2, $1, $3);}
 	| single_expr {MEET_JSON(single_expr from compare_expr, $1); $$=$1;}
-	| where_expr {MEET_JSON(where_expr from compare_expr, $1) $$=$1;}
+	| '(' where_expr ')' {MEET(括号where_expr from compare_expr); $$=$2;}
 
 ;
 negative_expr: NOT negative_expr {
 		fprintf(stderr, "negative_expr\n");
 	SIMPLE_OP_NODE_ONLY_LEFT($$, "非", $2);}
 	| compare_expr {MEET_JSON(compare_expr from negative_expr, $1) $$=$1;}
-	| where_expr {MEET(where_expr from negative_expr) $$=$1;}
+	| '(' negative_expr ')' {MEET_JSON(negative_expr from negative_expr, $2) $$=$2;}
 ;
-logical_expr: logical_expr bin_logical_op negative_expr {
+contains_expr: contains_expr bin_contains_op '(' select_stmt ')' {
+		MEET_JSON(logical_expr bin_contains_op select_stmt, $2);
+		SIMPLE_OP_NODE($$, $2, $1, $4)
+	}
+	| contains_expr bin_contains_op '(' expr_list ')' {
+		MEET_VAR(logical_expr bin_contains_op expr_list, $2);
+		SIMPLE_OP_NODE($$, $2, $1, $4)
+	}
+	| negative_expr {MEET_JSON(negative_expr from contains_expr, $1); $$=$1;}
+
+logical_expr: logical_expr bin_logical_op contains_expr {
 		fprintf(stderr, "logical_expr %s\n", $2);
 		SIMPLE_OP_NODE($$, $2, $1, $3);}
-	| negative_expr {MEET_JSON(negative_expr from logical_expr, $1); $$=$1;}
+	| contains_expr {MEET_JSON(contains_expr from logical_expr, $1); $$=$1;}
 	| single_expr {MEET_JSON(single_expr from logical_expr, $1) $$=$1;}
-	// | '(' logical_expr ')' {$$=$2;}
+	| negative_expr {MEET_JSON(negative_expr from logical_expr, $1); $$=$1;}
+
 ;
 
 
@@ -285,21 +289,11 @@ expr_list: {
 		cJSON_AddItemToArray(node, $1);
 		$$=node;
 	}
-	// | expr_list ',' logical_expr {
-	// 	fprintf(stderr, "迭代 expr_list\n %s", cJSON_Print($1));
-	// 	cJSON_AddItemToArray($1, $3);
-	// 	$$=$1;
-	// }
-;
-
-where_expr: logical_expr bin_contains_op '(' expr_list ')' {
-		MEET_JSON(logical_expr bin_contains_op expr_list, $2);
-		SIMPLE_OP_NODE($$, $2, $1, $4)
+	| expr_list ',' logical_expr {
+		fprintf(stderr, "迭代 expr_list\n %s", cJSON_Print($1));
+		cJSON_AddItemToArray($1, $3);
+		$$=$1;
 	}
-	// | logical_expr bin_contains_op '(' select_stmt ')' {
-	// 	MEET_JSON(logical_expr bin_contains_op select_stmt, $2);
-	// 	SIMPLE_OP_NODE($$, $2, $1, $4)
-	// }
 ;
 
 identifier: IDENTIFIER {