parser.y 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. %{
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <cjson/cJSON.h>
  6. #include <signal.h>
  7. extern int yylex();
  8. extern int yyparse();
  9. extern FILE* yyin;
  10. extern char* yytext;
  11. int yydebug=1;
  12. void yyerror(const char* s);
  13. cJSON* jroot;
  14. #define SIMPLE_OP_NODE(res, type, left, right) \
  15. fprintf(stderr, "SIMPLE_OP_NODE type: %s %s %s\n", (type), cJSON_Print(left), cJSON_Print(right)); \
  16. cJSON* node = cJSON_CreateObject(); \
  17. cJSON_AddStringToObject(node, "type", type); \
  18. cJSON_AddItemToObject(node, "left", left); \
  19. cJSON_AddItemToObject(node, "right", right); \
  20. res = node;
  21. #define SIMPLE_OP_NODE_ONLY_LEFT(res, type, left) \
  22. fprintf(stderr, "SIMPLE_OP_NODE_ONLY_LEFT type: %s %s %s\n", (type), cJSON_Print(left)); \
  23. cJSON* node = cJSON_CreateObject(); \
  24. cJSON_AddStringToObject(node, "type", type); \
  25. cJSON_AddItemToObject(node, "left", left); \
  26. res = node;
  27. #define SIMPLE_TYPE_VALUE_OBJECT(res, type_name, json_type_name, value) \
  28. cJSON* node = cJSON_CreateObject(); \
  29. cJSON_AddStringToObject(node, "type", #type_name); \
  30. cJSON_Add##json_type_name##ToObject(node, "value", value); \
  31. res = node;
  32. #define MEET(msg) fprintf(stderr, "MEET %s\n", #msg);
  33. #define MEET_VAR(msg, msg2) fprintf(stderr, "MEET %s %s\n", #msg, msg2);
  34. #define MEET_JSON(msg, msg2) MEET_VAR(msg, cJSON_Print(msg2));
  35. #define ADD_TO_ROOT(node) cJSON_AddItemToArray(jroot, node);
  36. %}
  37. %union {
  38. int iv;
  39. double fv;
  40. char* sv;
  41. cJSON* jv;
  42. int subtok;
  43. }
  44. %token IDENTIFIER
  45. %token SELECT FROM WHERE INSERT INTO VALUES DELETE UPDATE SET JOIN CREATE TABLE DROP
  46. %token AS ON
  47. %token AND OR NOT IN
  48. %token INT_V FLOAT_V STRING_V // 作为 value 出现的
  49. %token INT_T FLOAT_T STRING_T // 作为 字面量 type 出现的情况
  50. %token LPAREN RPAREN COMMA
  51. %token PRIMARY_KEY
  52. %token QUIT NEWLINE
  53. %type <iv> INT_V
  54. %type <fv> FLOAT_V
  55. %type <sv> STRING_V NOT table_name
  56. %type <sv> IDENTIFIER data_type PRIMARY_KEY col_options bin_cmp_op bin_logical_op unary_compare_op bin_contains_op
  57. %type <jv> create_definition create_col_list create_table_stmt data_value
  58. %type <jv> insert_stmt insert_list
  59. %type <jv> update_stmt update_list single_assign_item
  60. %type <jv> identifier identifier_or_const_value
  61. %type <jv> delete_stmt select_stmt select_item select_items drop_stmt
  62. %type <jv> compare_expr single_expr where_expr logical_expr negative_expr op_where_expr expr_list contains_expr
  63. %type <jv> op_join table_field column_name
  64. %type <jv> table_name_list
  65. %left OR
  66. %left AND
  67. %right NOT
  68. %nonassoc '=' '>' '<'
  69. // %left '+' '-'
  70. // %left '*' '/'
  71. %start statements
  72. %%
  73. statements: statement
  74. | statements statement
  75. ;
  76. statement: NEWLINE
  77. | QUIT {printf("bye!\n"); exit(0); }
  78. | sql_statement
  79. ;
  80. sql_statement: create_table_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
  81. | insert_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
  82. | update_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
  83. | delete_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
  84. | select_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
  85. | drop_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
  86. ;
  87. create_table_stmt: CREATE TABLE IDENTIFIER
  88. {
  89. cJSON* node = cJSON_CreateObject();
  90. cJSON_AddStringToObject(node, "type", "create_stmt");
  91. cJSON_AddStringToObject(node, "table_name", $3);
  92. cJSON_AddItemToObject(node, "cols", cJSON_CreateArray());
  93. $$ = node;
  94. }
  95. ;
  96. create_table_stmt: CREATE TABLE IDENTIFIER '(' create_col_list ')' {
  97. cJSON* node = cJSON_CreateObject();
  98. cJSON_AddStringToObject(node, "type", "create_stmt");
  99. cJSON_AddStringToObject(node, "table_name", $3);
  100. cJSON_AddItemToObject(node, "cols", $5);
  101. $$ = node;
  102. }
  103. ;
  104. create_col_list: create_definition {
  105. cJSON* node = cJSON_CreateArray();
  106. cJSON_AddItemToArray(node, $1);
  107. $$ = node;
  108. }
  109. | create_col_list ',' create_definition {
  110. cJSON_AddItemToArray($1, $3);
  111. $$ = $1;
  112. }
  113. ;
  114. create_definition: IDENTIFIER data_type col_options {
  115. cJSON* node = cJSON_CreateObject();
  116. cJSON_AddStringToObject(node, "type", "create_column");
  117. cJSON_AddStringToObject(node, "column_name", $1);
  118. cJSON_AddStringToObject(node, "data_type", $2);
  119. if (strlen($3) > 0){
  120. cJSON_AddTrueToObject(node, "primary_key");
  121. } else {
  122. cJSON_AddFalseToObject(node, "primary_key");
  123. }
  124. $$ = node;
  125. }
  126. ;
  127. col_options: {$$ = "";}
  128. | PRIMARY_KEY {
  129. // printf("得到主键 %s\n", $1);
  130. $$ = $1;
  131. }
  132. ;
  133. data_type: INT_T
  134. | FLOAT_T
  135. | STRING_T
  136. ;
  137. insert_stmt: INSERT INTO IDENTIFIER VALUES '(' insert_list ')' {
  138. cJSON* node = cJSON_CreateObject();
  139. cJSON_AddStringToObject(node, "type", "insert_stmt");
  140. cJSON_AddStringToObject(node, "table_name", $3);
  141. cJSON_AddItemToObject(node, "values", $6);
  142. $$=node;
  143. }
  144. ;
  145. insert_list: data_value {
  146. cJSON* node = cJSON_CreateArray();
  147. cJSON_AddItemToArray(node, $1);
  148. $$=node;
  149. }
  150. | insert_list ',' data_value {
  151. cJSON_AddItemToArray($1, $3);
  152. $$=$1;
  153. }
  154. ;
  155. data_value: INT_V {SIMPLE_TYPE_VALUE_OBJECT($$, int, Number, $1);}
  156. | FLOAT_V {SIMPLE_TYPE_VALUE_OBJECT($$, float, Number, $1);}
  157. | STRING_V {SIMPLE_TYPE_VALUE_OBJECT($$, string, String, $1);}
  158. ;
  159. update_stmt: UPDATE IDENTIFIER SET update_list WHERE where_expr {
  160. cJSON* node = cJSON_CreateObject();
  161. cJSON_AddStringToObject(node, "type", "update_stmt");
  162. cJSON_AddStringToObject(node, "table_name", $2);
  163. cJSON_AddItemToObject(node, "set", $4);
  164. cJSON_AddItemToObject(node, "where", $6);
  165. $$=node;
  166. }
  167. ;
  168. update_list: single_assign_item {
  169. cJSON* node = cJSON_CreateArray();
  170. cJSON_AddItemToArray(node, $1);
  171. $$=node;
  172. }
  173. | update_list ',' single_assign_item {
  174. cJSON_AddItemToArray($1, $3);
  175. $$=$1;
  176. }
  177. ;
  178. single_assign_item: identifier '=' identifier_or_const_value {
  179. cJSON* node = cJSON_CreateObject();
  180. cJSON_AddStringToObject(node, "type", "assign_const");
  181. cJSON_AddItemToObject(node, "left", $1);
  182. cJSON_AddItemToObject(node, "right", $3);
  183. $$=node;
  184. }
  185. ;
  186. table_field: IDENTIFIER '.' IDENTIFIER {
  187. cJSON* node = cJSON_CreateObject();
  188. cJSON_AddStringToObject(node, "type", "table_field");
  189. cJSON_AddStringToObject(node, "table", $1);
  190. cJSON_AddStringToObject(node, "field", $3);
  191. $$=node;
  192. }
  193. ;
  194. column_name: table_field {$$=$1;} | identifier {$$=$1;};
  195. single_expr: identifier {$$=$1;}
  196. | table_field {$$=$1;}
  197. | data_value {$$=$1;}
  198. // | '(' single_expr ')' {$$=$2;}
  199. ;
  200. where_expr: logical_expr {
  201. MEET_JSON(logical_expr from where_expr, $1);
  202. $$=$1;
  203. }
  204. ;
  205. op_where_expr: {$$=cJSON_CreateObject();}
  206. | WHERE where_expr {$$=$2;}
  207. ;
  208. compare_expr: compare_expr bin_cmp_op compare_expr {
  209. fprintf(stderr, "compare_expr %s\n", $2);
  210. SIMPLE_OP_NODE($$, $2, $1, $3);
  211. cJSON_AddStringToObject($$, "op_type", "bin_cmp_op");
  212. }
  213. | single_expr {MEET_JSON(single_expr from compare_expr, $1); $$=$1;}
  214. | '(' where_expr ')' {MEET(括号where_expr from compare_expr); $$=$2;}
  215. ;
  216. negative_expr: NOT negative_expr {SIMPLE_OP_NODE_ONLY_LEFT($$, "非", $2);}
  217. | compare_expr {MEET_JSON(compare_expr from negative_expr, $1) $$=$1;}
  218. | '(' negative_expr ')' {MEET_JSON(negative_expr from negative_expr, $2) $$=$2;}
  219. ;
  220. contains_expr: identifier bin_contains_op '(' select_stmt ')' {
  221. MEET_JSON(logical_expr bin_contains_op select_stmt, $2);
  222. SIMPLE_OP_NODE($$, $2, $1, $4);
  223. cJSON_AddStringToObject($$, "op_type", "bin_contains_op");
  224. }
  225. | identifier bin_contains_op '(' expr_list ')' {
  226. MEET_VAR(logical_expr bin_contains_op expr_list, $2);
  227. SIMPLE_OP_NODE($$, $2, $1, $4);
  228. cJSON_AddStringToObject($$, "op_type", "bin_contains_op");
  229. }
  230. | negative_expr {MEET_JSON(negative_expr from contains_expr, $1); $$=$1;}
  231. ;
  232. logical_expr: logical_expr bin_logical_op contains_expr {
  233. fprintf(stderr, "logical_expr %s\n", $2);
  234. SIMPLE_OP_NODE($$, $2, $1, $3);
  235. cJSON_AddStringToObject($$, "op_type", "bin_logical_op");
  236. }
  237. | contains_expr {MEET_JSON(contains_expr from logical_expr, $1); $$=$1;}
  238. | single_expr {MEET_JSON(single_expr from logical_expr, $1) $$=$1;}
  239. | negative_expr {MEET_JSON(negative_expr from logical_expr, $1); $$=$1;}
  240. ;
  241. expr_list: {
  242. MEET(empty expr_list);
  243. cJSON* node = cJSON_CreateArray();
  244. $$=node;
  245. }
  246. | logical_expr {
  247. MEET_JSON(where_expr from expr_list, $1);
  248. cJSON* node = cJSON_CreateArray();
  249. cJSON_AddItemToArray(node, $1);
  250. $$=node;
  251. }
  252. | expr_list ',' logical_expr {
  253. fprintf(stderr, "迭代 expr_list\n %s", cJSON_Print($1));
  254. cJSON_AddItemToArray($1, $3);
  255. $$=$1;
  256. }
  257. ;
  258. identifier: IDENTIFIER {
  259. cJSON* node = cJSON_CreateObject();
  260. cJSON_AddStringToObject(node, "type", "identifier");
  261. cJSON_AddStringToObject(node, "value", $1);
  262. $$=node;
  263. }
  264. ;
  265. identifier_or_const_value: identifier {$$=$1;} | data_value {$$=$1;}
  266. ;
  267. bin_cmp_op: '=' {$$ = "相等";}
  268. | '>' {$$ = "大于";}
  269. | '<' {$$ = "小于";}
  270. | ">=" {$$ = "大等";}
  271. | "<=" {$$ = "小等";}
  272. | "!=" {$$ = "不等";}
  273. ;
  274. unary_compare_op: NOT {$$ = "非";}
  275. ;
  276. bin_logical_op: AND {MEET(and from bin_log) $$ = "且";}
  277. | OR {MEET(or from bin_log) $$ = "或";}
  278. ;
  279. bin_contains_op: IN {$$ = "包含于";}
  280. | NOT IN {$$ = "不包含于";}
  281. ;
  282. delete_stmt: DELETE FROM IDENTIFIER op_where_expr {
  283. cJSON* node = cJSON_CreateObject();
  284. cJSON_AddStringToObject(node, "type", "delete_stmt");
  285. cJSON_AddStringToObject(node, "table_name", $3);
  286. cJSON_AddItemToObject(node, "where", $4);
  287. $$=node;
  288. }
  289. ;
  290. op_join: {$$ = NULL;}
  291. | JOIN column_name ON where_expr {
  292. cJSON* node = cJSON_CreateObject();
  293. cJSON_AddStringToObject(node, "type", "join_options");
  294. cJSON_AddItemToObject(node, "join_with", $2);
  295. cJSON_AddItemToObject(node, "on", $4);
  296. $$=node;
  297. }
  298. ;
  299. table_name: IDENTIFIER {$$=$1;}
  300. ;
  301. table_name_list: table_name {
  302. cJSON* node = cJSON_CreateArray();
  303. cJSON_AddItemToArray(node, cJSON_CreateString($1));
  304. $$=node;
  305. }
  306. | table_name_list ',' table_name {
  307. cJSON_AddItemToArray($1, cJSON_CreateString($3));
  308. $$=$1;
  309. }
  310. ;
  311. select_stmt: SELECT select_items FROM table_name_list op_join op_where_expr {
  312. cJSON* node = cJSON_CreateObject();
  313. cJSON_AddStringToObject(node, "type", "select_stmt");
  314. cJSON_AddItemToObject(node, "select_cols", $2);
  315. MEET_JSON(table_names, $4);
  316. cJSON_AddItemToObject(node, "table_names", $4);
  317. if ($5 != NULL) {
  318. cJSON_AddItemToObject(node, "join_options", $5);
  319. }
  320. cJSON_AddItemToObject(node, "where", $6);
  321. $$=node;
  322. }
  323. ;
  324. select_items: select_item {
  325. cJSON* node = cJSON_CreateArray();
  326. cJSON_AddItemToArray(node, $1);
  327. $$=node;
  328. }
  329. | select_items ',' select_item {
  330. cJSON_AddItemToArray($1, $3);
  331. $$=$1;
  332. }
  333. ;
  334. select_item: single_expr {
  335. cJSON* node = cJSON_CreateObject();
  336. cJSON_AddStringToObject(node, "type", "select_column");
  337. cJSON_AddItemToObject(node, "target", $1);
  338. $$=node;
  339. }
  340. | single_expr AS IDENTIFIER {
  341. cJSON* node = cJSON_CreateObject();
  342. cJSON_AddStringToObject(node, "type", "select_column");
  343. cJSON_AddItemToObject(node, "target", $1);
  344. cJSON_AddStringToObject(node, "alias", $3);
  345. $$=node;
  346. }
  347. | '*' {
  348. cJSON* node = cJSON_CreateObject();
  349. cJSON_AddStringToObject(node, "type", "select_all_column");
  350. cJSON* node_select_all = cJSON_CreateObject();
  351. cJSON_AddStringToObject(node_select_all, "type", "select_all_column");
  352. cJSON_AddStringToObject(node_select_all, "value", "select_all_column");
  353. cJSON_AddItemToObject(node, "target", node_select_all);
  354. $$=node;
  355. }
  356. ;
  357. drop_stmt: DROP TABLE IDENTIFIER {
  358. cJSON* node = cJSON_CreateObject();
  359. cJSON_AddStringToObject(node, "type", "drop_stmt");
  360. cJSON_AddStringToObject(node, "table_name", $3);
  361. $$=node;
  362. }
  363. ;
  364. %%
  365. int main(int ac, char** av) {
  366. jroot = cJSON_CreateArray();
  367. if (ac != 2) {
  368. printf("Usage: %s <sql>\n", av[0]);
  369. exit(1);
  370. }
  371. yy_scan_string(av[1]);
  372. int res = yyparse();
  373. printf("%s\n", cJSON_Print(jroot));
  374. return res;
  375. }
  376. void yyerror(const char *s) {
  377. fprintf(stderr, "error: %s at %s\n", s, yytext);
  378. exit(1);
  379. }