-
Notifications
You must be signed in to change notification settings - Fork 1
/
minic.y
245 lines (217 loc) · 7.6 KB
/
minic.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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
%{
#include <stdio.h>
#include <string.h>
#include "lex.yy.c"
struct SymbolTable {
char * name;
char * datatype;
char * type;
int line_no;
} symbol_table[100];
char current_data_type[10];
int symbol_table_counter = 0;
void check_if_not_declared(char * name);
int label_counter=0;
int label_skip_loop=0;
enum VarType { var,func };
void yyerror(const char *s) {
fprintf(stderr, "Error: %s\n", s);
}
void add_to_symbol_table(enum VarType vt,char * name);
char c_loop_condition[100];
char c_for_action[20];
char c_label[20];
struct token_node {
struct token_node * left;
struct token_node * right;
char * val;
};
struct token_node * head;
struct token_node* bootstrap_node(struct token_node * left, struct token_node * right,char * token){
struct token_node * base_node =(struct node *) malloc(sizeof(struct token_node));
base_node->left = left;
base_node->right = right;
char *_token = (char *)malloc(strlen(token)+1);
strcpy(_token, token);
base_node->val=_token;
return base_node;
}
int tac = 0;
char * three_address_code[100];
int fltac=0;
%}
%union {
struct TokenData {
char name[100];
struct token_node* nd;
} token_data;
}
%token <token_data> UNARY COMP FOR DATATYPE MAIN INT NUMBER ID INCLUDES B_OPEN B_CLOSE C_OPEN C_CLOSE EQL SEMI STR_LITERAL WHILE
%type <token_data> WHILE_LOOP FOR_LOOP LITERAL PROGRAM FUNCTION FUNCTIONS MAIN_FUNC NORMAL_FUNC INCLUDE_STM BODY STATEMENT ASSIGN DATATYPE_ALL
%%
PROGRAM: INCLUDE_STM FUNCTIONS {$$.nd=bootstrap_node($1.nd,$2.nd,"program");head=$$.nd;}
;
FUNCTIONS: MAIN_FUNC NORMAL_FUNC {
$$.nd=bootstrap_node($1.nd,$2.nd,"functions");
}
;
MAIN_FUNC: INT MAIN {add_to_symbol_table(func,$2.name)} {
char *max=(char *)malloc(sizeof($1.nd->val)+10);
sprintf(max,"LABEL %s:\n","main");
three_address_code[tac++] = max;
} B_OPEN B_CLOSE BODY {$$.nd=bootstrap_node($7.nd,NULL,"main");}
;
NORMAL_FUNC: FUNCTION NORMAL_FUNC {
$$.nd=bootstrap_node($1.nd,$2.nd,$1.nd->val);
char *max=(char *)malloc(sizeof($1.nd->val)+10);
sprintf(max,"LABEL %s:\n",$1.nd->val);
three_address_code[tac++] = max;
} | {}
;
INCLUDE_STM: INCLUDES {$$.nd=bootstrap_node(NULL,NULL,"include");} | INCLUDE_STM INCLUDES {$$.nd=bootstrap_node($1.nd,NULL,$1.name);}
;
BODY: C_OPEN STATEMENT C_CLOSE {$$.nd=bootstrap_node($2.nd,NULL,"body");}
;
STATEMENT: FOR_LOOP | WHILE_LOOP | ASSIGN SEMI | FUNC_CALL SEMI | STATEMENT STATEMENT {$$.nd=bootstrap_node($1.nd,$2.nd,"statement");} | {}
;
WHILE_LOOP: WHILE {
sprintf(c_label,"L%d",label_counter++);
} B_OPEN ID COMP NUMBER {
check_if_not_declared($4.name);
char *max=(char *)malloc(sizeof(c_label)+10);
sprintf(max,"IF %s %s %s GOTO %s\n",$4.name,$5.name,$6.name,c_label);
three_address_code[tac++] = max;
char * skip_loop=(char *)malloc(sizeof(c_label)+100);
label_skip_loop=label_counter++;
sprintf(skip_loop,"GOTO L%d\n",label_skip_loop);
three_address_code[tac++] = skip_loop;
char * label_declaration=(char *)malloc(sizeof(c_label)+100);
sprintf(label_declaration,"%s:\n",c_label);
three_address_code[tac++] = label_declaration;
strcpy(c_loop_condition,max);
} B_CLOSE BODY {
$$.nd=bootstrap_node($9.nd,NULL,"while");
three_address_code[tac++] = strdup(c_loop_condition);
char *max2=(char *)malloc(sizeof($1.nd->val)+10);
sprintf(max2,"L%d:\n",label_skip_loop);
three_address_code[tac++] = max2;
};
FOR_LOOP: FOR {
sprintf(c_label,"L%d",label_counter++);
} B_OPEN ASSIGN {
} SEMI ID COMP NUMBER {
char *max=(char *)malloc(sizeof($1.nd->val)+10);
sprintf(max,"IF %s %s %s GOTO %s\n",$7.name,$8.name,$9.name,c_label);
three_address_code[tac++] = max;
char * skip_loop=(char *)malloc(sizeof(c_label)+100);
label_skip_loop=label_counter++;
sprintf(skip_loop,"GOTO L%d\n",label_skip_loop);
three_address_code[tac++] = skip_loop;
char * label_declaration=(char *)malloc(sizeof(c_label)+100);
sprintf(label_declaration,"%s:\n",c_label);
three_address_code[tac++] = label_declaration;
strcpy(c_loop_condition,max);
} SEMI ID UNARY B_CLOSE BODY {
$$.nd=bootstrap_node($15.nd,NULL,"for");
char *max=(char *)malloc(sizeof($1.nd->val)+10);
sprintf(max,"%s%s\n",$12.name,$13.name);
three_address_code[tac++] = max;
three_address_code[tac++] = strdup(c_loop_condition);
char *max2=(char *)malloc(sizeof($1.nd->val)+10);
sprintf(max2,"L%d:\n",label_skip_loop);
three_address_code[tac++] = max2;
}
FUNC_CALL: ID B_OPEN B_CLOSE {
char *max=(char *)malloc(sizeof($1.nd->val)+10);
sprintf(max,"GOTO = %s\n","DUNNO");
three_address_code[tac++] = max;
}
ASSIGN: DATATYPE_ALL ID {add_to_symbol_table(var,$2.name)} EQL LITERAL {
$$.nd=bootstrap_node($1.nd,NULL,"assign");
char *max=(char *)malloc(sizeof($1.nd->val)+10);
sprintf(max,"%s = %s\n",$2.name,$5.name);
three_address_code[tac++] = max;
} | ID EQL LITERAL {
check_if_not_declared($1.name);
$$.nd=bootstrap_node(NULL,NULL,"assign");
char *max=(char *)malloc(sizeof($1.nd->val)+10);
sprintf(max,"%s = %s\n",$1.name,$3.name);
three_address_code[tac++] = max;
}
;
LITERAL: NUMBER | STR_LITERAL
DATATYPE_ALL: DATATYPE {strcpy(current_data_type,yytext);$$.nd=bootstrap_node(NULL,NULL,$1.name);} |
INT {strcpy(current_data_type,yytext)} {$$.nd=bootstrap_node(NULL,NULL,$1.name);}
;
FUNCTION: DATATYPE_ALL ID {add_to_symbol_table(func,$2.name)} B_OPEN B_CLOSE BODY {$$.nd=bootstrap_node($1.nd,$2.nd,$2.name);}
;
%%
void check_if_not_declared(char * name){
for(int j=0;j<symbol_table_counter;j++){
if(strcmp(symbol_table[j].name,name)==0){
return;
};
}
char * m = (char *)malloc(10);
sprintf(m,"Not declared: %s",name);
yyerror(m);
exit(1);
}
void add_to_symbol_table(enum VarType vt,char * name) {
for(int j=0;j<symbol_table_counter;j++){
if(strcmp(symbol_table[j].name,name)==0){
char * m = (char *)malloc(10);
sprintf(m,"Exist: %s",name);
yyerror(m);
exit(1);
};
}
if(vt == var) {
symbol_table[symbol_table_counter].name=strdup(name);
symbol_table[symbol_table_counter].datatype=strdup(current_data_type);
symbol_table[symbol_table_counter].line_no=line_no;
symbol_table[symbol_table_counter].type=strdup("Variable");
}
else if(vt == func) {
symbol_table[symbol_table_counter].name=strdup(name);
symbol_table[symbol_table_counter].datatype=strdup(current_data_type);
symbol_table[symbol_table_counter].line_no=line_no;
symbol_table[symbol_table_counter].type=strdup("Function");
}
symbol_table_counter++;
}
void print_symbol_table(){
printf("Symbol table\n");
for (int i = 0; i < symbol_table_counter; i++){
struct SymbolTable c_symbol_table = symbol_table[i];
printf("%s %s %s %d\n",c_symbol_table.name,c_symbol_table.datatype,c_symbol_table.type,c_symbol_table.line_no);
}
}
void preOrder(struct token_node *tree) {
if(tree){
printf("%s, ", tree->val);
preOrder(tree->left);
preOrder(tree->right);
}
}
void printtree(struct token_node* tree) {
printf("\n\n preorder traversal of the Parse Tree: \n\n");
preOrder(tree);
printf("\n\n");
}
void print_tac(){
printf("Three Address Code\n");
for (int i = 0; i < tac; i++){
printf("%s",three_address_code[i]);
}
}
int main(){
yyparse();
print_symbol_table();
printtree(head);
print_tac();
}
//max new phases
//lexical -> l vale
//syntax -> tree
//intermidiate -> tac