-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate.y
154 lines (137 loc) · 3.05 KB
/
update.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int yylex();
int yyerror();
int yyrestart();
FILE* yyin;
void test();
int success();
bool isTestMode = false;
%}
%token UPDATE SET WHERE AND OR IS NOT ID LIKE BETWEEN END
%token NULL_VAL STR_VAL NUM_VAL DEFAULT_VAL BOOL_VAL
%token MAX_FUNC MIN_FUNC AVG_FUNC SUM_FUNC ABS_FUNC CEIL_FUNC FLOOR_FUNC UPPER_FUNC LOWER_FUNC
%%
start: UPDATE ID SET columns clause END { success(); }
;
columns: ID '=' col_val ',' columns
| ID '=' col_val
;
col_val: value
| DEFAULT_VAL
;
value: NULL_VAL next_val
| STR_VAL next_val
| BOOL_VAL next_val
| pre_num NUM_VAL next_val
| MAX_FUNC '(' func_value ')' next_val
| MIN_FUNC '(' func_value ')' next_val
| AVG_FUNC '(' func_value ')' next_val
| SUM_FUNC '(' func_value ')' next_val
| ABS_FUNC '(' func_value ')' next_val
| CEIL_FUNC '(' func_value ')' next_val
| FLOOR_FUNC '(' func_value ')' next_val
| UPPER_FUNC '(' func_value ')' next_val
| LOWER_FUNC '(' func_value ')' next_val
;
pre_num: '+' pre_num
| '-' pre_num
| '~' pre_num
|
;
next_val: airth_op value
|
;
func_value: value
| ID
;
airth_op: '+'
| '-'
| '*'
| '/'
| '%'
| '&'
| '|'
| '^'
;
clause: WHERE where_stmt
|
;
where_stmt:
| condition
| condition AND condition
| condition OR condition
| ID BETWEEN value AND value
| ID BETWEEN value OR value
| ID NOT BETWEEN value AND value
| ID NOT BETWEEN value OR value
| ID LIKE STR_VAL
| ID NOT LIKE STR_VAL
;
condition: '(' where_stmt ')'
| ID relop value
| ID IS is_val
| ID IS NOT is_val
| NOT ID relop value
;
is_val: BOOL_VAL
| NULL_VAL
;
relop: '='
| '!''='
| '<''>'
| '<'
| '>'
| '>''='
| '<''='
| '<''=''>'
;
%%
int success() {
printf("Query is Valid!\n");
if (!isTestMode)
exit(0);
return 0;
}
int yyerror(const char* msg) {
fprintf(stderr, "Error: %s\n", msg);
return 2;
}
void test() {
FILE *fin, *fout;
char* line = NULL;
size_t len = 0;
ssize_t read;
int DELIM_ASCII = 59; // ascii value of ';'
fin = fopen("tests.txt", "r");
if (fin == NULL)
exit(0);
printf("\nRunning all tests...\n\n");
int test_num = 1;
while ((read = getdelim(&line, &len, DELIM_ASCII, fin)) != -1 && read > 1) {
printf("\n\nTest: %d\n\n", test_num++);
printf("%s\n", line);
// writing current read query into another file
fout = fopen("query.txt", "w");
fwrite (line , sizeof(char), read, fout);
fclose(fout);
yyin = fopen("query.txt", "r");
yyparse();
yyrestart();
}
fclose(fin);
}
int main(int argc, char* argv[]) {
if (argc > 1 && strcmp(argv[1], "TEST") == 0) {
isTestMode = true;
test();
return 0;
}
printf("Enter a SQL update query:\n");
printf("SQL: ");
yyparse();
return 0;
}