PageRenderTime 65ms CodeModel.GetById 2ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 1ms

/Lexical Analyzer/Lexical_Ana_C/prog1.c

https://github.com/rjsikarwar/compiler
C | 991 lines | 920 code | 47 blank | 24 comment | 36 complexity | 6cf8ae1b78774a06394fed0172f09075 MD5 | raw file
  1
  2#include <stdio.h>

  3#include <string.h>

  4#include <malloc.h>

  5
  6#define push(s) *stackp++ = s

  7#define pop() *--stackp

  8
  9int tot_size=0,cnt,key_cnt=0,par_cnt=0,del_cnt=0,relop_cnt=0,punc_cnt=0,op_cnt=0,id_cnt=0,l_cnt=0,d_cnt=0;
 10char keywords[20][20],par[20],delimiter[20],relop[3][20],punctuation[20],operators[20],identifiers[100],numbers[100],config[1000],program[1000];
 11char L[100],D[100];
 12
 13//STORING THE LIST OF POSITIONS FOR EACH OF THE TOKENS (SINCE ONE TOKEN CAN OCCUR IN VARIOUS LOCATIONS, THUS LINKED LIST)
 14typedef struct loc loc;
 15struct loc
 16{
 17    int row,col;
 18    loc *next2;
 19};
 20
 21//STRUCTURE FOR THE SYMBOL TABLE WHICH IS STORED AS A SINGLY LINKED LIST
 22typedef struct sym_tab sym_tab;
 23struct sym_tab
 24{
 25    char token[100];
 26    int type;   //1-keyword,2-parenthesis,3-relational operator,4-operator,5-identifier,6-number,7-literal
 27    loc *list;
 28    sym_tab *next1;
 29};
 30
 31sym_tab *table;
 32
 33//CONVERT INFIX EXPRESSION IN INPUT FILE TO POSTFIX EXPRESSION
 34void infix_postfix(char *inf,char *final)
 35{
 36    int length=strlen(inf);
 37    int i,j=0,k=0,cnt=0,cur=0;
 38
 39    char st_sym[100];
 40
 41    for(i=0;i<length;i++)
 42    {
 43        if(inf[i]=='(')
 44        {
 45            cnt++;
 46        }
 47        else if(inf[i]==')')
 48        {
 49            final[cur]=st_sym[k-1];
 50            k--;
 51            cur++;
 52        }
 53        else if(inf[i]=='.' || inf[i]=='*' || inf[i]=='?' || inf[i]=='|' || inf[i]=='+')
 54        {
 55            st_sym[k]=inf[i];
 56            k++;
 57        }
 58        else
 59        {
 60            final[cur]=inf[i];
 61            cur++;
 62        }
 63    }
 64    final[cur]='\0';
 65}
 66
 67
 68//IF MATCH, THEN FINAL STATE, ELSE IF SPLIT THEN TWO EDGES OUT OF THIS STATE, ELSE ON 'c' THERE IS A TRANSITION
 69enum
 70{
 71	Match = 256,
 72	Split = 257
 73};
 74
 75//STRUCTURE FOR EACH STATE
 76typedef struct State State;
 77struct State
 78{
 79	int c;                  //IF THERE IS A TRANSITION, THEN IT IS ON THIS CHARACTER
 80	State *out;             //TRANSITION INTO STATE 1
 81	State *out1;            //TRANSITION INTO STATE 2
 82	int lastlist;
 83};
 84
 85//FINAL MATCHING STATE
 86State matchstate = { Match };
 87
 88int nstate;                 //NUMBER OF STATES
 89
 90//INITIALIZE STATE
 91State*
 92state(int c, State *out, State *out1)
 93{
 94	State *s;
 95
 96	nstate++;               //INCREASE TOTAL COUNT OF STATES
 97	s = malloc(sizeof *s);
 98	s->lastlist = 0;
 99	s->c = c;
100	s->out = out;
101	s->out1 = out1;
102	return s;               //RETURN NEWLY ALLOTED STATE
103}
104
105//FRAG MAINTAINS THE NFA AS IT IS BUILDING UP(i.e. WITHOUT THE FINAL STATE)
106typedef struct Frag Frag;
107typedef union Ptrlist Ptrlist;
108struct Frag
109{
110	State *start;           //START STATE
111	Ptrlist *out;           //LIST OF TRANSITIONS OUT OF THIS STATE
112};
113
114//INITIALIZE THE FRAG STRUCTURE
115Frag
116frag(State *start, Ptrlist *out)
117{
118	Frag n = { start, out };
119	return n;
120}
121
122//STORING THE LISTS
123union Ptrlist
124{
125	Ptrlist *next;
126	State *s;
127};
128
129//CREATE A SINGLE LIST
130Ptrlist*
131list1(State **outp)
132{
133	Ptrlist *l;
134
135	l = (Ptrlist*)outp;
136	l->next = NULL;
137	return l;
138}
139
140//MODIFY OUT POINTERS FROM STATE TO POINT TO START
141void
142patch(Ptrlist *l, State *s)
143{
144	Ptrlist *next;
145
146	for(; l; l=next){
147		next = l->next;
148		l->s = s;
149	}
150}
151
152//JOIN TWO LISTS
153Ptrlist*
154append(Ptrlist *l1, Ptrlist *l2)
155{
156	Ptrlist *oldl1;
157
158	oldl1 = l1;
159	while(l1->next)
160		l1 = l1->next;
161	l1->next = l2;
162	return oldl1;
163}
164
165//CONVERT POSTFIX EXPRESSION TO NFA
166State*
167post2nfa(char *postfix)
168{
169	char *p;
170	Frag stack[1000], *stackp, e1, e2, e;
171	State *s;
172
173	if(postfix == NULL)
174		return NULL;
175
176	stackp = stack;
177	for(p=postfix; *p; p++){
178		switch(*p){
179		default:
180			s = state(*p, NULL, NULL);
181			push(frag(s, list1(&s->out)));
182			break;
183		case '.':	                            //CONCATE
184			e2 = pop();
185			e1 = pop();
186			patch(e1.out, e2.start);
187			push(frag(e1.start, e2.out));
188			break;
189		case '|':                               //UNION
190			e2 = pop();
191			e1 = pop();
192			s = state(Split, e1.start, e2.start);
193			push(frag(s, append(e1.out, e2.out)));
194			break;
195		case '?':                               //0 OR 1
196			e = pop();
197			s = state(Split, e.start, NULL);
198			push(frag(s, append(e.out, list1(&s->out1))));
199			break;
200		case '*':                               //0 OR MORE
201			e = pop();
202			s = state(Split, e.start, NULL);
203			patch(e.out, s);
204			push(frag(s, list1(&s->out1)));
205			break;
206		case '+':                               //1 OR MORE
207			e = pop();
208			s = state(Split, e.start, NULL);
209			patch(e.out, s);
210			push(frag(e.start, list1(&s->out1)));
211			break;
212		}
213	}
214
215	e = pop();
216	if(stackp != stack)
217		return NULL;
218
219	patch(e.out, &matchstate);
220	return e.start;
221}
222
223//STRUCTURE TO MAINTAIN LIST OF STATES
224typedef struct List List;
225struct List
226{
227	State **s;
228	int n;
229};
230List l1, l2, l3, l4;                //2 FOR IDENTIFIERS, 2 FOR NUMBERS
231static int listid;
232
233void addstate(List*, State*);
234void step(List*, int, List*);
235
236//ADDS LIST L TO STATE
237List*
238startlist(State *start, List *l)
239{
240	l->n = 0;
241	listid++;
242	addstate(l, start);
243	return l;
244}
245
246//CHECKS IF STATE LIST CONTAINS A FINAL STATE
247int
248ismatch(List *l)
249{
250	int i;
251
252	for(i=0; i<l->n; i++)
253		if(l->s[i] == &matchstate)
254			return 1;
255	return 0;
256}
257
258//ADDS STATE TO LIST
259void
260addstate(List *l, State *s)
261{
262	if(s == NULL || s->lastlist == listid)
263		return;
264	s->lastlist = listid;
265	if(s->c == Split){
266		/* follow unlabeled arrows */
267		addstate(l, s->out);
268		addstate(l, s->out1);
269		return;
270	}
271	l->s[l->n++] = s;
272}
273
274//FROM clist ON CHARACTER 'c' GET NEW LISTS nlist
275void
276step(List *clist, int c, List *nlist)
277{
278	int i;
279	State *s;
280
281	listid++;
282	nlist->n = 0;
283	for(i=0; i<clist->n; i++){
284		s = clist->s[i];
285		if(s->c == c)
286			addstate(nlist, s->out);
287	}
288}
289
290//CHECK WHETHER STRING 's' CAN BE SIMULATED USING THE NFA
291int
292match(State *start, char *s,int op)
293{
294	int i, c;
295	List *clist, *nlist, *t;
296
297	if(op==1)
298    {
299        clist = startlist(start, &l1);
300        nlist = &l2;
301    }
302    else
303    {
304        clist = startlist(start, &l3);
305        nlist = &l4;
306    }
307
308	for(; *s; s++){
309		c = *s & 0xFF;
310		step(clist, c, nlist);
311		t = clist; clist = nlist; nlist = t;        //SWAPS THE LIST
312	}
313	return ismatch(clist);
314}
315
316//CHECKS FOR DELIMITERS DEFINED IN config.txt
317int check_delimiter(char t)
318{
319    int flag=-1,i;
320
321    for(i=0;i<del_cnt;i++)
322    {
323        if(t==delimiter[i])
324            flag=i;
325    }
326    return flag;
327}
328
329//CHECKS FOR PARENTHESIS DEFINED IN config.txt
330int check_parenthesis(char t)
331{
332    int flag=-1,i;
333
334    for(i=0;i<par_cnt;i++)
335    {
336        if(t==par[i])
337            flag=i;
338    }
339    return flag;
340}
341
342//CHECKS FOR QUOTES DEFINED IN config.txt
343int check_quotes(char t)
344{
345    int flag=-1,i;
346
347    if(t=='\'' || t=='"')
348        flag=1;
349
350    return flag;
351}
352
353//CHECKS FOR KEYWORDS DEFINED IN config.txt
354int keyword_search(char *token)
355{
356    int i,j,flag=-1,mat=0,len=strlen(token);
357
358    for(i=0;i<key_cnt;i++)
359    {
360        mat=0;
361        for(j=0;j<strlen(keywords[i]);j++)
362        {
363            if(j<=len && keywords[i][j]==token[j])
364                mat++;
365        }
366        if(mat==strlen(keywords[i]))
367        {
368            flag=i;
369            i=key_cnt;
370        }
371    }
372    return flag;
373}
374
375//CHECKS FOR RELATIONAL OPERATORS DEFINED IN config.txt
376int relop_search(char *token)
377{
378    int i,j,flag=-1,mat=0,len=strlen(token);
379
380    for(i=0;i<relop_cnt;i++)
381    {
382        mat=0;
383        for(j=0;j<strlen(relop[i]);j++)
384        {
385            if(j<=len && relop[i][j]==token[j])
386                mat++;
387        }
388        if(mat==strlen(relop[i]))
389        {
390            flag=i;
391            i=key_cnt;
392        }
393    }
394    return flag;
395}
396
397//CHECKS FOR OPERATORS DEFINED IN config.txt
398int op_search(char *token)
399{
400    int i,j,flag=-1,mat=0,len=strlen(token);
401
402    for(i=0;i<op_cnt;i++)
403    {
404        mat=0;
405        if(j<=len && operators[i]==token[0])
406        mat++;
407
408        if(strlen(token)==1 && mat==1)
409        {
410            flag=i;
411            i=key_cnt;
412        }
413    }
414    return flag;
415}
416
417//THIS FUNCTION SAVES THE TOKEN (ITS TYPE, ETC.) INTO THE LINKED LIST
418void save_list(char *temp,int type,int row,int col)
419{
420    if(table==NULL)
421    {
422        table=(sym_tab *)malloc(sizeof(sym_tab));
423        table->next1=NULL;
424        strcpy(table->token,temp);
425        table->type=type;
426
427        loc *t12;
428        t12=(loc *)malloc(sizeof(loc));
429        t12->row=row;
430        t12->col=col;
431        t12->next2=NULL;
432
433        table->list=t12;
434    }
435    else
436    {
437        sym_tab *t123,*last;
438        t123=table;
439        int fl=0;
440        while(t123!=NULL)
441        {
442            if(t123->type==type)
443            {
444                if(strcmp(t123->token,temp)==0)
445                    break;
446            }
447            last=t123;
448            t123=t123->next1;
449        }
450        if(t123!=NULL)
451        {
452            loc *t12;
453            t12=(loc *)malloc(sizeof(loc));
454            t12->row=row;
455            t12->col=col;
456            t12->next2=NULL;
457
458            loc *l123;
459            l123=t123->list;
460
461            while(l123->next2!=NULL)
462            {
463                l123=l123->next2;
464            }
465            l123->next2=t12;
466        }
467        else
468        {
469            sym_tab *table1;
470            table1=(sym_tab *)malloc(sizeof(sym_tab));
471            table1->next1=NULL;
472            strcpy(table1->token,temp);
473            table1->type=type;
474
475            loc *t12;
476            t12=(loc *)malloc(sizeof(loc));
477            t12->row=row;
478            t12->col=col;
479            t12->next2=NULL;
480
481            table1->list=t12;
482
483            last->next1=table1;
484        }
485    }
486}
487
488int main()
489{
490    char regex[100],final[100],input[10][10],post_num[100],post_id[100];
491    int i,flag_rd=0,flag_cur=0,flag_box=0;
492	State *start_id,*start_num;
493    table=NULL;
494
495	char temp[20],c;
496    char token[1000];
497
498	int j,k,l,m,n;
499
500	FILE  *fp,*pro,*output,*error_file;
501
502	//READ FROM config.txt
503    fp = fopen("config.txt","r");
504
505    c = getc(fp) ;
506    while (c!= EOF)
507    {
508        config[tot_size]=c;
509        tot_size++;
510        c = getc(fp);
511    }
512    fclose(fp);
513
514    i=0;
515
516    //SKIP ALL THE COMMENTS
517    while(!(config[i]=='-' && config[i+1]=='>'))
518    {
519        i++;
520    }
521
522    //ARRAY 'L'
523    while(!(config[i]=='L' && config[i+1]==':'))
524        i++;
525
526    i=i+3;
527    cnt=0;
528    while(config[i]!='\n')
529    {
530        if(config[i]==',')
531        {
532            temp[cnt]='\0';
533            L[l_cnt]=temp[0];
534            l_cnt++;
535            cnt=0;
536        }
537        else
538        {
539            temp[cnt]=config[i];
540            cnt++;
541        }
542        i++;
543    }
544
545    //ARRAY 'D'
546    while(!(config[i]=='D' && config[i+1]==':'))
547        i++;
548
549    i=i+3;
550    cnt=0;
551    while(config[i]!='\n')
552    {
553        if(config[i]==',')
554        {
555            temp[cnt]='\0';
556            D[d_cnt]=temp[0];
557            d_cnt++;
558            cnt=0;
559        }
560        else
561        {
562            temp[cnt]=config[i];
563            cnt++;
564        }
565        i++;
566    }
567
568    //KEYWORDS
569    while(!(config[i]=='k' && config[i+1]=='e' && config[i+2]=='y'))
570    {
571        i++;
572    }
573
574    i+=10;
575
576    cnt=0;
577    while(config[i]!='\n')
578    {
579        if(config[i]==',')
580        {
581            temp[cnt]='\0';
582            strcpy(keywords[key_cnt],temp);
583            key_cnt++;
584            cnt=0;
585        }
586        else
587        {
588            temp[cnt]=config[i];
589            cnt++;
590        }
591        i++;
592    }
593
594    //PARENTHESIS
595    while(!(config[i]=='p' && config[i+1]=='a' && config[i+2]=='r'))
596        i++;
597
598    i=i+13;
599    cnt=0;
600    while(config[i]!='\n')
601    {
602        if(config[i]==',')
603        {
604            temp[cnt]='\0';
605            par[par_cnt]=temp[0];
606            par_cnt++;
607            cnt=0;
608        }
609        else
610        {
611            temp[cnt]=config[i];
612            cnt++;
613        }
614        i++;
615    }
616
617    //DELIMITER
618    while(!(config[i]=='d' && config[i+1]=='e' && config[i+2]=='l'))
619        i++;
620
621    i=i+11;
622    cnt=0;
623    while(config[i]!='\n')
624    {
625        if(config[i]==',')
626        {
627            temp[cnt]='\0';
628            delimiter[del_cnt]=temp[0];
629            del_cnt++;
630            cnt=0;
631        }
632        else
633        {
634            temp[cnt]=config[i];
635            cnt++;
636        }
637        i++;
638    }
639
640    delimiter[del_cnt]='\n';
641    delimiter[del_cnt+1]=',';
642    del_cnt+=2;
643
644    //RELATIONAL-OPERATOR
645    while(!(config[i]=='r' && config[i+1]=='e' && config[i+2]=='l'))
646        i++;
647
648    i=i+7;
649    cnt=0;
650    while(config[i]!='\n')
651    {
652        if(config[i]==',')
653        {
654            temp[cnt]='\0';
655            strcpy(relop[relop_cnt],temp);
656            relop_cnt++;
657            cnt=0;
658        }
659        else
660        {
661            temp[cnt]=config[i];
662            cnt++;
663        }
664        i++;
665    }
666
667    //OPERATOR
668    while(!(config[i]=='o' && config[i+1]=='p' && config[i+2]=='e'))
669        i++;
670
671    i=i+10;
672    cnt=0;
673    while(config[i]!='\n')
674    {
675        if(config[i]==',')
676        {
677            temp[cnt]='\0';
678            operators[op_cnt]=temp[0];
679            op_cnt++;
680            cnt=0;
681        }
682        else
683        {
684            temp[cnt]=config[i];
685            cnt++;
686        }
687        i++;
688    }
689
690    //IDENTIFIERS
691    while(!(config[i]=='i' && config[i+1]=='d' && config[i+2]=='e'))
692    {
693        i++;
694    }
695
696    i=i+13;
697    cnt=0;
698    while(config[i]!='\n')
699    {
700        temp[cnt]=config[i];
701        cnt++;
702        i++;
703    }
704    temp[cnt]='\0';
705    strcpy(identifiers,temp);
706
707    //NUMBERS
708    while(!(config[i]=='n' && config[i+1]=='u' && config[i+2]=='m'))
709    {
710        i++;
711    }
712
713    i=i+9;
714    cnt=0;
715    while(config[i]!='\n')
716    {
717        temp[cnt]=config[i];
718        cnt++;
719        i++;
720    }
721    temp[cnt]='\0';
722    strcpy(numbers,temp);
723
724    infix_postfix(identifiers,post_id);         //CONVERTS INFIX EXPRESSION OF IDENTIFIER INTO POSTFIX
725    start_id = post2nfa(post_id);               //CONVERTS POSTFIX EXPRESSION OF IDENTIFIER INTO NFA
726
727    infix_postfix(numbers,post_num);            //CONVERTS INFIX EXPRESSION OF NUMBERS INTO POSTFIX
728    start_num = post2nfa(post_num);             //CONVERTS POSTFIX EXPRESSION OF NUMBERS INTO NFA
729
730    l1.s = malloc(nstate*sizeof l1.s[0]);
731	l2.s = malloc(nstate*sizeof l2.s[0]);
732
733    l3.s = malloc(nstate*sizeof l3.s[0]);
734	l4.s = malloc(nstate*sizeof l4.s[0]);
735
736    //READ THE PROGRAM
737    pro = fopen("sample.txt","r");
738
739    output = fopen("symbol_table.txt","w");     //OUPUT THE SYMBOL TABLE
740    error_file = fopen("error_file.txt","w");     //OUPUT THE SYMBOL TABLE
741
742    c = getc(pro) ;
743    tot_size=0;
744    while (c!= EOF)
745    {
746        program[tot_size]=c;
747        tot_size++;
748        c = getc(pro);
749    }
750    fclose(pro);
751
752    fprintf(output,"%20s %20s %30s\n","TOKEN","TYPE","LINE NUMBER (row,col)");
753
754    int row=1,col=0;
755    cnt=0;
756
757    for(i=0;i<tot_size;i++)
758    {
759        //CHECKS IF THERE ARE ANY COMMENTS
760        if(i!=tot_size-1)
761        {
762            if(program[i]=='/' && program[i+1]=='/')
763            {
764                while((program[i]!='\n') && i<tot_size)
765                    i++;
766                row++;
767            }
768        }
769
770        //AT ANY POINT, IF THERE ARE MROE NUMBER OF CLOSING PARENTHESIS THAN OPEN, THEN ERROR (BALANCED PARENTHESIS)
771        if(flag_rd<0)
772            fprintf(error_file,"\nError on line %d column %d.\n \t Extra parenthesis ')'.",row,col);
773
774        if(flag_cur<0)
775            fprintf(error_file,"\nError on line %d column %d.\n \t Extra parenthesis '}'.",row,col);
776
777        if(flag_box<0)
778            fprintf(error_file,"\nError on line %d column %d.\n \t Extra parenthesis ']'.",row,col);
779
780        //IF THERE ARE QUOTES, WE NEED TO INCLUDE 'ALL' CHARACTERS BETWEEN THEM AS LITERALS
781        if(check_quotes(program[i])!=-1)
782        {
783            char abc=program[i];
784            j=1;
785            temp[0]=program[i];
786            int prev_row=row;
787            int prev_col=col;
788            while(((i+j)<tot_size)&&(program[i+j]!=abc))
789            {
790                temp[j]=program[i+j];
791                j++;
792                if(program[i+j]=='\n')
793                {
794                    row++;
795                    col=0;
796                }
797                else
798                    col++;
799            }
800
801            if(i+j==tot_size)
802            {
803                fprintf(error_file,"\nError on line %d column %d.\n \t Quotes does not have matching pair.",prev_row,prev_col);
804                break;
805            }
806
807            temp[j]=abc;
808            temp[j+1]='\0';
809
810            //fprintf(output,"%20s %20s %10s (%d,%d)\n",temp,"literal","",row,col);
811
812            save_list(temp,7,row,col);
813
814            i=i+j;
815        }
816
817        //CHECK FOR THE PRESENCE OF DELIMITER
818        else if(check_delimiter(program[i])!=-1)
819        {
820            token[cnt]='\0';
821
822            if(cnt!=0)
823            {
824                j=0;
825                while(j<strlen(token))
826                {
827                    int my_fl=0;
828                    for(m=0;m<l_cnt;m++)
829                    {
830                        if(L[m]==token[j])
831                        {
832                            temp[j]='L';
833                            my_fl=1;
834                        }
835                    }
836                    for(m=0;m<d_cnt;m++)
837                    {
838                        if(D[m]==token[j])
839                        {
840                            temp[j]='D';
841                            my_fl=1;
842                        }
843                    }
844                    if(token[j]=='.')
845                        temp[j]='W';
846
847                    else if(my_fl==0)
848                        temp[j]=token[j];
849
850                    j++;
851                }
852                temp[j]='\0';
853
854                //CHECK IF TOKEN IS A KEYWORD
855                if(keyword_search(token)!=-1)
856                {
857                    //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"keyword","",row,(col-strlen(token)-1));
858
859                    save_list(token,1,row,(col-strlen(token)-1));
860                }
861
862                //CHECK IF TOKEN IS A RELATIONAL OPERATOR
863                else if(relop_search(token)!=-1)
864                {
865                    //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"relop","",row,(col-strlen(token)));
866
867                    save_list(token,3,row,(col-strlen(token)));
868                }
869
870                //CHECK IF TOKEN IS A OPERATOR
871                else if(op_search(token)!=-1)
872                {
873                    //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"op","",row,col-1);
874
875                    save_list(token,4,row,(col-1));
876                }
877
878                //CHECK IF TOKEN IS A IDENTIFIER
879                else if(match(start_id, temp, 1))
880                {
881                    //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"identifier","",row,(col-strlen(token)));
882
883                    save_list(token,5,row,(col-strlen(token)));
884                }
885
886                //CHECK IF TOKEN IS A NUMBER
887                else if(match(start_num, temp, 2))
888                {
889                    //fprintf(output,"%20s %20s %10s (%d,%d)\n",token,"number","",row,(col-strlen(token)));
890
891                    save_list(token,6,row,(col-strlen(token)));
892                }
893
894                //IF IT DOES NOT MATCH ANY OF THESE, THEN IT IS AN ERROR
895                else
896                {
897                    fprintf(error_file,"\nError on line %d column %d.\n \t %s does not match any known type of token.",row,(col-strlen(token)),token);
898                }
899            }
900
901            //CHECK IF PRESENCE OF PARENTHESIS (CHECK SEPARATELY BECAUSE IT IS ALSO PART OF DELIMITER)
902            if(check_parenthesis(program[i])!=-1)
903            {
904                //fprintf(output,"%20c %20s %10s (%d,%d)\n",program[i],"parenthesis","",row,col-1);
905
906                if(program[i]=='(')
907                   flag_rd++;
908                else if(program[i]==')')
909                   flag_rd--;
910
911                if(program[i]=='{')
912                   flag_cur++;
913                else if(program[i]=='}')
914                   flag_cur--;
915
916                if(program[i]=='[')
917                   flag_box++;
918                else if(program[i]==']')
919                   flag_box--;
920
921                char temp12[1000];
922                strcpy(temp12,token);
923                token[0]=program[i];
924                token[1]='\0';
925
926                save_list(token,2,row,(col-1));
927            }
928            if(program[i]=='\n')
929            {
930                row++;
931                col=0;
932            }
933
934            cnt=0;
935        }
936        else
937        {
938            token[cnt]=program[i];
939            cnt++;
940        }
941        col++;
942    }
943
944    sym_tab *temp12;
945    temp12=table;
946
947    //PRINT THE SYMBOL TABLE ONTO FILE
948    while(temp12!=NULL)
949    {
950        if(temp12->type==1)
951            fprintf(output,"%20s %20s %5s",temp12->token,"keyword","");
952        else if(temp12->type==2)
953            fprintf(output,"%20s %20s %5s",temp12->token,"parenthesis","");
954        else if(temp12->type==3)
955            fprintf(output,"%20s %20s %5s",temp12->token,"rel. operator","");
956        else if(temp12->type==4)
957            fprintf(output,"%20s %20s %5s",temp12->token,"operator","");
958        else if(temp12->type==5)
959            fprintf(output,"%20s %20s %5s",temp12->token,"identifier","");
960        else if(temp12->type==6)
961            fprintf(output,"%20s %20s %5s",temp12->token,"number","");
962        else if(temp12->type==7)
963            fprintf(output,"%20s %20s %5s",temp12->token,"literal","");
964
965        loc *ter12=temp12->list;
966        while(ter12!=NULL)
967        {
968            fprintf(output,"(%d,%d),",ter12->row,ter12->col);
969            ter12=ter12->next2;
970        }
971        temp12=temp12->next1;
972        fprintf(output,"\n");
973        //int ag;
974        //scanf("%d",&ag);
975    }
976    fclose(output);
977
978    //AT THE END ALSO CHECK IF ALL THE PARENTHESIS HAVE BEEN CLOSED
979    if(flag_rd!=0)
980        fprintf(error_file,"\nError on line %d column %d.\n \t '(' not closed.",row,col);
981
982    if(flag_cur!=0)
983        fprintf(error_file,"\nError on line %d column %d.\n \t '{' not closed.",row,col);
984
985    if(flag_box!=0)
986        fprintf(error_file,"\nError on line %d column %d.\n \t '[' not closed.",row,col);
987
988    printf("\n");
989
990    return 0;
991}