├── ICG ├── ICG Report.pdf ├── parser.l ├── parser.y ├── symbolTable.c ├── test1.c ├── test2.c ├── test3.c ├── test4.c ├── test5.c ├── test6.c ├── test7.c └── test8.c ├── Lexical Analysis ├── Lexical Analysis Report.pdf ├── isPrime.c ├── lexer.l ├── test1.c ├── test2.c ├── test3.c ├── test4.c ├── test5.c └── test6.c ├── README.md ├── Semantic Analysis ├── Semantic Analysis Report.pdf ├── parser.l ├── parser.y ├── symbolTable.c ├── test1.c ├── test2.c ├── test3.c ├── test4.c ├── test5.c ├── test6.c └── test7.c └── Syntax Analysis ├── Readme.txt ├── Synatx Analysis Report.pdf ├── parser.l ├── parser.y ├── test1.c ├── test2.c ├── test3.c ├── test4.c ├── test5.c └── test6.c /ICG/ICG Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivananda199/Mini-C-Compiler/95ccf8af785851899ae5b47ef12e07bfb4298abb/ICG/ICG Report.pdf -------------------------------------------------------------------------------- /ICG/parser.l: -------------------------------------------------------------------------------- 1 | %{ 2 | int yylineno; 3 | %} 4 | 5 | alpha [A-Za-z] 6 | digit [0-9] 7 | 8 | 9 | %% 10 | [ \t] ; 11 | \n {yylineno++;} 12 | "{" {scope_start(); return '{';} 13 | "}" {scope_end(); return '}';} 14 | ";" { return(';'); } 15 | "," { return(','); } 16 | ":" { return(':'); } 17 | "=" { return('='); } 18 | "(" { return('('); } 19 | ")" { return(')'); } 20 | ("[") { return('['); } 21 | ("]") { return(']'); } 22 | "." { return('.'); } 23 | "&" { return('&'); } 24 | "!" { return('!'); } 25 | "~" { return('~'); } 26 | "-" { return('-'); } 27 | "+" { return('+'); } 28 | "*" { return('*'); } 29 | "/" { return('/'); } 30 | "%" { return('%'); } 31 | "<" { return('<'); } 32 | ">" { return('>'); } 33 | "^" { return('^'); } 34 | "|" { return('|'); } 35 | "?" { return('?'); } 36 | int {yylval.ival = INT; return INT;} 37 | float {yylval.ival = FLOAT; return FLOAT;} 38 | void {yylval.ival = VOID; return VOID;} 39 | else {return ELSE;} 40 | do return DO; 41 | if return IF; 42 | struct return STRUCT; 43 | ^"#include ".+ return PREPROC; 44 | while return WHILE; 45 | for return FOR; 46 | return return RETURN; 47 | printf return PRINT; 48 | {alpha}({alpha}|{digit})* {yylval.str=strdup(yytext); return ID;} 49 | {digit}+ {yylval.str=strdup(yytext);return NUM;} 50 | {digit}+\.{digit}+ {yylval.str=strdup(yytext); return REAL;} 51 | "<=" return LE; 52 | ">=" return GE; 53 | "==" return EQ; 54 | "!=" return NEQ; 55 | "&&" return AND; 56 | "||" return OR; 57 | \/\/.* ; 58 | \/\*(.*\n)*.*\*\/ ; 59 | 60 | \".*\" return STRING; 61 | . return yytext[0]; 62 | %% 63 | -------------------------------------------------------------------------------- /ICG/parser.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include "symbolTable.c" 5 | 6 | int g_addr = 100; 7 | int i=1,lnum1=0; 8 | int stack[100],index1=0,end[100],arr[10],ct,c,b,fl,top=0,label[20],label_num=0,ltop=0; 9 | char st1[100][10]; 10 | char temp_count[2]="0"; 11 | int plist[100],flist[100],k=-1,errc=0,j=0; 12 | char temp[2]="t"; 13 | char null[2]=" "; 14 | void yyerror(char *s); 15 | int printline(); 16 | extern int yylineno; 17 | void scope_start() 18 | { 19 | stack[index1]=i; 20 | i++; 21 | index1++; 22 | return; 23 | } 24 | void scope_end() 25 | { 26 | index1--; 27 | end[stack[index1]]=1; 28 | stack[index1]=0; 29 | return; 30 | } 31 | void if1() 32 | { 33 | label_num++; 34 | strcpy(temp,"t"); 35 | strcat(temp,temp_count); 36 | printf("\n%s = not %s\n",temp,st1[top]); 37 | printf("if %s goto L%d\n",temp,label_num); 38 | temp_count[0]++; 39 | label[++ltop]=label_num; 40 | 41 | } 42 | void if2() 43 | { 44 | label_num++; 45 | printf("\ngoto L%d\n",label_num); 46 | printf("L%d: \n",label[ltop--]); 47 | label[++ltop]=label_num; 48 | } 49 | void if3() 50 | { 51 | printf("\nL%d:\n",label[ltop--]); 52 | } 53 | void while1() 54 | { 55 | label_num++; 56 | label[++ltop]=label_num; 57 | printf("\nL%d:\n",label_num); 58 | } 59 | void while2() 60 | { 61 | label_num++; 62 | strcpy(temp,"t"); 63 | strcat(temp,temp_count); 64 | printf("\n%s = not %s\n",temp,st1[top--]); 65 | printf("if %s goto L%d\n",temp,label_num); 66 | temp_count[0]++; 67 | label[++ltop]=label_num; 68 | } 69 | void while3() 70 | { 71 | int y=label[ltop--]; 72 | printf("\ngoto L%d\n",label[ltop--]); 73 | printf("L%d:\n",y); 74 | } 75 | void dowhile1() 76 | { 77 | label_num++; 78 | label[++ltop]=label_num; 79 | printf("\nL%d:\n",label_num); 80 | } 81 | void dowhile2() 82 | { 83 | printf("\nif %s goto L%d\n",st1[top--],label[ltop--]); 84 | } 85 | void for1() 86 | { 87 | label_num++; 88 | label[++ltop]=label_num; 89 | printf("\nL%d:\n",label_num); 90 | } 91 | void for2() 92 | { 93 | label_num++; 94 | strcpy(temp,"t"); 95 | strcat(temp,temp_count); 96 | printf("\n%s = not %s\n",temp,st1[top--]); 97 | printf("if %s goto L%d\n",temp,label_num); 98 | temp_count[0]++; 99 | label[++ltop]=label_num; 100 | label_num++; 101 | printf("goto L%d\n",label_num); 102 | label[++ltop]=label_num; 103 | label_num++; 104 | printf("L%d:\n",label_num); 105 | label[++ltop]=label_num; 106 | } 107 | void for3() 108 | { 109 | printf("\ngoto L%d\n",label[ltop-3]); 110 | printf("L%d:\n",label[ltop-1]); 111 | } 112 | void for4() 113 | { 114 | printf("\ngoto L%d\n",label[ltop]); 115 | printf("L%d:\n",label[ltop-2]); 116 | ltop-=4; 117 | } 118 | void push(char *a) 119 | { 120 | strcpy(st1[++top],a); 121 | } 122 | void array1() 123 | { 124 | strcpy(temp,"t"); 125 | strcat(temp,temp_count); 126 | printf("\n%s = %s\n",temp,st1[top]); 127 | strcpy(st1[top],temp); 128 | temp_count[0]++; 129 | strcpy(temp,"t"); 130 | strcat(temp,temp_count); 131 | printf("%s = %s [ %s ] \n",temp,st1[top-1],st1[top]); 132 | top--; 133 | strcpy(st1[top],temp); 134 | temp_count[0]++; 135 | } 136 | void codegen() 137 | { 138 | strcpy(temp,"t"); 139 | strcat(temp,temp_count); 140 | printf("\n%s = %s %s %s\n",temp,st1[top-2],st1[top-1],st1[top]); 141 | top-=2; 142 | strcpy(st1[top],temp); 143 | temp_count[0]++; 144 | } 145 | void codegen_umin() 146 | { 147 | strcpy(temp,"t"); 148 | strcat(temp,temp_count); 149 | printf("\n%s = -%s\n",temp,st1[top]); 150 | top--; 151 | strcpy(st1[top],temp); 152 | temp_count[0]++; 153 | } 154 | void codegen_assign() 155 | { 156 | printf("\n%s = %s\n",st1[top-2],st1[top]); 157 | top-=2; 158 | } 159 | %} 160 | 161 | %token INT FLOAT VOID 162 | %token ID NUM REAL 163 | %token WHILE IF RETURN PREPROC LE STRING PRINT FUNCTION DO ARRAY ELSE STRUCT STRUCT_VAR FOR GE EQ NE INC DEC AND OR 164 | %left LE GE EQ NEQ AND OR '<' '>' 165 | %right '=' 166 | %right UMINUS 167 | %left '+' '-' 168 | %left '*' '/' 169 | %type assignment assignment1 consttype '=' '+' '-' '*' '/' E T F 170 | %type Type 171 | %union { 172 | int ival; 173 | char *str; 174 | } 175 | %% 176 | 177 | start : Function start 178 | | PREPROC start 179 | | Declaration start 180 | | 181 | ; 182 | 183 | Function : Type ID '('')' CompoundStmt { 184 | if(strcmp($2,"main")!=0) 185 | { 186 | printf("goto F%d\n",lnum1); 187 | } 188 | if ($1!=returntype_func(ct)) 189 | { 190 | printf("\nError : Type mismatch : Line %d\n",printline()); 191 | } 192 | 193 | if (!(strcmp($2,"printf") && strcmp($2,"scanf") && strcmp($2,"getc") && strcmp($2,"gets") && strcmp($2,"getchar") && strcmp ($2,"puts") && strcmp($2,"putchar") && strcmp($2,"clearerr") && strcmp($2,"getw") && strcmp($2,"putw") && strcmp($2,"putc") && strcmp($2,"rewind") && strcmp($2,"sprint") && strcmp($2,"sscanf") && strcmp($2,"remove") && strcmp($2,"fflush"))) 194 | printf("Error : Type mismatch in redeclaration of %s : Line %d\n",$2,printline()); 195 | else 196 | { 197 | insert($2,FUNCTION); 198 | insert($2,$1); 199 | g_addr+=4; 200 | } 201 | } 202 | | Type ID '(' parameter_list ')' CompoundStmt { 203 | if ($1!=returntype_func(ct)) 204 | { 205 | printf("\nError : Type mismatch : Line %d\n",printline()); errc++; 206 | } 207 | 208 | if (!(strcmp($2,"printf") && strcmp($2,"scanf") && strcmp($2,"getc") && strcmp($2,"gets") && strcmp($2,"getchar") && strcmp ($2,"puts") && strcmp($2,"putchar") && strcmp($2,"clearerr") && strcmp($2,"getw") && strcmp($2,"putw") && strcmp($2,"putc") && strcmp($2,"rewind") && strcmp($2,"sprint") && strcmp($2,"sscanf") && strcmp($2,"remove") && strcmp($2,"fflush"))) 209 | {printf("Error : Redeclaration of %s : Line %d\n",$2,printline());errc++;} 210 | else 211 | { 212 | insert($2,FUNCTION); 213 | insert($2,$1); 214 | for(j=0;j<=k;j++) 215 | {insertp($2,plist[j]);} 216 | k=-1; 217 | } 218 | } 219 | ; 220 | 221 | parameter_list : parameter_list ',' parameter 222 | | parameter 223 | ; 224 | 225 | parameter : Type ID {plist[++k]=$1;insert($2,$1);insertscope($2,i);} 226 | ; 227 | 228 | Type : INT 229 | | FLOAT 230 | | VOID 231 | ; 232 | 233 | CompoundStmt : '{' StmtList '}' 234 | ; 235 | 236 | StmtList : StmtList stmt 237 | | 238 | ; 239 | 240 | stmt : Declaration 241 | | if 242 | | ID '(' ')' ';' 243 | | while 244 | | dowhile 245 | | for 246 | | RETURN consttype ';' { 247 | if(!(strspn($2,"0123456789")==strlen($2))) 248 | storereturn(ct,FLOAT); 249 | else 250 | storereturn(ct,INT); ct++; 251 | } 252 | | RETURN ';' {storereturn(ct,VOID); ct++;} 253 | | RETURN ID ';' { 254 | int sct=returnscope($2,stack[top-1]); //stack[top-1] - current scope 255 | int type=returntype($2,sct); 256 | if (type==259) storereturn(ct,FLOAT); 257 | else storereturn(ct,INT); 258 | ct++; 259 | } 260 | | ';' 261 | | PRINT '(' STRING ')' ';' 262 | | CompoundStmt 263 | ; 264 | 265 | dowhile : DO {dowhile1();} CompoundStmt WHILE '(' E ')' {dowhile2();} ';' 266 | ; 267 | 268 | for : FOR '(' E {for1();} ';' E {for2();}';' E {for3();} ')' CompoundStmt {for4();} 269 | ; 270 | 271 | if : IF '(' E ')' {if1();} CompoundStmt {if2();} else 272 | ; 273 | 274 | else : ELSE CompoundStmt {if3();} 275 | | 276 | ; 277 | 278 | while : WHILE {while1();}'(' E ')' {while2();} CompoundStmt {while3();} 279 | ; 280 | 281 | assignment : ID '=' consttype 282 | | ID '+' assignment 283 | | ID ',' assignment 284 | | consttype ',' assignment 285 | | ID 286 | | consttype 287 | ; 288 | 289 | assignment1 : ID {push($1);} '=' {strcpy(st1[++top],"=");} E {codegen_assign();} 290 | { 291 | int sct=returnscope($1,stack[index1-1]); 292 | int type=returntype($1,sct); 293 | if((!(strspn($5,"0123456789")==strlen($5))) && type==258 && fl==0) 294 | printf("\nError : Type Mismatch : Line %d\n",printline()); 295 | if(!lookup($1)) 296 | { 297 | int currscope=stack[index1-1]; 298 | int scope=returnscope($1,currscope); 299 | if((scope<=currscope && end[scope]==0) && !(scope==0)) 300 | { 301 | check_scope_update($1,$5,currscope); 302 | } 303 | } 304 | } 305 | 306 | | ID ',' assignment1 { 307 | if(lookup($1)) 308 | printf("\nUndeclared Variable %s : Line %d\n",$1,printline()); 309 | } 310 | | consttype ',' assignment1 311 | | ID { 312 | if(lookup($1)) 313 | printf("\nUndeclared Variable %s : Line %d\n",$1,printline()); 314 | } 315 | // | function_call 316 | | consttype 317 | ; 318 | 319 | /* 320 | function_call: ID '=' E '(' paralist ')' //function call 321 | { 322 | int sct=returnscope($1,stack[top-1]); 323 | int type=returntype($1,sct); 324 | //printf("%s",$3); 325 | int rtype; 326 | rtype=returntypef($3); int ch=0; 327 | //printf("%d",rtype); 328 | if(rtype!=type) 329 | { printf("\nError : Type Mismatch : Line %d\n",printline()); errc++;} 330 | if(!lookup($1)) 331 | { 332 | for(j=0;j<=l;j++) 333 | {ch = ch+checkp($3,flist[j],j);} 334 | if(ch>0) { printf("\nError : Parameter Type Mistake or Function undeclared : Line %d\n",printline()); errc++;} 335 | l=-1; 336 | } 337 | } 338 | | ID '(' paralist ')' //function call without assignment 339 | { 340 | int sct=returnscope($1,stack[top-1]); 341 | int type=returntype($1,sct); int ch=0; 342 | if(!lookup($1)) 343 | { 344 | for(j=0;j<=l;j++) 345 | {ch = ch+checkp($1,flist[j],j);} 346 | if(ch>0) { printf("\nError : Parameter Type Mistake or Required Function undeclared : Line %d\n",printline()); errc++;} 347 | l=-1; 348 | } 349 | else {printf("\nUndeclared Function %s : Line %d\n",$1,printline());errc++;} 350 | } 351 | ; 352 | 353 | paralist : paralist ',' param 354 | | param 355 | ; 356 | 357 | param : ID 358 | { 359 | if(lookup($1)) 360 | {printf("\nUndeclared Variable %s : Line %d\n",$1,printline());errc++;} 361 | else 362 | { 363 | int sct=returnscope($1,stack[top-1]); 364 | flist[++l]=returntype($1,sct); 365 | } 366 | } 367 | ; 368 | */ 369 | 370 | consttype : NUM 371 | | REAL 372 | ; 373 | 374 | Declaration : Type ID {push($2);} '=' {strcpy(st1[++top],"=");} E {codegen_assign();} ';' 375 | { 376 | if( (!(strspn($6,"0123456789")==strlen($6))) && $1==258 && (fl==0)) 377 | { 378 | printf("\nError : Type Mismatch : Line %d\n",printline()); 379 | fl=1; 380 | } 381 | if(!lookup($2)) 382 | { 383 | int currscope=stack[index1-1]; 384 | int previous_scope=returnscope($2,currscope); 385 | if(currscope==previous_scope) 386 | printf("\nError : Redeclaration of %s : Line %d\n",$2,printline()); 387 | else 388 | { 389 | insert_dup($2,$1,currscope); 390 | check_scope_update($2,$6,stack[index1-1]); 391 | int sg=returnscope($2,stack[index1-1]); 392 | g_addr+=4; 393 | } 394 | } 395 | else 396 | { 397 | int scope=stack[index1-1]; 398 | insert($2,$1); 399 | insertscope($2,scope); 400 | check_scope_update($2,$6,stack[index1-1]); 401 | g_addr+=4; 402 | } 403 | } 404 | 405 | | assignment1 ';' { 406 | if(!lookup($1)) 407 | { 408 | int currscope=stack[index1-1]; 409 | int scope=returnscope($1,currscope); 410 | if(!(scope<=currscope && end[scope]==0) || scope==0) 411 | printf("\nError : Variable %s out of scope : Line %d\n",$1,printline()); 412 | } 413 | else 414 | printf("\nError : Undeclared Variable %s : Line %d\n",$1,printline()); 415 | } 416 | /* 417 | | Type ID '[' assignment ']' ';' { 418 | insert($2,ARRAY); 419 | insert($2,$1); 420 | g_addr+=4; 421 | } 422 | */ 423 | | Type ID '[' assignment ']' ';' { 424 | int itype; 425 | if(!(strspn($4,"0123456789")==strlen($4))) { itype=259; } else itype = 258; 426 | if(itype!=258) 427 | { printf("\nError : Array index must be of type int : Line %d\n",printline());errc++;} 428 | if(atoi($4)<=0) 429 | { printf("\nError : Array index must be of type int > 0 : Line %d\n",printline());errc++;} 430 | if(!lookup($2)) 431 | { 432 | int currscope=stack[top-1]; 433 | int previous_scope=returnscope($2,currscope); 434 | if(currscope==previous_scope) 435 | {printf("\nError : Redeclaration of %s : Line %d\n",$2,printline());errc++;} 436 | else 437 | { 438 | insert_dup($2,ARRAY,currscope); 439 | insert_by_scope($2,$1,currscope); //to insert type to the correct identifier in case of multiple entries of the identifier by using scope 440 | if (itype==258) {insert_index($2,$4);} 441 | } 442 | } 443 | else 444 | { 445 | int scope=stack[top-1]; 446 | insert($2,ARRAY); 447 | insert($2,$1); 448 | insertscope($2,scope); 449 | if (itype==258) {insert_index($2,$4);} 450 | } 451 | } 452 | 453 | | ID '[' assignment1 ']' ';' 454 | | STRUCT ID '{' Declaration '}' ';' { 455 | insert($2,STRUCT); 456 | g_addr+=4; 457 | } 458 | | STRUCT ID ID ';' { 459 | insert($3,STRUCT_VAR); 460 | g_addr+=4; 461 | } 462 | | error 463 | ; 464 | 465 | array : ID {push($1);}'[' E ']' 466 | ; 467 | 468 | E : E '+'{strcpy(st1[++top],"+");} T{codegen();} 469 | | E '-'{strcpy(st1[++top],"-");} T{codegen();} 470 | | T 471 | | ID {push($1);} LE {strcpy(st1[++top],"<=");} E {codegen();} 472 | | ID {push($1);} GE {strcpy(st1[++top],">=");} E {codegen();} 473 | | ID {push($1);} EQ {strcpy(st1[++top],"==");} E {codegen();} 474 | | ID {push($1);} NEQ {strcpy(st1[++top],"!=");} E {codegen();} 475 | | ID {push($1);} AND {strcpy(st1[++top],"&&");} E {codegen();} 476 | | ID {push($1);} OR {strcpy(st1[++top],"||");} E {codegen();} 477 | | ID {push($1);} '<' {strcpy(st1[++top],"<");} E {codegen();} 478 | | ID {push($1);} '>' {strcpy(st1[++top],">");} E {codegen();} 479 | | ID {push($1);} '=' {strcpy(st1[++top],"=");} E {codegen_assign();} 480 | | array {array1();} 481 | ; 482 | T : T '*'{strcpy(st1[++top],"*");} F{codegen();} 483 | | T '/'{strcpy(st1[++top],"/");} F{codegen();} 484 | | F 485 | ; 486 | F : '(' E ')' {$$=$2;} 487 | | '-'{strcpy(st1[++top],"-");} F{codegen_umin();} %prec UMINUS 488 | | ID {push($1);fl=1;} 489 | | consttype {push($1);} 490 | ; 491 | 492 | %% 493 | 494 | #include "lex.yy.c" 495 | #include 496 | 497 | 498 | int main(int argc, char *argv[]) 499 | { 500 | yyin =fopen(argv[1],"r"); 501 | yyparse(); 502 | if(!yyparse()) 503 | { 504 | printf("Parsing done\n"); 505 | print(); 506 | } 507 | else 508 | { 509 | printf("Error\n"); 510 | } 511 | fclose(yyin); 512 | return 0; 513 | } 514 | 515 | void yyerror(char *s) 516 | { 517 | printf("\nLine %d : %s %s\n",yylineno,s,yytext); 518 | } 519 | int printline() 520 | { 521 | return yylineno; 522 | } 523 | -------------------------------------------------------------------------------- /ICG/symbolTable.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | struct sym 4 | { 5 | int sno; 6 | char token[100]; 7 | int type[100]; 8 | int paratype[100]; 9 | int tn; 10 | int pn; 11 | float fvalue; 12 | int index; 13 | int scope; 14 | }st[100]; 15 | int n=0,arr[10]; 16 | float t[100]; 17 | int iter=0; 18 | int returntype_func(int ct) 19 | { 20 | return arr[ct-1]; 21 | } 22 | void storereturn( int ct, int returntype ) 23 | { 24 | arr[ct] = returntype; 25 | return; 26 | } 27 | void insertscope(char *a,int s) 28 | { 29 | int i; 30 | for(i=0;i=st[i].scope) 46 | { 47 | if(st[i].scope>=max) 48 | max = st[i].scope; 49 | } 50 | } 51 | return max; 52 | } 53 | int lookup(char *a) 54 | { 55 | int i; 56 | for(i=0;i=st[i].scope) 102 | { 103 | if(st[i].scope>=max) 104 | max=st[i].scope; 105 | } 106 | } 107 | for(i=0;i<=n;i++) 108 | { 109 | if(!strcmp(a,st[i].token) && max==st[i].scope) 110 | { 111 | float temp=atof(b); 112 | for(k=0;k1 && j<(st[i].tn-1))printf(" - "); 253 | } 254 | printf("\n"); 255 | } 256 | printf("-----------------------------------------------------------------------\n\n"); 257 | return; 258 | } 259 | -------------------------------------------------------------------------------- /ICG/test1.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=5; 5 | int b=6; 6 | int d=a+b-c*a/d; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /ICG/test2.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=5; 5 | int b=6; 6 | if(a<=7) 7 | b=b-4; 8 | else 9 | b=b+3; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /ICG/test3.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=5; 5 | int b=6; 6 | while(a<20) 7 | { 8 | b=b+1; 9 | a=a+1; 10 | } 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /ICG/test4.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=5; 5 | int b=6; 6 | int c=8; 7 | for(a=9;a!=6;a=a-1) 8 | { 9 | b=b+4; 10 | c=c-1; 11 | } 12 | b=b/9; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ICG/test5.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=5; 5 | int b=6; 6 | do 7 | { 8 | b=b+1; 9 | }while(a>7); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /ICG/test6.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=5; 5 | int b=6; 6 | if(a<=7) 7 | { 8 | if(a==9) 9 | { 10 | b=b*8; 11 | b=9; 12 | } 13 | else 14 | { 15 | a=10; 16 | } 17 | } 18 | else 19 | { 20 | b=2; 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ICG/test7.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=5; 5 | int b=6; 6 | while(a>7) 7 | { 8 | b=6; 9 | while(b>=5) 10 | { 11 | a=9; 12 | } 13 | } 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /ICG/test8.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int d=3; 5 | int a[10]; 6 | int x=a[d-2]; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Lexical Analysis/Lexical Analysis Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivananda199/Mini-C-Compiler/95ccf8af785851899ae5b47ef12e07bfb4298abb/Lexical Analysis/Lexical Analysis Report.pdf -------------------------------------------------------------------------------- /Lexical Analysis/isPrime.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a,i,flag=0; 5 | printf("Input no"); 6 | scanf("%d",&a); 7 | i=2; 8 | while(i <= a/2) 9 | { 10 | if(a%i == 0) 11 | { 12 | flag=1; 13 | break; 14 | } 15 | i++; 16 | } 17 | if(flag==0) 18 | printf("Prime"); 19 | else 20 | printf("Not Prime"); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Lexical Analysis/lexer.l: -------------------------------------------------------------------------------- 1 | %{ 2 | int lineno = 1; 3 | #include 4 | #include 5 | #include 6 | 7 | #define AUTO 1 8 | #define BREAK 2 9 | #define CASE 3 10 | #define CHAR 4 11 | #define CONST 5 12 | #define CONTINUE 6 13 | #define DEFAULT 7 14 | #define DO 8 15 | #define DOUBLE 9 16 | #define ELSE 10 17 | #define ENUM 11 18 | #define EXTERN 12 19 | #define FLOAT 13 20 | #define FOR 14 21 | #define GOTO 15 22 | #define IF 16 23 | #define INT 17 24 | #define LONG 18 25 | #define REGISTER 19 26 | #define RETURN 20 27 | #define SHORT 21 28 | #define SIGNED 22 29 | #define SIZEOF 23 30 | #define STATIC 24 31 | #define STRUCT 25 32 | #define SWITCH 26 33 | #define TYPEDEF 27 34 | #define UNION 28 35 | #define UNSIGNED 29 36 | #define VOID 30 37 | #define VOLATILE 31 38 | #define WHILE 32 39 | 40 | #define IDENTIFIER 33 41 | #define SLC 34 42 | #define MLCS 35 43 | #define MLCE 36 44 | 45 | #define LEQ 37 46 | #define GEQ 38 47 | #define EQEQ 39 48 | #define NEQ 40 49 | #define LOR 41 50 | #define LAND 42 51 | #define ASSIGN 43 52 | #define PLUS 44 53 | #define SUB 45 54 | #define MULT 46 55 | #define DIV 47 56 | #define MOD 48 57 | #define LESSER 49 58 | #define GREATER 50 59 | #define INCR 51 60 | #define DECR 52 61 | 62 | #define COMMA 53 63 | #define SEMI 54 64 | 65 | #define HEADER 55 66 | #define MAIN 56 67 | 68 | #define PRINTF 57 69 | #define SCANF 58 70 | #define DEFINE 59 71 | 72 | #define INT_CONST 60 73 | #define FLOAT_CONST 61 74 | 75 | #define TYPE_SPEC 62 76 | 77 | #define DQ 63 78 | 79 | #define OBO 64 80 | #define OBC 65 81 | #define CBO 66 82 | #define CBC 67 83 | #define HASH 68 84 | 85 | #define ARR 69 86 | #define FUNC 70 87 | 88 | #define NUM_ERR 71 89 | #define UNKNOWN 72 90 | 91 | #define CHAR_CONST 73 92 | #define SIGNED_CONST 74 93 | #define STRING_CONST 75 94 | %} 95 | 96 | alpha [A-Za-z] 97 | digit [0-9] 98 | und [_] 99 | space [ ] 100 | tab [ ] 101 | line [\n] 102 | char \'.\' 103 | at [@] 104 | string \"(.^([%d]|[%f]|[%s]|[%c]))\" 105 | 106 | %% 107 | {space}* {} 108 | {tab}* {} 109 | {string} return STRING_CONST; 110 | {char} return CHAR_CONST; 111 | {line} {lineno++;} 112 | auto return AUTO; 113 | break return BREAK; 114 | case return CASE; 115 | char return CHAR; 116 | const return CONST; 117 | continue return CONTINUE; 118 | default return DEFAULT; 119 | do return DO; 120 | double return DOUBLE; 121 | else return ELSE; 122 | enum return ENUM; 123 | extern return EXTERN; 124 | float return FLOAT; 125 | for return FOR; 126 | goto return GOTO; 127 | if return IF; 128 | int return INT; 129 | long return LONG; 130 | register return REGISTER; 131 | return return RETURN; 132 | short return SHORT; 133 | signed return SIGNED; 134 | sizeof return SIZEOF; 135 | static return STATIC; 136 | struct return STRUCT; 137 | switch return SWITCH; 138 | typedef return TYPEDEF; 139 | union return UNION; 140 | unsigned return UNSIGNED; 141 | void return VOID; 142 | volatile return VOLATILE; 143 | while return WHILE; 144 | 145 | printf return PRINTF; 146 | scanf return SCANF; 147 | 148 | {alpha}({alpha}|{digit}|{und})* return IDENTIFIER; 149 | 150 | [+-][0-9]{digit}*(\.{digit}+)? return SIGNED_CONST; 151 | 152 | "//" return SLC; 153 | "/*" return MLCS; 154 | "*/" return MLCE; 155 | 156 | "<=" return LEQ; 157 | ">=" return GEQ; 158 | "==" return EQEQ; 159 | "!=" return NEQ; 160 | "||" return LOR; 161 | "&&" return LAND; 162 | "=" return ASSIGN; 163 | "+" return PLUS; 164 | "-" return SUB; 165 | "*" return MULT; 166 | "/" return DIV; 167 | "%" return MOD; 168 | "<" return LESSER; 169 | ">" return GREATER; 170 | "++" return INCR; 171 | "--" return DECR; 172 | 173 | "," return COMMA; 174 | ";" return SEMI; 175 | 176 | "#include" return HEADER; 177 | "#include " return HEADER; 178 | "main()" return MAIN; 179 | 180 | {digit}+ return INT_CONST; 181 | ({digit}+)\.({digit}+) return FLOAT_CONST; 182 | 183 | "%d"|"%f"|"%u"|"%s" return TYPE_SPEC; 184 | "\"" return DQ; 185 | "(" return OBO; 186 | ")" return OBC; 187 | "{" return CBO; 188 | "}" return CBC; 189 | "#" return HASH; 190 | 191 | {alpha}({alpha}|{digit}|{und})*\[{digit}*\] return ARR; 192 | {alpha}({alpha}|{digit}|{und})*\(({alpha}|{digit}|{und}|{space})*\) return FUNC; 193 | ({digit}+)\.({digit}+)\.({digit}|\.)* return NUM_ERR; 194 | ({digit}|{at})+({alpha}|{digit}|{und}|{at})* return UNKNOWN; 195 | %% 196 | 197 | struct node 198 | { 199 | char token[100]; 200 | char attr[100]; 201 | struct node *next; 202 | }; 203 | 204 | struct hash 205 | { 206 | struct node *head; 207 | int count; 208 | }; 209 | 210 | struct hash hashTable[1000]; 211 | int eleCount = 1000; 212 | 213 | struct node * createNode(char *token, char *attr) 214 | { 215 | struct node *newnode; 216 | newnode = (struct node *) malloc(sizeof(struct node)); 217 | strcpy(newnode->token, token); 218 | strcpy(newnode->attr, attr); 219 | newnode->next = NULL; 220 | return newnode; 221 | } 222 | 223 | int hashIndex(char *token) 224 | { 225 | int hi=0; 226 | int l,i; 227 | for(i=0;token[i]!='\0';i++) 228 | { 229 | hi = hi + (int)token[i]; 230 | } 231 | hi = hi%eleCount; 232 | return hi; 233 | } 234 | 235 | void insertToHash(char *token, char *attr) 236 | { 237 | int flag=0; 238 | int hi; 239 | hi = hashIndex(token); 240 | struct node *newnode = createNode(token, attr); 241 | /* head of list for the bucket with index "hashIndex" */ 242 | if (hashTable[hi].head==NULL) 243 | { 244 | hashTable[hi].head = newnode; 245 | hashTable[hi].count = 1; 246 | return; 247 | } 248 | struct node *myNode; 249 | myNode = hashTable[hi].head; 250 | while (myNode != NULL) 251 | { 252 | if (strcmp(myNode->token, token)==0) 253 | { 254 | flag = 1; 255 | break; 256 | } 257 | myNode = myNode->next; 258 | } 259 | if(!flag) 260 | { 261 | //adding new node to the list 262 | newnode->next = (hashTable[hi].head); 263 | //update the head of the list and no of nodes in the current bucket 264 | hashTable[hi].head = newnode; 265 | hashTable[hi].count++; 266 | } 267 | return; 268 | } 269 | 270 | void display() 271 | { 272 | struct node *myNode; 273 | int i,j, k=1; 274 | printf("-------------------------------------------------------------------"); 275 | printf("\nSNo \t|\tToken \t\t|\tToken Type \t\n"); 276 | printf("-------------------------------------------------------------------\n"); 277 | for (i = 0; i < eleCount; i++) 278 | { 279 | if (hashTable[i].count == 0) 280 | continue; 281 | myNode = hashTable[i].head; 282 | if (!myNode) 283 | continue; 284 | while (myNode != NULL) 285 | { 286 | printf("%d\t\t", k++); 287 | printf("%s\t\t\t", myNode->token); 288 | printf("%s\t\n", myNode->attr); 289 | myNode = myNode->next; 290 | } 291 | } 292 | return; 293 | } 294 | 295 | int main() 296 | { 297 | int scan, slcline=0, mlc=0, mlcline=0, dq=0, dqline=0; 298 | yyin = fopen("test6.c","r"); 299 | printf("\n\n"); 300 | scan = yylex(); 301 | while(scan) 302 | { 303 | if(lineno == slcline) 304 | { 305 | scan = yylex(); 306 | continue; 307 | } 308 | if(lineno!=dqline && dqline!=0) 309 | { 310 | if(dq%2!=0) 311 | printf("\n******** ERROR!! INCOMPLETE STRING at Line %d ********\n\n", dqline); 312 | dq=0; 313 | } 314 | if((scan>=1 && scan<=32) && mlc==0) 315 | { 316 | printf("%s\t\t\tKEYWORD\t\t\t\tLine %d\n", yytext, lineno); 317 | insertToHash(yytext, "KEYWORD"); 318 | } 319 | if(scan==33 && mlc==0) 320 | { 321 | printf("%s\t\t\tIDENTIFIER\t\t\tLine %d\n", yytext, lineno); 322 | insertToHash(yytext, "IDENTIFIER"); 323 | } 324 | if(scan==34) 325 | { 326 | printf("%s\t\t\tSingleline Comment\t\tLine %d\n", yytext, lineno); 327 | slcline = lineno; 328 | } 329 | if(scan==35 && mlc==0) 330 | { 331 | printf("%s\t\t\tMultiline Comment Start\t\tLine %d\n", yytext, lineno); 332 | mlcline = lineno; 333 | mlc = 1; 334 | } 335 | if(scan==36 && mlc==0) 336 | { 337 | printf("\n******** ERROR!! UNMATCHED MULTILINE COMMENT END %s at Line %d ********\n\n", yytext, lineno); 338 | } 339 | if(scan==36 && mlc==1) 340 | { 341 | mlc = 0; 342 | printf("%s\t\t\tMultiline Comment End\t\tLine %d\n", yytext, lineno); 343 | } 344 | if((scan>=37 && scan<=52) && mlc==0) 345 | { 346 | printf("%s\t\t\tOPERATOR\t\t\tLine %d\n", yytext, lineno); 347 | insertToHash(yytext, "OPERATOR"); 348 | } 349 | if((scan==53||scan==54||scan==63||(scan>=64 && scan<=68)) && mlc==0) 350 | { 351 | printf("%s\t\t\tSPECIAL SYMBOL\t\t\tLine %d\n", yytext, lineno); 352 | if(scan==63) 353 | { 354 | dq++; 355 | dqline = lineno; 356 | } 357 | insertToHash(yytext, "SPECIAL SYMBOL"); 358 | } 359 | if(scan==55 && mlc==0) 360 | { 361 | printf("%s\tHEADER\t\t\t\tLine %d\n",yytext, lineno); 362 | } 363 | if(scan==56 && mlc==0) 364 | { 365 | printf("%s\t\t\tMAIN FUNCTION\t\t\tLine %d\n", yytext, lineno); 366 | insertToHash(yytext, "IDENTIFIER"); 367 | } 368 | if((scan==57 || scan==58) && mlc==0) 369 | { 370 | printf("%s\t\t\tPRE DEFINED FUNCTION\t\tLine %d\n", yytext, lineno); 371 | insertToHash(yytext, "PRE DEFINED FUNCTION"); 372 | } 373 | if(scan==59 && mlc==0) 374 | { 375 | printf("%s\t\t\tPRE PROCESSOR DIRECTIVE\t\tLine %d\n", yytext, lineno); 376 | } 377 | if(scan==60 && mlc==0) 378 | { 379 | printf("%s\t\t\tINTEGER CONSTANT\t\tLine %d\n", yytext, lineno); 380 | insertToHash(yytext, "INTEGER CONSTANT"); 381 | } 382 | if(scan==61 && mlc==0) 383 | { 384 | printf("%s\t\t\tFLOATING POINT CONSTANT\t\tLine %d\n", yytext, lineno); 385 | insertToHash(yytext, "FLOATING POINT CONSTANT"); 386 | } 387 | if(scan==62 && mlc==0) 388 | { 389 | printf("%s\t\t\tTYPE SPECIFIER\t\t\tLine %d\n", yytext, lineno); 390 | } 391 | if(scan==69 && mlc==0) 392 | { 393 | printf("%s\t\t\tARRAY\t\t\t\tLine %d\n", yytext, lineno); 394 | insertToHash(yytext, "ARRAY"); 395 | } 396 | if(scan==70 && mlc==0) 397 | { 398 | printf("%s\t\t\tUSER DEFINED FUNCTION\t\tLine %d\n", yytext, lineno); 399 | insertToHash(yytext, "USER DEFINED FUNCTION"); 400 | } 401 | if(scan==71 && mlc==0) 402 | { 403 | printf("\n******** ERROR!! CONSTANT ERROR %s at Line %d ********\n\n", yytext, lineno); 404 | } 405 | if(scan==72 && mlc==0) 406 | { 407 | printf("\n******** ERROR!! UNKNOWN TOKEN %s at Line %d ********\n\n", yytext, lineno); 408 | } 409 | if(scan==73 && mlc==0) 410 | { 411 | printf("%s\t\t\tCHARACTER CONSTANT\t\t\tLine %d\n", yytext, lineno); 412 | insertToHash(yytext, "CHARACTER CONSTANT"); 413 | } 414 | if(scan==74 && mlc==0) 415 | { 416 | printf("%s\t\t\tSIGNED CONSTANT\t\t\tLine %d\n", yytext, lineno); 417 | insertToHash(yytext, "SIGNED CONSTANT"); 418 | } 419 | if(scan==75 && mlc==0) 420 | { 421 | printf("%s\t\t\tSTRING CONSTANT\t\t\tLine %d\n", yytext, lineno); 422 | insertToHash(yytext, "STRING CONSTANT"); 423 | } 424 | scan = yylex(); 425 | } 426 | if(mlc==1) 427 | printf("\n******** ERROR!! UNMATCHED COMMENT STARTING at Line %d ********\n\n",mlcline); 428 | printf("\n"); 429 | printf("\n\t******** SYMBOL TABLE ********\t\t\n"); 430 | display(); 431 | printf("-------------------------------------------------------------------\n\n"); 432 | } 433 | int yywrap() 434 | { 435 | return 1; 436 | } 437 | -------------------------------------------------------------------------------- /Lexical Analysis/test1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define x 3 3 | void main() 4 | { 5 | int a=3; 6 | float b=5.6; 7 | while(a<20) 8 | { 9 | a = a + 1; 10 | printf(“%d”, a); 11 | } 12 | a++; 13 | } 14 | -------------------------------------------------------------------------------- /Lexical Analysis/test2.c: -------------------------------------------------------------------------------- 1 | #include 2 | void main() 3 | { 4 | signed int a = -2; 5 | //Single line comment 6 | printf("%d\n", a); 7 | /* Multiline 8 | comment */ 9 | } 10 | -------------------------------------------------------------------------------- /Lexical Analysis/test3.c: -------------------------------------------------------------------------------- 1 | #include 2 | void main() 3 | { 4 | int a=5; 5 | //identifier rule broken 6 | float 3b = 9.5; 7 | } 8 | -------------------------------------------------------------------------------- /Lexical Analysis/test4.c: -------------------------------------------------------------------------------- 1 | #include 2 | void main() 3 | { 4 | int a=2; 5 | /*Unmatched 6 | /*Multiline*/ 7 | comment*/ 8 | } 9 | -------------------------------------------------------------------------------- /Lexical Analysis/test5.c: -------------------------------------------------------------------------------- 1 | #include 2 | void foo() 3 | { 4 | return; 5 | } 6 | void main() 7 | { 8 | int a; 9 | foo(); 10 | //user defined function 11 | } 12 | -------------------------------------------------------------------------------- /Lexical Analysis/test6.c: -------------------------------------------------------------------------------- 1 | #include 2 | void main() 3 | { 4 | int a = 8; 5 | float b = 9.5.7; 6 | //constant error 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mini C Compiler 2 | The project aims to build a mini compiler for C language 3 | #### The project team: 4 | * Shivananda D (15CO148) 5 | * Yeshwanth R (15CO154) 6 | 7 | The front-end of compiler consisting of the following four phases is built: 8 | 1) Lexical Analysis 9 | 2) Syntax Analysis 10 | 3) Semantic Analysis 11 | 4) Intermediate Code Generation 12 | -------------------------------------------------------------------------------- /Semantic Analysis/Semantic Analysis Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivananda199/Mini-C-Compiler/95ccf8af785851899ae5b47ef12e07bfb4298abb/Semantic Analysis/Semantic Analysis Report.pdf -------------------------------------------------------------------------------- /Semantic Analysis/parser.l: -------------------------------------------------------------------------------- 1 | %{ 2 | int yylineno; 3 | %} 4 | 5 | alpha [A-Za-z] 6 | digit [0-9] 7 | und [_] 8 | 9 | %% 10 | [ \t] ; 11 | \n {yylineno++;} 12 | "{" {push(); return '{';} 13 | "}" {pop(); return '}';} 14 | ";" { return(';'); } 15 | "," { return(','); } 16 | ":" { return(':'); } 17 | "=" { return('='); } 18 | "(" { return('('); } 19 | ")" { return(')'); } 20 | ("[") { return('['); } 21 | ("]") { return(']'); } 22 | "." { return('.'); } 23 | "&" { return('&'); } 24 | "!" { return('!'); } 25 | "~" { return('~'); } 26 | "-" { return('-'); } 27 | "+" { return('+'); } 28 | "*" { return('*'); } 29 | "/" { return('/'); } 30 | "%" { return('%'); } 31 | "<" { return('<'); } 32 | ">" { return('>'); } 33 | "^" { return('^'); } 34 | "|" { return('|'); } 35 | "?" { return('?'); } 36 | int {yylval.ival = INT; return INT;} 37 | float {yylval.ival = FLOAT; return FLOAT;} 38 | void {yylval.ival = VOID; return VOID;} 39 | else {return ELSE;} 40 | do {return DO;} 41 | if {return IF;} 42 | for {return FOR;} 43 | struct {return STRUCT;} 44 | ^"#include ".+ return PREPROC; 45 | while return WHILE; 46 | return return RETURN; 47 | printf return PRINT; 48 | {alpha}({alpha}|{digit}|{und})* {yylval.str=strdup(yytext); return ID;} 49 | {digit}+ {yylval.str=strdup(yytext);return NUM;} 50 | {digit}+\.{digit}+ {yylval.str=strdup(yytext); return REAL;} 51 | "<=" return LE; 52 | ">=" return GE; 53 | "==" return EQ; 54 | "!=" return NE; 55 | "++" return INC; 56 | "--" return DEC; 57 | \/\/.* ; 58 | \/\*(.*\n)*.*\*\/ ; 59 | \".*\" return STRING; 60 | . return yytext[0]; 61 | %% 62 | -------------------------------------------------------------------------------- /Semantic Analysis/parser.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include 5 | #include "symbolTable.c" 6 | int i=1,k=-1,l=-1; 7 | int j=0; 8 | char curfunc[100]; 9 | int stack[100]; 10 | int top=0; 11 | int plist[100],flist[100]; 12 | int end[100]; 13 | int arr[10]; 14 | int ct=0,c=0,b; 15 | int loop = 0; 16 | int errc=0; 17 | int type=0; 18 | extern int yylineno; 19 | %} 20 | 21 | %token INT FLOAT VOID 22 | %token ID NUM REAL 23 | %token WHILE IF RETURN PREPROC LE STRING PRINT FUNCTION DO ARRAY ELSE STRUCT STRUCT_VAR FOR GE EQ NE INC DEC 24 | %right '=' 25 | 26 | %type assignment assignment1 consttype assignment2 27 | %type Type 28 | 29 | %union 30 | { 31 | int ival; 32 | char *str; 33 | } 34 | 35 | %% 36 | 37 | start : Function start 38 | | PREPROC start 39 | | Declaration start 40 | | 41 | ; 42 | 43 | Function : Type ID '('')' CompoundStmt { 44 | if ($1!=returntype_func(ct)) 45 | { 46 | printf("\nError : Type mismatch : Line %d\n",printline()); errc++; 47 | } 48 | 49 | if (!(strcmp($2,"printf") && strcmp($2,"scanf") && strcmp($2,"getc") && strcmp($2,"gets") && strcmp($2,"getchar") && strcmp ($2,"puts") && strcmp($2,"putchar") && strcmp($2,"clearerr") && strcmp($2,"getw") && strcmp($2,"putw") && strcmp($2,"putc") && strcmp($2,"rewind") && strcmp($2,"sprint") && strcmp($2,"sscanf") && strcmp($2,"remove") && strcmp($2,"fflush"))) 50 | {printf("Error : Redeclaration of %s : Line %d\n",$2,printline()); errc++;} 51 | else 52 | { 53 | insert($2,FUNCTION); 54 | insert($2,$1); 55 | } 56 | } 57 | | Type ID '(' parameter_list ')' CompoundStmt { 58 | if ($1!=returntype_func(ct)) 59 | { 60 | printf("\nError : Type mismatch : Line %d\n",printline()); errc++; 61 | } 62 | 63 | if (!(strcmp($2,"printf") && strcmp($2,"scanf") && strcmp($2,"getc") && strcmp($2,"gets") && strcmp($2,"getchar") && strcmp ($2,"puts") && strcmp($2,"putchar") && strcmp($2,"clearerr") && strcmp($2,"getw") && strcmp($2,"putw") && strcmp($2,"putc") && strcmp($2,"rewind") && strcmp($2,"sprint") && strcmp($2,"sscanf") && strcmp($2,"remove") && strcmp($2,"fflush"))) 64 | {printf("Error : Redeclaration of %s : Line %d\n",$2,printline());errc++;} 65 | else 66 | { 67 | insert($2,FUNCTION); 68 | insert($2,$1); 69 | for(j=0;j<=k;j++) 70 | {insertp($2,plist[j]);} 71 | k=-1; 72 | } 73 | } 74 | ; 75 | 76 | parameter_list : parameter_list ',' parameter 77 | | parameter 78 | ; 79 | 80 | parameter : Type ID {plist[++k]=$1;insert($2,$1);insertscope($2,i);} 81 | ; 82 | 83 | Type : INT 84 | | FLOAT 85 | | VOID 86 | ; 87 | 88 | CompoundStmt : '{' StmtList '}' 89 | ; 90 | 91 | StmtList : StmtList stmt 92 | | CompoundStmt 93 | | 94 | ; 95 | 96 | stmt : Declaration 97 | | if 98 | | for 99 | | while 100 | | dowhile 101 | | RETURN consttype ';' { 102 | 103 | if(!(strspn($2,"0123456789")==strlen($2))) 104 | storereturn(ct,FLOAT); 105 | else 106 | storereturn(ct,INT); 107 | ct++; 108 | } 109 | | RETURN ';' {storereturn(ct,VOID); ct++;} 110 | | RETURN ID ';' { 111 | int sct=returnscope($2,stack[top-1]); //stack[top-1] - current scope 112 | int type=returntype($2,sct); 113 | if (type==259) storereturn(ct,FLOAT); 114 | else storereturn(ct,INT); 115 | ct++; 116 | } 117 | | ';' 118 | | PRINT '(' STRING ')' ';' 119 | | CompoundStmt 120 | ; 121 | 122 | dowhile : DO CompoundStmt WHILE '(' expr1 ')' ';' 123 | ; 124 | 125 | if : IF '(' expr1 ')' CompoundStmt 126 | | IF '(' expr1 ')' CompoundStmt ELSE CompoundStmt 127 | ; 128 | 129 | for : FOR '(' expr1 ';' expr1 ';' expr1 ')' '{' {loop=1;} StmtList {loop=0;} '}' 130 | ; 131 | 132 | while : WHILE '(' expr1 ')' '{' {loop=1;} StmtList {loop=0;} '}' 133 | ; 134 | 135 | expr1 : expr1 LE expr1 136 | | expr1 GE expr1 137 | | expr1 NE expr1 138 | | expr1 EQ expr1 139 | | expr1 INC 140 | | expr1 DEC 141 | | expr1 '>' expr1 142 | | expr1 '<' expr1 143 | | assignment1 144 | ; 145 | 146 | assignment : ID '=' consttype 147 | | ID '+' assignment 148 | | ID ',' assignment 149 | | consttype ',' assignment 150 | | ID 151 | | consttype 152 | ; 153 | 154 | assignment1 : ID '=' assignment1 155 | { 156 | int sct=returnscope($1,stack[top-1]); 157 | int type=returntype($1,sct); 158 | if((!(strspn($3,"0123456789")==strlen($3))) && type==258) 159 | {printf("\nError : Type Mismatch : Line %d\n",printline()); errc++;} 160 | else if (type==273) {printf("\nError : Type Mismatch : Line %d\n",printline());errc++;} 161 | if(!lookup($1)) 162 | { 163 | int currscope=stack[top-1]; 164 | int scope=returnscope($1,currscope); 165 | if((scope<=currscope && end[scope]==0) && !(scope==0)) 166 | check_scope_update($1,$3,currscope); 167 | } 168 | } 169 | 170 | | ID ',' assignment1 171 | { 172 | if(lookup($1)) 173 | printf("\nUndeclared Variable %s : Line %d\n",$1,printline()); errc++; 174 | } 175 | | assignment2 176 | | consttype ',' assignment1 177 | | ID 178 | { 179 | if(lookup($1)) 180 | { printf("\nUndeclared Variable %s : Line %d\n",$1,printline()); errc++; } 181 | } 182 | | ID '=' ID '(' paralist ')' //function call 183 | { 184 | int sct=returnscope($1,stack[top-1]); 185 | int type=returntype($1,sct); 186 | //printf("%s",$3); 187 | int rtype; 188 | rtype=returntypef($3); int ch=0; 189 | //printf("%d",rtype); 190 | if(rtype!=type) 191 | { printf("\nError : Type Mismatch : Line %d\n",printline()); errc++;} 192 | if(!lookup($1)) 193 | { 194 | for(j=0;j<=l;j++) 195 | {ch = ch+checkp($3,flist[j],j);} 196 | if(ch>0) { printf("\nError : Parameter Type Mistake or Function undeclared : Line %d\n",printline()); errc++;} 197 | l=-1; 198 | } 199 | } 200 | | ID '(' paralist ')' //function call without assignment 201 | { 202 | int sct=returnscope($1,stack[top-1]); 203 | int type=returntype($1,sct); int ch=0; 204 | if(!lookup($1)) 205 | { 206 | for(j=0;j<=l;j++) 207 | {ch = ch+checkp($1,flist[j],j);} 208 | if(ch>0) { printf("\nError : Parameter Type Mistake or Required Function undeclared : Line %d\n",printline()); errc++;} 209 | l=-1; 210 | } 211 | else {printf("\nUndeclared Function %s : Line %d\n",$1,printline());errc++;} 212 | } 213 | /* | ID '[' ID ']' '=' ID 214 | { 215 | int sct=returnscope($1,stack[top-1]); 216 | int itype=returntype($3,sct); 217 | int type=returntype2($1,sct); int ch=0; 218 | int rtype=returntype($6,sct); 219 | if(itype!=258) 220 | { printf("\nError : Array index must be of type int : Line %d\n",printline());errc++;} 221 | if(rtype!=type) 222 | { printf("\nError : Type Mismatch : Line %d\n",printline()); errc++;} 223 | }*/ 224 | | consttype 225 | ; 226 | 227 | paralist : paralist ',' param 228 | | param 229 | ; 230 | 231 | param : ID 232 | { 233 | if(lookup($1)) 234 | {printf("\nUndeclared Variable %s : Line %d\n",$1,printline());errc++;} 235 | else 236 | { 237 | int sct=returnscope($1,stack[top-1]); 238 | flist[++l]=returntype($1,sct); 239 | } 240 | } 241 | ; 242 | 243 | assignment2 : ID '=' exp {c=0;} 244 | | ID '=' '(' exp ')' 245 | ; 246 | 247 | exp : ID 248 | { 249 | if(c==0) //check compatibility of mathematical operations 250 | { 251 | c=1; 252 | int sct=returnscope($1,stack[top-1]); 253 | b=returntype($1,sct); 254 | } 255 | else 256 | { 257 | int sct1=returnscope($1,stack[top-1]); 258 | if(b!=returntype($1,sct1)){} 259 | {printf("\nError : Type Mismatch : Line %d\n",printline());errc++;} 260 | } 261 | } 262 | | exp '+' exp 263 | | exp '-' exp 264 | | exp '*' exp 265 | | exp '/' exp 266 | | '(' exp '+' exp ')' 267 | | '(' exp '-' exp ')' 268 | | '(' exp '*' exp ')' 269 | | '(' exp '/' exp ')' 270 | | consttype 271 | ; 272 | 273 | consttype : NUM 274 | | REAL 275 | ; 276 | 277 | Declaration : Type ID '=' consttype ';' 278 | { 279 | if( (!(strspn($4,"0123456789")==strlen($4))) && $1==258) 280 | {printf("\nError : Type Mismatch : Line %d\n",printline());errc++;} 281 | else if ($1==273) {printf("\nError : Type Mismatch : Line %d\n",printline());errc++;} 282 | if(!lookup($2)) 283 | { 284 | int currscope=stack[top-1]; 285 | int previous_scope=returnscope($2,currscope); 286 | if(currscope==previous_scope) 287 | {printf("\nError : Redeclaration of %s : Line %d\n",$2,printline());errc++;} 288 | else 289 | { 290 | insert_dup($2,$1,currscope); 291 | check_scope_update($2,$4,stack[top-1]); 292 | } 293 | } 294 | else 295 | { 296 | int scope=stack[top-1]; 297 | insert($2,$1); 298 | insertscope($2,scope); 299 | check_scope_update($2,$4,stack[top-1]); 300 | } 301 | } 302 | | assignment1 ';' 303 | { 304 | if(!lookup($1)) 305 | { 306 | int currscope=stack[top-1]; 307 | int scope=returnscope($1,currscope); 308 | int type=returntype($1,scope); 309 | if(!(scope<=currscope && end[scope]==0) || scope==0 && type!=271) 310 | {printf("\nError : Variable %s out of scope : Line %d\n",$1,printline());errc++;} 311 | } 312 | else 313 | {printf("\nError : Undeclared Variable %s : Line %d\n",$1,printline());errc++;} 314 | } 315 | | Type ID ';' 316 | { 317 | if(!lookup($2)) 318 | { 319 | int currscope=stack[top-1]; 320 | int previous_scope=returnscope($2,currscope); 321 | if(currscope==previous_scope) 322 | {printf("\nError : Redeclaration of %s : Line %d\n",$2,printline());errc++;} 323 | else 324 | { 325 | insert_dup($2,$1,currscope); 326 | //check_scope_update($2,$4,stack[top-1]); 327 | } 328 | } 329 | else 330 | { 331 | int scope=stack[top-1]; 332 | //printf("%d",type); 333 | insert($2,$1); 334 | insertscope($2,scope); 335 | //check_scope_update($2,$4,stack[top-1]); 336 | } 337 | } 338 | | Type ID '[' assignment ']' ';' { 339 | int itype; 340 | if(!(strspn($4,"0123456789")==strlen($4))) { itype=259; } else itype = 258; 341 | if(itype!=258) 342 | { printf("\nError : Array index must be of type int : Line %d\n",printline());errc++;} 343 | if(atoi($4)<=0) 344 | { printf("\nError : Array index must be of type int > 0 : Line %d\n",printline());errc++;} 345 | if(!lookup($2)) 346 | { 347 | int currscope=stack[top-1]; 348 | int previous_scope=returnscope($2,currscope); 349 | if(currscope==previous_scope) 350 | {printf("\nError : Redeclaration of %s : Line %d\n",$2,printline());errc++;} 351 | else 352 | { 353 | 354 | insert_dup($2,ARRAY,currscope); 355 | insert_by_scope($2,$1,currscope); //to insert type to the correct identifier in case of multiple entries of the identifier by using scope 356 | if (itype==258) {insert_index($2,$4);} 357 | } 358 | } 359 | else 360 | { 361 | int scope=stack[top-1]; 362 | insert($2,ARRAY); 363 | insert($2,$1); 364 | insertscope($2,scope); 365 | if (itype==258) {insert_index($2,$4);} 366 | } 367 | 368 | } 369 | | STRUCT ID '{' Declaration '}' ';' { 370 | insert($2,STRUCT); 371 | } 372 | | STRUCT ID ID ';' { 373 | insert($3,STRUCT_VAR); 374 | } 375 | | error 376 | ; 377 | 378 | 379 | 380 | %% 381 | 382 | #include "lex.yy.c" 383 | #include 384 | int main(int argc, char *argv[]) 385 | { 386 | yyin =fopen(argv[1],"r"); 387 | if(!yyparse()&& errc<=0) 388 | { 389 | printf("\nParsing Completed\n"); 390 | display(); 391 | } 392 | else 393 | { 394 | printf("\nParsing Failed\n"); 395 | display(); 396 | } 397 | fclose(yyin); 398 | return 0; 399 | } 400 | 401 | yyerror(char *s) 402 | { 403 | printf("\nLine %d : %s %s\n",yylineno,s,yytext); 404 | } 405 | 406 | int printline() 407 | { 408 | return yylineno; 409 | } 410 | void push() 411 | { 412 | stack[top]=i; 413 | i++; 414 | top++; 415 | return; 416 | } 417 | void pop() 418 | { 419 | top--; 420 | end[stack[top]]=1; 421 | stack[top]=0; 422 | return; 423 | } 424 | -------------------------------------------------------------------------------- /Semantic Analysis/symbolTable.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | struct sym 4 | { 5 | int sno; 6 | char token[100]; 7 | int type[100]; 8 | int paratype[100]; 9 | int tn; 10 | int pn; 11 | float fvalue; 12 | int index; 13 | int scope; 14 | }st[100]; 15 | int n=0,arr[10]; 16 | int tnp; 17 | 18 | int returntype_func(int ct) 19 | { 20 | return arr[ct-1]; 21 | } 22 | void storereturn( int ct, int returntype ) 23 | { 24 | arr[ct] = returntype; 25 | return; 26 | } 27 | void insertscope(char *a,int s) 28 | { 29 | int i; 30 | for(i=0;i=st[i].scope) 46 | { 47 | if(st[i].scope>=max) 48 | max = st[i].scope; 49 | } 50 | } 51 | return max; 52 | } 53 | int lookup(char *a) 54 | { 55 | int i; 56 | for(i=0;i=st[i].scope) 101 | { 102 | if(st[i].scope>=max) 103 | max=st[i].scope; 104 | } 105 | } 106 | for(i=0;i<=n;i++) 107 | { 108 | if(!strcmp(a,st[i].token) && max==st[i].scope) 109 | { 110 | float temp=atof(b); 111 | for(k=0;k1 && j<(st[i].tn-1))printf(" - "); 254 | } 255 | printf("\t\t"); 256 | for(j=0;j1 && j<(st[i].pn-1))printf(", "); 263 | } 264 | printf("\n"); 265 | } 266 | printf("------------------------------------------------------------------------------------------------------------------------------\n\n"); 267 | return; 268 | } 269 | -------------------------------------------------------------------------------- /Semantic Analysis/test1.c: -------------------------------------------------------------------------------- 1 | //no error 2 | #include 3 | 4 | int foo(int a) 5 | { 6 | a=a+1; 7 | return a; 8 | } 9 | 10 | void main() 11 | { 12 | int a,b,c; 13 | int b; 14 | b=5; 15 | int c; 16 | c=foo(b); 17 | return; 18 | } 19 | -------------------------------------------------------------------------------- /Semantic Analysis/test2.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=4; 5 | b=9; //undeclared variable 6 | a=10; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Semantic Analysis/test3.c: -------------------------------------------------------------------------------- 1 | #include 2 | void main() 3 | { 4 | int a[0]; //array index error (has to be greater than zero) 5 | int b[8.5]; //array index cannot be a float value 6 | int c=5; 7 | float d; 8 | int i; 9 | int c=3; //redeclaration of variable 'c' 10 | int sum; 11 | sum=0; 12 | 13 | for(i=0;i<12;i++) 14 | { 15 | sum=sum+i; 16 | } 17 | return; 18 | } 19 | -------------------------------------------------------------------------------- /Semantic Analysis/test4.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=4; 5 | int b=5; 6 | { 7 | int d=56; 8 | } 9 | int sum; 10 | sum=a+b; 11 | { 12 | int d=20; 13 | } 14 | foo(); 15 | d=89; //variable 'd' out of scope 16 | } 17 | -------------------------------------------------------------------------------- /Semantic Analysis/test5.c: -------------------------------------------------------------------------------- 1 | #include 2 | int foo(int a) 3 | { 4 | float s; 5 | return s; //return type mismatch 6 | } 7 | int sum(int b,int c) 8 | { 9 | int s; 10 | s=b+c; 11 | return s; 12 | } 13 | void main() 14 | { 15 | int p=3; 16 | int q=4; 17 | float f=4.5; 18 | int d; 19 | d=sum(p,f); //parameter type mismatch 20 | return; 21 | } 22 | -------------------------------------------------------------------------------- /Semantic Analysis/test6.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a=5; 5 | return 0; 6 | } 7 | void scanf() //error - standard function redeclared 8 | { 9 | return; 10 | } 11 | -------------------------------------------------------------------------------- /Semantic Analysis/test7.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | int a = 5.4; //type mismatch 5 | int b=67; 6 | float f=6.7; 7 | b=f; //type mismatch (int = float) 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Syntax Analysis/Readme.txt: -------------------------------------------------------------------------------- 1 | Syntax Analysis Phase 2 | 3 | Output: Syntax errors with line numbers 4 | 5 | Steps to Compile & Run 6 | 1) lex parser.l 7 | 2) yacc parser.y 8 | 3) gcc y.tab.c -ll -w 9 | 4) ./a.out test1.c 10 | -------------------------------------------------------------------------------- /Syntax Analysis/Synatx Analysis Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivananda199/Mini-C-Compiler/95ccf8af785851899ae5b47ef12e07bfb4298abb/Syntax Analysis/Synatx Analysis Report.pdf -------------------------------------------------------------------------------- /Syntax Analysis/parser.l: -------------------------------------------------------------------------------- 1 | 2 | alpha [A-Za-z_] 3 | fl (f|F|l|L) 4 | ul (u|U|l|L)* 5 | digit [0-9] 6 | space [ ] 7 | hex [a-fA-F0-9] 8 | exp [Ee][+-]?{digit}+ 9 | 10 | %{ 11 | //int yylineno = 1; 12 | char datatype[100] = "dummy"; 13 | int tl; 14 | char next; 15 | #include 16 | #include 17 | %} 18 | 19 | %% 20 | \n { yylineno++; } 21 | "/*" { multicomment(); } 22 | "//" { singlecomment(); } 23 | 24 | "#include<"({alpha})*".h>" {} 25 | 26 | "#define"({space})""({alpha})""({alpha}|{digit})*""({space})""({digit})+"" { return DEFINE;} 27 | "#define"({space})""({alpha}({alpha}|{digit})*)""({space})""(({digit}+)\.({digit}+))"" { return DEFINE;} 28 | "#define"({space})""({alpha}({alpha}|{digit})*)""({space})""({alpha}({alpha}|{digit})*)"" { return DEFINE;} 29 | 30 | {digit}+ { insertToConstTable(yytext, yylineno, "INT"); return CONSTANT; } 31 | ({digit}+)\.({digit}+) { insertToConstTable(yytext, yylineno, "FLOAT"); return CONSTANT; } 32 | 0[xX]{hex}+{ul}? { insertToConstTable(yytext, yylineno, "FLOAT"); return CONSTANT; } 33 | {digit}+{ul}? { insertToConstTable(yytext, yylineno, "FLOAT"); return CONSTANT; } 34 | '(\\.|[^\\'])+' { insertToConstTable(yytext, yylineno, "FLOAT"); return CONSTANT; } 35 | {digit}+{exp}{fl}? { insertToConstTable(yytext, yylineno, "FLOAT"); return CONSTANT; } 36 | {digit}*"."{digit}+({exp})?{fl}? { insertToConstTable(yytext, yylineno, "FLOAT"); return CONSTANT; } 37 | {digit}+"."{digit}*({exp})?{fl}? { insertToConstTable(yytext, yylineno, "FLOAT"); return CONSTANT; } 38 | 39 | {alpha}?\"(\\.|[^\\"])*\" { insertToConstTable(yytext, yylineno, "STRING"); return STRING_LITERAL; } 40 | 41 | "->" { return PTR_OP; } 42 | "++" { return INC_OP; } 43 | "--" { return DEC_OP; } 44 | "<<" { return LEFT_OP; } 45 | ">>" { return RIGHT_OP; } 46 | "<=" { return LE_OP; } 47 | ">=" { return GE_OP; } 48 | "==" { return EQ_OP; } 49 | "!=" { return NE_OP; } 50 | "&&" { return AND_OP; } 51 | "||" { return OR_OP; } 52 | "*=" { return MUL_ASSIGN; } 53 | "/=" { return DIV_ASSIGN; } 54 | "%=" { return MOD_ASSIGN; } 55 | "+=" { return ADD_ASSIGN; } 56 | "-=" { return SUB_ASSIGN; } 57 | "<<=" { return LEFT_ASSIGN; } 58 | ">>=" { return RIGHT_ASSIGN; } 59 | "&=" { return AND_ASSIGN; } 60 | "^=" { return XOR_ASSIGN; } 61 | "|=" { return OR_ASSIGN; } 62 | 63 | "auto" { return AUTO; } 64 | "break" { return BREAK; } 65 | "case" { return CASE; } 66 | "char" { return CHAR; } 67 | "const" { return CONST; } 68 | "continue" { return CONTINUE; } 69 | "default" { return DEFAULT; } 70 | "do" { return DO; } 71 | "double" { return DOUBLE; } 72 | "else" { return ELSE; } 73 | "enum" { return ENUM; } 74 | "extern" { return EXTERN; } 75 | "float" { strcpy(datatype, "FLOAT"); tl = yylineno; return FLOAT; } 76 | "for" { return FOR; } 77 | "goto" { return GOTO; } 78 | "if" { return IF; } 79 | "int" { strcpy(datatype, "INT"); tl = yylineno; return INT; } 80 | "long" { return LONG; } 81 | "register" { return REGISTER; } 82 | "return" { return RETURN; } 83 | "short" { return SHORT; } 84 | "signed" { return SIGNED; } 85 | "sizeof" { return SIZEOF; } 86 | "static" { return STATIC; } 87 | "struct" { return STRUCT; } 88 | "switch" { return SWITCH; } 89 | "typedef" { return TYPEDEF; } 90 | "union" { return UNION; } 91 | "unsigned" { return UNSIGNED; } 92 | "void" { return VOID; } 93 | "volatile" { return VOLATILE; } 94 | "while" { return WHILE; } 95 | 96 | 97 | ";" { strcpy(datatype, "dummy"); return(';'); } 98 | ("{"|"<%") { return('{'); } 99 | ("}"|"%>") { return('}'); } 100 | "," { return(','); } 101 | ":" { return(':'); } 102 | "=" { return('='); } 103 | "(" { return('('); } 104 | ")" { return(')'); } 105 | ("["|"<:") { return('['); } 106 | ("]"|":>") { return(']'); } 107 | "." { return('.'); } 108 | "&" { return('&'); } 109 | "!" { return('!'); } 110 | "~" { return('~'); } 111 | "-" { return('-'); } 112 | "+" { return('+'); } 113 | "*" { return('*'); } 114 | "/" { return('/'); } 115 | "%" { return('%'); } 116 | "<" { return('<'); } 117 | ">" { return('>'); } 118 | "^" { return('^'); } 119 | "|" { return('|'); } 120 | "?" { return('?'); } 121 | "printf"|"scanf" { insertToHash(yytext,"PROCEDURE",yylineno); return IDENTIFIER; } 122 | "main" { insertToHash(yytext,"PROCEDURE",yylineno); return IDENTIFIER; } 123 | {alpha}({alpha}|{digit})* { 124 | if(strcmp(datatype, "dummy")==0) 125 | return IDENTIFIER; 126 | else 127 | { 128 | insertToHash(yytext,datatype,yylineno); 129 | return IDENTIFIER; 130 | } 131 | } 132 | [ \t\v\n\f] { } 133 | . { /* ignore bad characters */ } 134 | %% 135 | 136 | struct cnode 137 | { 138 | char num[50]; 139 | //int lno; 140 | char type[20]; 141 | }; 142 | struct cnode ctable[100]; 143 | int ccount = 0; 144 | 145 | void insertToConstTable(char *num, int l, char *type) 146 | { 147 | strcpy(ctable[ccount].num, num); 148 | strcpy(ctable[ccount].type, type); 149 | //ctable[ccount].lno = l; 150 | ccount++; 151 | } 152 | 153 | void disp() 154 | { 155 | int i; 156 | printf("\n\n------------------------------CONSTANT TABLE------------------------------\n"); 157 | printf("--------------------------------------------------------------------------\n"); 158 | printf("Value \t\t|\tData Type\t\t\n"); 159 | printf("--------------------------------------------------------------------------\n"); 160 | for(i=0;itoken, token); 192 | strcpy(newnode->attr, attr); 193 | //newnode->line[0] = l; 194 | newnode->line_count = 1; 195 | newnode->next = NULL; 196 | return newnode; 197 | } 198 | 199 | int hashIndex(char *token) 200 | { 201 | int hi=0; 202 | int l,i; 203 | for(i=0;token[i]!='\0';i++) 204 | { 205 | hi = hi + (int)token[i]; 206 | } 207 | hi = hi%eleCount; 208 | return hi; 209 | } 210 | 211 | void insertToHash(char *token, char *attr, int l) 212 | { 213 | int flag=0; 214 | int hi; 215 | hi = hashIndex(token); 216 | struct node *newnode = createNode(token, attr, l); 217 | /* head of list for the bucket with index "hashIndex" */ 218 | if (hashTable[hi].head==NULL) 219 | { 220 | hashTable[hi].head = newnode; 221 | hashTable[hi].hash_count = 1; 222 | return; 223 | } 224 | struct node *myNode; 225 | myNode = hashTable[hi].head; 226 | while (myNode != NULL) 227 | { 228 | if (strcmp(myNode->token, token)==0) 229 | { 230 | flag = 1; 231 | //myNode->line[(myNode->line_count)++] = l; 232 | if(strcmp(myNode->attr, attr)!=0) 233 | { 234 | strcpy(myNode->attr, attr); 235 | } 236 | break; 237 | } 238 | myNode = myNode->next; 239 | } 240 | if(!flag) 241 | { 242 | //adding new node to the list 243 | newnode->next = (hashTable[hi].head); 244 | //update the head of the list and no of nodes in the current bucket 245 | hashTable[hi].head = newnode; 246 | hashTable[hi].hash_count++; 247 | } 248 | return; 249 | } 250 | 251 | void display() 252 | { 253 | struct node *myNode; 254 | int i,j, k=1; 255 | printf("\n-----------------------------------------Symbol Table---------------------------------------------\n"); 256 | printf("--------------------------------------------------------------------------------------------------"); 257 | printf("\nToken \t\t|\tToken Type \t\t\t\t\t \n"); 258 | printf("--------------------------------------------------------------------------------------------------\n"); 259 | for (i = 0; i < eleCount; i++) 260 | { 261 | if (hashTable[i].hash_count == 0) 262 | continue; 263 | myNode = hashTable[i].head; 264 | if (!myNode) 265 | continue; 266 | while (myNode != NULL) 267 | { 268 | //printf("%d\t\t", k++); 269 | printf("%s\t\t\t", myNode->token); 270 | printf("%s\t\t\t", myNode->attr); 271 | /*for(j=0;j<(myNode->line_count);j++) 272 | printf("%d ",myNode->line[j]);*/ 273 | printf("\n"); 274 | myNode = myNode->next; 275 | } 276 | } 277 | printf("--------------------------------------------------------------------------------------------------\n"); 278 | return; 279 | } 280 | 281 | yywrap() 282 | { 283 | return(1); 284 | } 285 | multicomment() 286 | { 287 | char c, c1; 288 | while ((c = input()) != '*' && c != 0); 289 | c1=input(); 290 | if(c=='*' && c1=='/') 291 | { 292 | c=0; 293 | } 294 | if (c != 0) 295 | putchar(c1); 296 | } 297 | singlecomment() 298 | { 299 | char c; 300 | while(c=input()!='\n'); 301 | if(c=='\n') 302 | c=0; 303 | if(c!=0) 304 | putchar(c); 305 | } 306 | -------------------------------------------------------------------------------- /Syntax Analysis/parser.y: -------------------------------------------------------------------------------- 1 | %{ 2 | int yylineno; 3 | char data_type[200]; 4 | %} 5 | 6 | %expect 19 7 | 8 | %name parse 9 | %nonassoc NO_ELSE 10 | %nonassoc ELSE 11 | %left '<' '>' '=' GE_OP LE_OP EQ_OP NE_OP 12 | %left '+' '-' 13 | %left '*' '/' '%' 14 | %left '|' 15 | %left '&' 16 | %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF 17 | %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP 18 | %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN 19 | %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN 20 | %token XOR_ASSIGN OR_ASSIGN DEFINE 21 | %token TYPEDEF EXTERN STATIC AUTO REGISTER 22 | %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID 23 | %token STRUCT UNION ENUM 24 | %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN 25 | %start begin 26 | 27 | %union{ 28 | char str[1000]; 29 | } 30 | 31 | %% 32 | 33 | begin 34 | : external_declaration 35 | | begin external_declaration 36 | | Define begin 37 | ; 38 | 39 | primary_expression 40 | : IDENTIFIER { insertToHash($1, data_type , yylineno); } 41 | | CONSTANT 42 | | STRING_LITERAL 43 | | '(' expression ')' 44 | ; 45 | 46 | Define 47 | : DEFINE 48 | ; 49 | 50 | postfix_expression 51 | : primary_expression 52 | | postfix_expression '[' expression ']' 53 | | postfix_expression '(' ')' 54 | | postfix_expression '(' argument_expression_list ')' 55 | | postfix_expression '.' IDENTIFIER 56 | | postfix_expression PTR_OP IDENTIFIER 57 | | postfix_expression INC_OP 58 | | postfix_expression DEC_OP 59 | ; 60 | 61 | argument_expression_list 62 | : assignment_expression 63 | | argument_expression_list ',' assignment_expression 64 | ; 65 | 66 | unary_expression 67 | : postfix_expression 68 | | INC_OP unary_expression 69 | | DEC_OP unary_expression 70 | | unary_operator cast_expression 71 | | SIZEOF unary_expression 72 | | SIZEOF '(' type_name ')' 73 | ; 74 | 75 | unary_operator 76 | : '&' 77 | | '*' 78 | | '+' 79 | | '-' 80 | | '~' 81 | | '!' 82 | ; 83 | 84 | cast_expression 85 | : unary_expression 86 | | '(' type_name ')' cast_expression 87 | ; 88 | 89 | multiplicative_expression 90 | : cast_expression 91 | | multiplicative_expression '*' cast_expression 92 | | multiplicative_expression '/' cast_expression 93 | | multiplicative_expression '%' cast_expression 94 | ; 95 | 96 | additive_expression 97 | : multiplicative_expression 98 | | additive_expression '+' multiplicative_expression 99 | | additive_expression '-' multiplicative_expression 100 | ; 101 | 102 | shift_expression 103 | : additive_expression 104 | | shift_expression LEFT_OP additive_expression 105 | | shift_expression RIGHT_OP additive_expression 106 | ; 107 | 108 | relational_expression 109 | : shift_expression 110 | | relational_expression '<' shift_expression 111 | | relational_expression '>' shift_expression 112 | | relational_expression LE_OP shift_expression 113 | | relational_expression GE_OP shift_expression 114 | ; 115 | 116 | equality_expression 117 | : relational_expression 118 | | equality_expression EQ_OP relational_expression 119 | | equality_expression NE_OP relational_expression 120 | ; 121 | 122 | and_expression 123 | : equality_expression 124 | | and_expression '&' equality_expression 125 | ; 126 | 127 | exclusive_or_expression 128 | : and_expression 129 | | exclusive_or_expression '^' and_expression 130 | ; 131 | 132 | inclusive_or_expression 133 | : exclusive_or_expression 134 | | inclusive_or_expression '|' exclusive_or_expression 135 | ; 136 | 137 | logical_and_expression 138 | : inclusive_or_expression 139 | | logical_and_expression AND_OP inclusive_or_expression 140 | ; 141 | 142 | logical_or_expression 143 | : logical_and_expression 144 | | logical_or_expression OR_OP logical_and_expression 145 | ; 146 | 147 | conditional_expression 148 | : logical_or_expression 149 | | logical_or_expression '?' expression ':' conditional_expression 150 | ; 151 | 152 | assignment_expression 153 | : conditional_expression 154 | | unary_expression assignment_operator assignment_expression 155 | ; 156 | 157 | assignment_operator 158 | : '=' 159 | | MUL_ASSIGN 160 | | DIV_ASSIGN 161 | | MOD_ASSIGN 162 | | ADD_ASSIGN 163 | | SUB_ASSIGN 164 | | LEFT_ASSIGN 165 | | RIGHT_ASSIGN 166 | | AND_ASSIGN 167 | | XOR_ASSIGN 168 | | OR_ASSIGN 169 | ; 170 | 171 | expression 172 | : assignment_expression 173 | | expression ',' assignment_expression 174 | ; 175 | 176 | constant_expression 177 | : conditional_expression 178 | ; 179 | 180 | declaration 181 | : declaration_specifiers ';' 182 | | declaration_specifiers init_declarator_list ';' 183 | ; 184 | 185 | declaration_specifiers 186 | : storage_class_specifier 187 | | storage_class_specifier declaration_specifiers 188 | | type_specifier { strcpy(data_type, $1); } 189 | | type_specifier declaration_specifiers 190 | ; 191 | 192 | init_declarator_list 193 | : init_declarator 194 | | init_declarator_list ',' init_declarator 195 | ; 196 | 197 | init_declarator 198 | : declarator 199 | | declarator '=' initializer 200 | ; 201 | 202 | storage_class_specifier 203 | : TYPEDEF 204 | | EXTERN 205 | | STATIC 206 | | AUTO 207 | | REGISTER 208 | ; 209 | 210 | type_specifier 211 | : VOID 212 | | CHAR 213 | | SHORT 214 | | INT 215 | | LONG 216 | | FLOAT 217 | | DOUBLE 218 | | SIGNED 219 | | UNSIGNED 220 | | struct_or_union_specifier 221 | ; 222 | 223 | specifier_qualifier_list 224 | : type_specifier specifier_qualifier_list 225 | | type_specifier 226 | | CONST specifier_qualifier_list 227 | | CONST 228 | ; 229 | 230 | struct_or_union_specifier 231 | : struct_or_union IDENTIFIER '{' struct_declaration_list '}' ';' 232 | | struct_or_union '{' struct_declaration_list '}' ';' 233 | | struct_or_union IDENTIFIER ';' 234 | ; 235 | 236 | struct_or_union 237 | : STRUCT 238 | | UNION 239 | ; 240 | 241 | struct_declaration_list 242 | : struct_declaration 243 | | struct_declaration_list struct_declaration 244 | ; 245 | 246 | struct_declaration 247 | : specifier_qualifier_list struct_declarator_list ';' 248 | ; 249 | 250 | 251 | struct_declarator_list 252 | : declarator 253 | | struct_declarator_list ',' declarator 254 | ; 255 | 256 | declarator 257 | : pointer direct_declarator 258 | | direct_declarator 259 | ; 260 | 261 | direct_declarator 262 | : IDENTIFIER 263 | | '(' declarator ')' 264 | | direct_declarator '[' constant_expression ']' 265 | | direct_declarator '[' ']' 266 | | direct_declarator '(' parameter_list ')' 267 | | direct_declarator '(' identifier_list ')' 268 | | direct_declarator '(' ')' 269 | ; 270 | 271 | pointer 272 | : '*' 273 | | '*' pointer 274 | ; 275 | 276 | parameter_list 277 | : parameter_declaration 278 | | parameter_list ',' parameter_declaration 279 | ; 280 | 281 | parameter_declaration 282 | : declaration_specifiers declarator 283 | | declaration_specifiers 284 | ; 285 | 286 | identifier_list 287 | : IDENTIFIER 288 | | identifier_list ',' IDENTIFIER 289 | ; 290 | 291 | type_name 292 | : specifier_qualifier_list 293 | | specifier_qualifier_list declarator 294 | ; 295 | 296 | initializer 297 | : assignment_expression 298 | | '{' initializer_list '}' 299 | | '{' initializer_list ',' '}' 300 | ; 301 | 302 | initializer_list 303 | : initializer 304 | | initializer_list ',' initializer 305 | ; 306 | 307 | statement 308 | : compound_statement 309 | | expression_statement 310 | | selection_statement 311 | | iteration_statement 312 | | jump_statement 313 | ; 314 | 315 | compound_statement 316 | : '{' '}' 317 | | '{' statement_list '}' 318 | | '{' declaration_list '}' 319 | | '{' declaration_list statement_list '}' 320 | ; 321 | 322 | declaration_list 323 | : declaration 324 | | declaration_list declaration 325 | ; 326 | 327 | statement_list 328 | : statement 329 | | statement_list statement 330 | ; 331 | 332 | expression_statement 333 | : ';' 334 | | expression ';' 335 | ; 336 | 337 | selection_statement 338 | : IF '(' expression ')' statement %prec NO_ELSE 339 | | IF '(' expression ')' statement ELSE statement 340 | ; 341 | 342 | iteration_statement 343 | : WHILE '(' expression ')' statement 344 | | DO statement WHILE '(' expression ')' ';' 345 | | FOR '(' expression_statement expression_statement ')' statement 346 | | FOR '(' expression_statement expression_statement expression ')' statement 347 | ; 348 | 349 | jump_statement 350 | : CONTINUE ';' 351 | | BREAK ';' 352 | | RETURN ';' 353 | | RETURN expression ';' 354 | ; 355 | 356 | external_declaration 357 | : function_definition 358 | | declaration 359 | ; 360 | 361 | function_definition 362 | : declaration_specifiers declarator declaration_list compound_statement 363 | | declaration_specifiers declarator compound_statement 364 | | declarator declaration_list compound_statement 365 | | declarator compound_statement 366 | ; 367 | %% 368 | 369 | #include "lex.yy.c" 370 | #include 371 | #include 372 | int main(int argc, char *argv[]) 373 | { 374 | yyin = fopen(argv[1], "r"); 375 | if(!yyparse()) 376 | printf("\nParsing complete\n"); 377 | else 378 | printf("\nParsing failed\n"); 379 | 380 | fclose(yyin); 381 | display(); 382 | disp(); 383 | return 0; 384 | } 385 | //extern int lineno; 386 | extern char *yytext; 387 | yyerror(char *s) { 388 | printf("\nLine %d : %s\n", (yylineno), s); 389 | } 390 | -------------------------------------------------------------------------------- /Syntax Analysis/test1.c: -------------------------------------------------------------------------------- 1 | //without error - nested if-else 2 | #include 3 | #define x 3 4 | int main() 5 | { 6 | int a=4; 7 | if(a<10) 8 | { 9 | a = a + 1; 10 | } 11 | else 12 | { 13 | a = a + 2; 14 | } 15 | return; 16 | } 17 | -------------------------------------------------------------------------------- /Syntax Analysis/test2.c: -------------------------------------------------------------------------------- 1 | //without error - while and for loop 2 | #include 3 | #define x 3 4 | int main() 5 | { 6 | int a=4; 7 | int i; 8 | while(a<10) 9 | { 10 | a++; 11 | } 12 | for(i=1;i<5;i++) 13 | a--; 14 | } 15 | -------------------------------------------------------------------------------- /Syntax Analysis/test3.c: -------------------------------------------------------------------------------- 1 | //with error - missing multiple semicolon 2 | #include 3 | #define x 3 4 | int main() 5 | { 6 | //int c=4; 7 | int b=5 8 | /* multiline 9 | comment*/ 10 | printf("%d",b); 11 | printf("this is for checking git commit"); 12 | while(b<10) 13 | { 14 | printf("%d", b) 15 | b++; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Syntax Analysis/test4.c: -------------------------------------------------------------------------------- 1 | //with error - mispelled keyword 'while' and unmatched paranthesis 2 | #include 3 | #define x 3 4 | int main() 5 | { 6 | int a=4; 7 | whle(a<10) 8 | { 9 | printf("%d",a); 10 | j=1; 11 | while(j<=4) 12 | j++; 13 | } //unmatched paranthesis 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Syntax Analysis/test5.c: -------------------------------------------------------------------------------- 1 | //with error - dangling else problem 2 | #include 3 | #define x 3 4 | int main() 5 | { 6 | int a=4; 7 | if(a<10) 8 | printf("10"); 9 | else 10 | { 11 | if(a<12) 12 | printf("11"); 13 | else 14 | printf("All"); 15 | else 16 | printf("error"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Syntax Analysis/test6.c: -------------------------------------------------------------------------------- 1 | //with error - for loop syntax error 2 | #include 3 | int main() 4 | { 5 | int a=4, i; 6 | for(i=0;i<10) 7 | { 8 | printf("%d",i); 9 | } 10 | } 11 | --------------------------------------------------------------------------------