You are on page 1of 47

/*** WRITE A PROGRAM TO IMPLEMENT TOKENIZER ***/ #include<stdio.h> #include<conio.h> #include<string.h> #include<ctype.h> #define INPUT_FILE"LEX_IN.TXT" #define OUTPUT_FILE"LEX_OUT.

TXT" struct tab_main { char token[20]; char attribute[45]; }; struct tab_main tm[3]; struct table { char token[20]; char attribute[35]; struct table *node; }; typedef struct table *node; node *head=NULL; int get_token(char[]); node install_id(char[]); void initialize(); node void void char FILE install_num(char*); print_table(); error(); buffer[50]; *fs,*ft;

void main() { int state=0,i=0,j; char ch; initialize(); fs=fopen(INPUT_FILE,"r"); ft=fopen(OUTPUT_FILE,"w+"); while(!feof(fs)) { int p; node q; switch(state) { case 0:fgetc(fs); buffer[i++]=ch; if(ch== ' '|| /*ch=\t' ||*/ ch==',') {

state=0; i=0; } else if(isalpha(ch)) state=1; else if(isdigit(ch)) state=3; else if(ch=='<') state=7; else if(ch=='>') state=9; else if(ch=='=') state=13; break; case 1: ch=fgetc(fs); buffer[i++]=ch; if(isalpha(ch)) state=1; else if(isdigit(ch)) state=1; else state=2; break; case 2: buffer[i-1]='\0'; i=0; state=0; p=get_token(buffer); if(p!=0) { fprintf(ft,"\n\n%s\t\t%s", buffer,tm[i} break; case 3: ch=fgetc(fs); buffer[i++]=ch; if(isdigit(ch)) state=3; else if(ch=='.') state=5; else state=4; break; case 4: buffer[i-1]='\0'; state=0; i=0; q=install_num(buffer); fprintf(ft,"\n\n%s\t%u", buffer,q); break; case 5: ch=fgetc(fs); buffer[i++]=ch; if(isdigit(ch)) state=5;

1].attribute);

case

case

case

case

case

case

case

case

else state=6; break; 6: buffer[i-1]='\0'; state=0; i=0; q=install_num(buffer); fprintf(ft,"\n\n%s\t%u", buffer,q); break; 7: ch=fgetc(fs); buffer[i++]=ch; if(ch=='>') state=10; else if(ch=='=') state=8; else state=16; break; 8: buffer[i]='\0'; fprintf(ft,"\n\n%s",buffer); i=0; state=0; break; 9: ch=fgetc(fs); buffer[i++]=ch; if(ch=='=') state=11; break; 10: buffer[i]='\0'; fprintf(ft,"\n\n%s", buffer); i=0; state=0; break; 11: buffer[i]='\0'; fprintf(ft,"\n\n%s", buffer); i=0; state=0; break; 12: buffer[i-1]='\0'; fprintf(ft,"\n\n%s", buffer); i=0; state=0; break; 13: ch=fgetc(fs); buffer[i++]=ch; if(ch=='=') state=15; else state=14; break;

case 14: buffer[i-1]='\0'; fprintf(ft,"\n\n%s", buffer); i=0; state=0; break; case 15: buffer[i]='\0'; fprintf(ft,"\n\n%s", buffer); i=0; state=0; break; } } fprintf(ft,"\n\n--------------SYMBOL TABLE----------------\n"); print_table(); } void initialize() { strcpy(tm[0].token,"int"); strcpy(tm[0].attribute,"Integer Keyword"); strcpy(tm[1].token,"float"); strcpy(tm[1].attribute,"Float Keyword"); strcpy(tm[2].token,"char"); strcpy(tm[2].attribute,"Character Keyword"); } int get_token(char buffer[]) { int i; for(i=0;i<=2;i++) { if(strcpy(buffer,tm[i].token)==0) return(i+1); } return 0; } NODE install_id(char buffer[]) { NODE new_node,nd; nd=head; new_node=(struct table*)malloc(sizeof(struct table)); while(nd!=NULL) { if(strcmp(nd->token,buffer)==0) return(nd); else nd=nd->next; } if(head==NULL) { strcpy(new_node->token,buffer); strcpy(new_node->attribute,"identifier"); new_node->next=NULL; head=new_node;

} else {

return(new_node);

nd=head; while(nd->next!=NULL) nd=nd->next; strcpy(new_node->,buffer); strcpy(new_node->attribute,"identifier"); new_node->next=NULL; nd->next=new_node; return(new_node); } } void error() { fprintf(ft,"No State"); exit(0); } void print_table() { node start; start=head; fprintf(ft,"\n"); while(start!=NULL) { fprintf(ft,"\n%s\t\t%s",start->token,start>attribute); start=start->next; } } node install_num(char buffer[]) { node new_node,nd; nd=head; new_node=(start table*)malloc(sizeof(struct table)); if(head==NULL) { strcpy(new_node->token,buffer); strcpy(new_node->attribute,"number"); new_node->next=null; head=new_node; return(new_node); } else { while(nd->next!=NULL) nd=nd->next; strcpy(new_node->token,buffer); strcpy(new_node->attribute,"number"); new_node->next=NULL; nd->next=new_node; return(new_node); } }

/*** WRITE A PROGRAM USING CALL STATEMENT AND CASE STATEMENT ***/ #include<stdio.h> #include<conio.h> #include<stdlib.h> int fact(int); int sum(int); void swap(int,int); void main() { int ch,n,m,d,f; clrscr(); printf("****Program Call & Case Statement***"); printf("\n\n 1::Factorial"); printf("\n\n 2::Sum of Digit"); printf("\n\n 3::Call by Value"); printf("\n\n 4::Exit"); printf("\n\n :: Enter Your Choice"); scanf("%d", &ch); switch(ch) { case 1: printf("\n Enter the Number"); scanf("%d", &n); f=fact(n); printf("\n The Factorial is:%d",f); break; case 2: printf("\n Enter the Digit"); scanf("%d", &n); d=sum(n); printf("\n The sum of digit is:%d",d); break; case 3: printf("\n Enter the Two Number a & b"); scanf("%d %d", &n, &m); swap(n,m); break; case 4: exit(0); break; default: printf("\n Enter Your Choice"); } getch(); } int fact(int n) { int a=1,i; for(i=1;i<=n;i++) { a=a*i; } return(a); }

int sum(int n) { int s=0; int i; for(i=1;i<=3;i++) { s=s+n%10; n=n/10; } return(s); } void swap(int n,int m) { int t; t=n; n=m; m=t; printf("\n The Swap value a & b is: %d %d",n,m); }

/* HEADER FILE TO FIRST AND FOLLOW */ #include<stdio.h> #include<conio.h> #include<string.h> #include<ctype.h> #include<math.h> #include<dos.h> #include<stdarg.h> #include<stdlib.h> #define #define #define #define #define #define ENDMARKER '$' F1 59 F2 60 F3 61 F4 62 ESC 27

int max,deflen=5,q; char start='E'; //for default grammer char terminal[12],nonterminal[12]; int callf,callfo,NO_PRO; int nos=0; int getprod(); int k=0; struct FIRST { char F_of; char first[10];

char present; struct FIRST *next; }; struct FOLLOW { char Fo_of; char follow[10]; char present; struct FOLLOW *next; }; struct PROD { char P_of; char prod[10]; struct FIRST *id; struct FOLLOW *idfo; struct PROD *next; struct PROD *no; }; struct PROD *P, stapro; struct FIRST *F,stafir; struct FOLLOW *Fo,stafo; /*******PRINT FORMATED STRING AT(X,Y)*********/ void printxy(int x, int y, const char *str, ...) { va_list argptr; char buffer[35]; va_start(argptr,str); vsprintf(buffer,str,argptr); va_end(argptr); gotoxy(x,y); printf(buffer); } /*********SHOW HELP IF PRESS F2************/ void showhelp() { struct PROD *temp; clrscr(); temp=stapro.next; printxy(25,5,"HELP"); printxy(23,6,"********"); printxy(5,8,"1.Press 'I' for an ID"); printxy(5,10,"2.Press 'N' for NULL"); printxy(5,12,"3.Use Symbol ':=' or '->' to from of"); printxy(5,14,"4.Use UPPER CASE only for NON TERMINAL"); printxy(5,16,"5.Do not use a char ' anywhere"); printxy(5,19,"6.Press F1 for DEFAULT production"); printxy(5,21,"7.Press F2 for HELP"); printxy(5,23,"8.Press F3 for not consider production"); printxy(5,25,"9.Press F4 After Last Production");

printxy(5,27,"10.Press ESC for Abnornal Exit"); printxy(5,29,"Example of a production X->+a*b|(a)|N"); getch(); gotoxy(1,13); while(temp) { printf("%c->%s\n\n", temp->P_of, temp->prod); temp=temp->next; q++; gotoxy(1,1); getprod(); } } /********PRINT AN ERROR MESSAGE*********/ void errmsg(int n) { switch(n) { case 1: break; case 2: break; case 3: grammer"); break; case 4: break; case 5: break; case 6: recursion call"); break; } getch(); exit(3); }

printf("\n Not enough memory to allocate buffer"); printf("\n Syntax error in entered production"); printf("\n Follow cannot be calculated in this printf("\n Sorry cannot interpret this grammer"); printf("\n Start symbol not found"); printf("\n Cannot interpret grammar \n Indirect

/***************FIND TERMINAL****************/ int isterminal(char ch) { int i, flag=1; char ter[]="()/*+IN"; if(strchr(ter,ch)||islower(ch)) { for(i=0;terminal[i]!='\0'; i++) { if(terminal[i]==ch) flag=0; } if(flag && ch!='N') terminal[i++]=ch; terminal[i]='\0';

} }

return 1; return 0;

/****************STORE PRODUCTION IN LINKED LIST***************/ int store(char *str, int len) { static int l=0; int i=0,e=0,z=0,flag=l,s; char strp[20]; while(flag) { flag=0; for(s=0;s<3;s++) strp[s]=str[s]; for(s=3;(z+2<len && flag==0); z++) { if(str[z+3]!='|') strp[s++]=str[z+3]; else if(str[z+3]=='|') flag=1; } strp[s]='\0'; P->next=(struct PROD *)malloc(sizeof(struct PROD)); if(!P->next) errmsg(1); P=P->next; if(isterminal(strp[0])) errmsg(2); if(strp[1]!=':'||strp[2]!='=') e++; if(strp[1]!='-'||strp[2]!='>') e++; if(e!=1||!isupper(strp[0])) errmsg(2); P->P_of=strp[0]; if(nos==0) start=strp[0]; nonterminal[l++]=strp[0]; nonterminal[l++]='\0'; nos++; for(i=3;i<len;i++) P->prod[i-3]=strp[i]; P->prod[i-3]='\0'; P->next=NULL; printf("\n Production(%d)=%c->%s",nos,P->P_of,P->prod); } return 1; }

/********GET A DEFAULT PRODUCTION *********/ int get_default_prod() { int n=0,l; char p[27],*str; p[0]=25; P=&stapro; start='E'; deflen=5; for(n=0;n<5;n++) { switch(n) { case 0: str="E:=TR"; break; case 1: str="R:=+TR|N"; break; case 2: str="T:=FV"; break; case 3: str="V:=*VF|N"; if(k) k++; break; case 4: str="F:=(E)|I"; break; } l=strlen(str); store(str,l);

} return deflen;

/*********CALL IF USER PRESS ANY KEY **************/ unsigned int chkf1f2(char ch) { static char last=13,k=0; if(ch==27) exit(0); if(ch==8) return F3; if(ch==0) { ch=getch();

break;

switch(ch) { case F1: get_default_prod();

case F4:return F4; case F3: return F3; case F2:showhelp(); case 75:return-1; //if a left arrow hit } } if(last==1 && ch==13) { k++; if(k>2) printf("\n\t\tmessage:press F4 to End Production\n"); return 2; } last=ch; if(isspace(ch)) { putch(' '); return 1; } return 0; } /************GET GRAMMER FORM USER OR DEFAULT IF PRESS F1 *************/ int getprod() { static int n=0; int l,i=0,r,flag=0; char str[30],ch; stapro.next=NULL; stafir.next=NULL; stafo.next=NULL; P= &stapro; F= &stafir; Fo=&stafo; fflush(stdin); printf("\n\n enter the production of a grammar"); printf("Press 'N' for NULL. 'I' to show an ID"); printf("\n\n\n PRESS F1 for default production"); printf("\n PRESS F2 for HELP"); printf("\n PRESS F3 for any mistake"); printf("\n PRESS F4 after last production"); printf("\n PRESS ESC for exit");

gotoxy(1,q*2+12); while(1) { puts("\n\t\t"); i=0; do { fflush(stdin); ch=getch(); r=chkf1f2(ch); switch(r) { case 0: if(!i==0 && r==F4) // store in array str { if(ch!='\r') str[i++]=ch; putch(ch); } break; //if press F4 or backspace case F3: while(i--) printf("\b\b"); i++; break; case F1: return deflen; // for default production break; case F4: flag=1; // at the end close array case 1: printf("\b\b"); i--; //if press backspace or F4 break; case 2:ch='z'; } if(flag==1) break; } while(ch!='r' && flag==0); str[i++]='\0'; if(flag==1) break; store(str,i); printf("\n\n"); n++; }

printf("\n enter START symbol(default '%c'):", start); scanf("%c", &start); if(!strchr(nonterminal, start)) errmsg(5); return n; } /***************SETS UNIQUE ID TO A TERMINAL AND RETURN NO. OF TERMINALS************/ int set_id() { struct PROD *Z,*X; int i, j, flag, x=0; P=stapro.next; for(X=stapro.next,i=0;X;i++,X=X->next) { for(j=0;X->prod[j]!='\0';j++) { if(isupper(X->prod[j]) && !strchr(nonterminal,X>prod[j]) && !strchr("IN", X->prod[j])) errmsg(4); } } for(i=0;P++;i++) { flag=1; Z=stapro.next; for(j=0;j<i && flag; j++) { if(P->P_of==Z->P_of) { P->id=Z->id; P->idfo=Z->idfo; flag=0; } Z=Z->next; } if(flag) { F->next=(struct FIRST*) malloc(sizeof(struct FIRST)); if(!F->next) errmsg(1); F=F->next; Fo=Fo->next; F->present='n'; F->F_of=P->P_of; P->id=F; F->next=NULL; Fo->present='n'; Fo->Fo_of=P->P_of; P->idfo=F; Fo->next=NULL; x++;

} } P=P->next;

return x; } /***********CALCULATE FIRST AND RETURN THE FIRST OF GIVEN SYMBOL*************/ char *First(char ch) { struct FIRST *pf; struct PROD *pp; char *fir,*f; int i,j,x=0,k,find; char *chstr,prev[10]; callf++; if(isterminal(ch)) { chstr=(char*)malloc(sizeof(char)); chstr[0]=ch; chstr[1]='\0'; //if X is terminal, then FIRST(X)=X return chstr; } pf=F; pp=P; P=stapro.next; F=stafir.next; for(i=0;F;i++) { if(F->F_of==ch) break; } F=F->next;

if(F->present!='y') { while(P) { find=1; //calculate first ONLY once of a symbol if(P->P_of==ch) { for(i=0;P->prod[i]!='\0'; i++) { if(i && P->prod[i-1]=='|') find=1; //check 'ch' in all productions if(find==1) { if(isterminal(P->prod[i])) {

>prod[i]));

} else if((P->id)->present=='n') { strcpy(prev,First(P-

F->first[x++]=P->prod[i]; find=0; continue;

(P->id)->present='y'; strcpy((P->id)->first,prev); } else strcpy(prev,(P->id)->first); find=0; for(j=0;P->prod[j]!='\0';j++) { if(prev[j]!='N') F->first[x++]=prev[j]; //case 3 } } } P=P->next; } F->first[x++]='\0'; F->present='y'; } f=F->next; F=pf; P=pp; if(callf>40) errmsg(6); return f; } /**********CALCULATE AND RETURN THE FOLLOW OF GIVEN SYMBOL**************/ char *FOLLOW(char ch) { struct FIRST *pf; struct PROD *pp; struct FOLLOW *pfo; char *fir,*f; int i,j,x=0,k,find,t; char prev[10]; pf=F; pp=P; P=stapro.next; F=stafir.next; Fo=stafo.next; } else find=1;

for(i=0;Fo;i++) { if(Fo->Fo_of==ch) break; Fo=Fo->next; } if(start==ch) Fo->follow[x++]=ENDMARKER; /*case1:place $in FOLLOW(S)*/ if(isterminal(ch)) { printf("For terminal:=%c", ch); errmsg(3); } for(; P!=NULL;P=P->next) { for(i=0;P->prod[i]!='\0';i++) { if(ch==P->prod[i]) { t=0; if(P->prod[i+1]!='|' && P->prod[i+1]!='\0') { strcpy(prev,First(P->prod[i+1])); for(k=0;prev[k]!='\0';k++) { if(prev[k]!='N') Fo->follow[x++]=prev[k]; else t=1; } } else t=1; if(t) { if(Fo->Fo_of!=P->P_of) { strcpy(prev,Follow(P->P_of)); callfo++; } else t=0; if(t) { for(j=0;prev[j]='\0';j++) Fo->follow[x++]=prev[j]; } } }

(P->idfo)->present='y'; t=0; for(i=0,k=1;i<x;i++) { for(j=0;j<i;j++) if(Fo->follow[i]==Fo->follow[j]) k=0; if(k) f[t++]=Fo->follow[i]; } f[t]='\0'; strcpy(Fo->follow,f); Fo->present='y'; F=pf; P=pp; if(callfo>40) errmsg(6); return f; } void reset() { callf=0; callfo=0; } void Show_First_And_Follow() { int i,j; char str[12],str1[12],str2[12]; P=stapro.next; F=stafir.next; Fo=stafo.next; printf("\n Given Productions are:"); for(i=1;P;i++) { printf("\n\n%d %c:=%s",i,P->P_of,P->prod); P=P->next; } P=stapro.next; F=stafir.next; Fo=stafo.next; for(i=0;i<NO_PRO;i++,P=P->next,Fo=Fo->next,F=F->next)

} nos=0;

printf("\n\n FOR SYMBOL '%c'", Fo->Fo_of); reset(); strcpy(str,First(F->F_of)); reset(); strcpy(str1,Follow(Fo->Fo_of)); printf("\t FIRST:%s FOLLOW:%s", str,str1);

/*** WRITE A PROGRAM TO FIND OUT FIRST/FOLLOW OF GRAMMAR ***/ #include<stdio.h> #include<conio.h> #include<string.h> #include<ctype.h> #include<math.h> #include<dos.h> #include<stdarg.h> #include<stdlib.h> #include"FIRST.H" void main() { char ch; do { clrscr(); max=getprod(); NO_PROD=set_id(); Show_First_And_Follow(); printf("\n\n Do you want to calculate FIRST and Follow for some other terminal (y/n):"); ch=getch(); } while(ch=='y'||ch=='Y'); }

/* EVALUATE POSTFIX AND PREFIX EXPRESSION WITH THE HELP OF STACK */ #include<stdio.h> #include<conio.h> #include<ctype.h> #include<string.h> int top=-1,i=0,l; char infix[50],stk[50],a;

void postfix(char); int p(char); void main() { clrscr(); printf("Enter infix expression"); gets(infix); l=strlen(infix); infix[l]='#'; stk[++top]='#'; printf("Postfix Expression"); while(infix[i]!='#') { if(isalpha(infix[i])) printf("%c",infix[i]); else postfix(infix[i]); i++; } while((top!=-1)&&(stk[top]!='#')) printf("%c",stk[top--]); getch(); } void postfix(char a) { switch(a) { case '(':stk[++top]=a; break; default: if(a==')') { while(stk[++top]!=')') printf("%c",stk[--top]); } else if(stk[++top]=='(') stk[++top]=a; else if(p(a)>p(stk[top])) stk[++top]=a; else { while(p(stk[top])>p(a)) printf("%c",stk[top--]); stk[++top]=a; }

} }

int p(char a) { switch(a) { case '^':

return 3; break; case '/': case '*': return 2; break; case '+': case '-': return 1; break; default: return 0;

} }

/* EVALUATE POSTFIX AND PREFIX EXPRESSION WITH THE HELP OF STACK */ #include<stdio.h> #include<conio.h> #include<ctype.h> #include<string.h> int top=-1,t=-1; char infix[20],sym[20],inf[20],pre[20]; void prefix(char); int p(char); void main() { int l,i=0; clrscr(); printf("\n Convert Postfix to Infix Expression\n"); printf("Enter infix expression"); gets(infix); l=strlen(infix); while(i<l) { inf[i+1]=infix[i]; i++; } inf[0]='('; sym[++t]=')'; i=strlen(inf)-1; while(i!=0) { if(isalpha(inf[i])) pre[++top]=inf[i]; else prefix(inf[i]); i--; }

while((t!=-1)&&(sym[t]!=')')) pre[++top]=sym[t--]; printf("Prefix Expression"); while(top!=-1) printf("%c", pre[top--]); getch();

void prefix(char a) { switch(a) { case ')': sym[++t]=a; break; default: if(a=='(') { while(sym[++t]!=')') pre[++top]=sym[t--]; t--; } else if(a==')') sym[++t]=a; else if(p(a)>p(sym[t])) sym[++t]=a; else { while(p(a)<p(sym[t])) pre[++top]=sym[t--]; sym[++t]=a; } } }

int p(char a) { switch(a) { case '^': return 3; break; case '/': case '*': return 2; break; case '+': case '-': return 1; break; default: return 0;

} }

/* WRITE A PROGRAMME TO IMPLEMENT OPERATOR PRECEDENCE PARSER */ #include<stdio.h> #include<conio.h> #include<ctype.h> #include<string.h> #include<stdlib.h>

struct stack { char nts,trs; }; struct stack stack[20]; int lead[20][20],trail[20][20],nop,top=0,i; char nr,tr,p[10[10],nt[20],t[20],opt[20][20],starts,stk[20]; void read_grammar() { printf("Enter the Terminal:"); gets(t); printf("Enter the Non terminal:"); gets(nt); printf("Enter No. of Productions:"); scanf("%d", &nop); for(i=0;i<nop;i++) { scanf("%s", &p[i]); } starts=p[0][0]; } int nt_no(char x) { if(x!='\0') { for(i=0;nt[i]!='\0';i++) { if(nt[i]==x) return (i); } } } int t_no(char x) { if(x!='\0') { for(i=0;nt[i]!='\0';i++) { if(nt[i]==x)

} } }

return(i); if(x=='$') return(strlen(t));

int nonterminal(char x) { if(x!='\0') { for(i=0;i<strlen(nt);i++) { if(nt[i]==x) return(1); } } return 0; } int terminal(char x) { if(x!='\0') { for(i=0;i<strlen(nt);i++) { if(t[i]==x) return(1); } } return 0; } void push(int r,int c) { top++; stack[top].nts=nt[r]; stack[top].nts=t[c]; } void pop() { nr=stack[top].nts; tr=stack[top].nts; top--; } void install(int r,int c, int lt) { if(lt==1) { if(!lead[r][c]) { lead[r][c]=1; push(r,c); } }

if(lt==2) { if(!lead[r][c]) { lead[r][c]=1; push(r,c); } }

void leading() { char a; int r,c,no,j; top=0; for(no=0;nt[no]!='\0';no++) { for(i=0;i<nop;i++) { if(nt[no]==p[i][0]) { a=p[i][3]; if(terminal(a)) { r=nt_no(p[i][0]); c=t_no(a); install(r,c,l); } [4])) else if(nonterminal(a) && terminal(p[i] { r=nt_no(p[i][0]); c=t_no(p[i][4]); install(r,c,l);

} while(top!=0) { pop(); for(j=0;j<nop;j++) { char nont=p[j][3]; if(nont==nr) { r=nt_no(p[j][0]); c=t_no(tr); install(r,c,l); } } } } } } }

void trailing() { char a; int r,c,no,j,l; top=0; for(no=0;nt[no]!='\0';no++) { for(i=0;i<nop;i++) { if(nt[no]==p[i][0]) { l=strlen(p[i]); a=p[i][l-1]; if(terminal(A)) { r=nt_no(p[i][0]); c=t_no(a); install(r,c,2); } [i-2])) else if(nonterminal(A) && terminal(p[i] { r=nt_no(p[i][0]); c=t_no(p[i][l-2]); install(r,c,2);

} while(top!=0) { pop(); for(j=0;j<nop;j++) { char nont=p[j][3]; l=strlen(p[j]); if(nont==nr) { r=nt_no(p[j][0]); c=t_no(tr); install(r,c,2); } } } } } } void prec_tab() { int r,c,no,j,l,pos,pl; top=0; for(no=0;no<nop;no++) { l=strlen(p[no]); for(i=3;i<l-2;i++) { }

if(terminal(p[no][i])&& terminal(p[no][i+1])) { r=nt_no(p[no][i]; c=t_no(p[no][i+1]); opt[r][c]='='; } if(i<l-3) { if(terminal(p[no][i] && terminal(p[no][i+2]) && nonterminal(p[no][i+1])) { r=nt_no(p[no][i]; c=t_no(p[no][i+1]); opt[r][c]='='; } } if(terminal(p[no][i]) && nonterminal(p[no][i+1])) { pos=nt_no(p[no][i+1]); for(j=0;j<strlen(t);j++) { if(lead[pos][j]) { r=nt_no(p[no][i]); opt[r][j]='<'; } } } if(terminal(p[no][i]) && nontermianl(p[no][i+1])) { pos=nt_no(p[no][i]); for(j=0;j<strlen(t);j++) { if(trail[pos][j]) { r=nt_no(p[no][i]); opt[j][c]='>'; } } } } } pos=nt_no(starts); l=strlen(t); for(pl=0;pl<strlen(t);pl++) if(lead[pos][p]) opt[l][p]='<'; for(pl=0;pl<strlen(t);pl++) if(trail[pos][p]) opt[l][p]='>'; } void show() { int x,y; printf("\n Leading:");

for(x=0;x<strlen(nt);x++) { printf("\n Leading(%c)={",nt[x]); for(y=0;y<strlen(t);y++) if(lead[x][y]) printf("%c", ", t[y]); printf("}"); } printf("\n Trailing:"); for(x=0;x<strlen(nt);x++) { printf("\n Leading(%c)={", nt[x]); for(y=0;y<strlen(t);y++) if(trail[x][y]) printf("%c",", t[y]); printf("}"); } } void show_tab() { int l=strlen(t),i,j; clrscr(); printf("\n Operator Precedence Grammar:\n\t"); for(i=0;i<=l;i++) printf("\t%c", t[i]); printf("$"); printf("\n _______________\n"); for(i=0;i<=l;i++) { if(i==l) printf("\n $"); else printf("\n %c", t[i]); printf("\t"); for(j=0;j<=l;j++) { if(opt[i][j]=='\0') printf("\t"); else printf("\t%c", opt[i][j]); } printf("\n\t");

} int parse_str(char *str) { char ts,cs; int r,c,pt,pc; stk[top]='$'; printf("\n STACK \t INPUT \t ACTION \n"); printf("%c\t\t%s\t\t\n", stk[top],str);

} printf("\n _________________");

while(l) { if(stk[top]=='$' && str[0]=='$') { printf("%c\t%c\t\t Accept \n", stk[top],str[0]); return 1; } else {

ts=stk[top]; cs=str[0]; r=t_no(ts); c=t_no(cs);

if(opt[r][c]=='<<'||opt[r][c]=='=') { int t=0; printf(" "); while(t<=top) { printf("%c", stk[top]); t++; } top++; stk[top]=cs; printf("%c%c\t", opt[r][c],stk[top]); strlen(str)!=1?strcpy(str,&str[1]):0; printf("%s", str); if(opt[r][c]=='>') printf("\t\t Shift \n"); } else if(opt[r][c]=='>') { do { char pops=stk[top]; int t=0; printf(" "); while(t<=top) { printf("%c",stk[t]); t++ } top--; if(stk[top]!='$') printf("%c%c\t%s\t\t Reduce \n", opt[r] [c],stk[top],str); else printf("%c\t%s\t\t Reduce \n", opt[r][c],str); pt=t_no(stk[top]); pc=t_no(pops);

} while(opt[pt][pc]!='<'); } else } } return 0; } void main() { char *str,string[20]; int l; clrscr(); read_grammar(); clrscr(); leading(); trailing(); clrscr(); show(); getch() prec_tab(); show_tab(); getch(); clrscr(); printf("Enter string to parse:"); scanf("%s", str); l=strlen(str); strcpy(string,str); str[l]='$'; str[l+1]='\0'; if(parse_str(str)) printf("\n String:%s is accepted", str); else printf("\n String:%s is not accepted", str); getch(); } break;

/*** WRITE A PARSER LIKE RECURSIVE DESCENT PARSER ***/ #include<stdio.h> #include<stdlib.h> #include<ctype.h> char next; void E(void); void T(void); void S(void); void F(void); void error(int); void scanf(void); void enter(char); void leave(char); void spaces(int);

int level=0; void main(void) { scan(); E(); if(next!='#') error(1); else printf("Successful Parse\n"); } void E(void) { enter('E'); T(); while(next=='+'||next=='-') { scan(); T(); } leave('E'); } void T(void) { enter('T'); S(); while(next=='*'||next=='/') { scan(); S(); } leave('T'); } void S(void) { enter('S'); F(); if(next=='^') { scan(); S(); } leave('S'); } void F(void) { enter('F'); if(isalpha(next)) { scan(); } else if(next=='(') { scan(); E(); if(next==')') scan(); else error(2); } else { error(3); } leave('F'); }

void scan(void) { while(isspace(next=getchar())) ; } void error(int n) { printf("\n*** ERROR:%i\n", n); exit(1); } void enter(char name) { spaces(level++); printf("+_%c:Enter, \t", name); printf("Next==%c\n", next); } void leave(char name) { spaces(--level); printf("+_%c:Leave,\t", name); printf("Next==%c\n", next); } void spaces(int local_level) { while(local_level-->0) printf("|"); } This Program implements the Predictive Parsing Of the grammar E->E+T/T F->F*T/F F->id(Identifier)
//To Implement Predictive Parsing #include<string.h> #include<conio.h> char a[10]; int top=-1,i; void error(){ printf("Syntax Error"); } void push(char k[]) //Pushes The Set Of Characters on to the Stack { for(i=0;k[i]!='\0';i++) { if(top<9) a[++top]=k[i]; } } char TOS() //Returns TOP of the Stack { return a[top]; }

void pop() //Pops 1 element from the Stack { if(top>=0) a[top--]='\0'; } void display() //Displays Elements Of Stack { for(i=0;i<=top;i++) printf("%c",a[i]); } void display1(char p[],int m) //Displays The Present Input String { int l; printf("\t"); for(l=m;p[l]!='\0';l++) printf("%c",p[l]); } char* stack(){ return a; } int main() { char ip[20],r[20],st,an; int ir,ic,j=0,k; char t[5][6][10]={"$","$","TH","$","TH","$", "+TH","$","e","e","$","e", "$","$","FU","$","FU","$", "e","*FU","e","e","$","e", "$","$","(E)","$","i","$"}; clrscr(); printf("\nEnter any String(Append with $)"); gets(ip); printf("Stack\tInput\tOutput\n\n"); push("$E"); display(); printf("\t%s\n",ip); for(j=0;ip[j]!='\0';) { if(TOS()==an) { pop(); display(); display1(ip,j+1); printf("\tPOP\n"); j++; } an=ip[j]; st=TOS();

if(st=='E')ir=0; else if(st=='H')ir=1; else if(st=='T')ir=2; else if(st=='U')ir=3; else if(st=='F')ir=4; else { error(); break; } if(an=='+')ic=0; else if(an=='*')ic=1; else if(an=='(')ic=2; else if(an==')')ic=3; else if((an>='a'&&an<='z')||(an>='A'&&an<='Z')){ic=4;an='i';} else if(an=='$')ic=5; strcpy(r,strrev(t[ir][ic])); strrev(t[ir][ic]); pop(); push(r); if(TOS()=='e') { pop(); display(); display1(ip,j); printf("\t%c->%c\n",st,238); } else{ display(); display1(ip,j); printf("\t%c->%s\n",st,t[ir][ic]); } if(TOS()=='$'&&an=='$') break; if(TOS()=='$'){ error(); break; } } k=strcmp(stack(),"$"); if(k==0 && i==strlen(ip)) printf("\n Given String is accepted"); else printf("\n Given String is not accepted");

return 0; }
/* Generate the nondeterministic finite state machine for bison,

Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. Bison is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Bison is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bison; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* See comments in state.h for the data structures that represent it. The entry point is generate_states. */ #include #include #include #include #include #include <stdio.h> "system.h" "machine.h" "new.h" "gram.h" "state.h"

extern char *nullable; extern short *itemset; extern short *itemsetend; int nstates; int final_state; core *first_state; shifts *first_shift; reductions *first_reduction; int get_state(); core *new_state(); void new_itemsets(); void append_states(); void initialize_states(); void save_shifts(); void save_reductions(); void augment_automaton(); void insert_start_shift(); extern void initialize_closure(); extern void closure(); extern void finalize_closure(); extern void toomany();

static static static static

core *this_state; core *last_state; shifts *last_shift; reductions *last_reduction;

static int nshifts; static short *shift_symbol; static short *redset; static short *shiftset; static short **kernel_base; static short **kernel_end; static short *kernel_items; /* hash table for states, to recognize equivalent ones. #define STATE_TABLE_SIZE static core **state_table; 1009 */

void allocate_itemsets() { register short *itemp; register int symbol; register int i; register int count; register short *symbol_count; count = 0; symbol_count = NEW2(nsyms, short); itemp = ritem; symbol = *itemp++; while (symbol) { if (symbol > 0) { count++; symbol_count[symbol]++; } symbol = *itemp++; } /* see comments before new_itemsets. All the vectors of items live inside kernel_items. The number of active items after some symbol cannot be more than the number of times that symbol appears as an item, which is symbol_count[symbol]. We allocate that much space for each symbol. */ kernel_base = NEW2(nsyms, short *); kernel_items = NEW2(count, short); count = 0; for (i = 0; i < nsyms; i++)

{ }

kernel_base[i] = kernel_items + count; count += symbol_count[i];

shift_symbol = symbol_count; kernel_end = NEW2(nsyms, short *);

void allocate_storage() { allocate_itemsets(); shiftset = NEW2(nsyms, short); redset = NEW2(nrules + 1, short); state_table = NEW2(STATE_TABLE_SIZE, core *); } void free_storage() { FREE(shift_symbol); FREE(redset); FREE(shiftset); FREE(kernel_base); FREE(kernel_end); FREE(kernel_items); FREE(state_table); }

/* compute the nondeterministic finite state machine (see state.h for details) from the grammar. */ void generate_states() { allocate_storage(); initialize_closure(nitems); initialize_states(); while (this_state) { /* Set up ruleset and itemset for the transitions out of this state. ruleset gets a 1 bit for each rule that could reduce now. itemset gets a vector of all the items that could be accepted next. */ closure(this_state->items, this_state->nitems); /* record the reductions allowed out of this state */ save_reductions(); /* find the itemsets of the states that shifts can reach */ new_itemsets();

/* find or create the core structures for those states */ append_states(); /* create the shifts structures for the shifts to those states, now that the state numbers transitioning to are known */ if (nshifts > 0) save_shifts(); /* states are queued when they are created; process them all */ this_state = this_state->next; } /* discard various storage */ finalize_closure(); free_storage(); /* set up initial and final states as parser wants them */ augment_automaton(); }

/* Find which symbols can be shifted in the current state, and for each one record which items would be active after that shift. Uses the contents of itemset. shift_symbol is set to a vector of the symbols that can be shifted. For each symbol in the grammar, kernel_base[symbol] points to a vector of item numbers activated if that symbol is shifted, and kernel_end[symbol] points after the end of that vector. */ void new_itemsets() { register int i; register int shiftcount; register short *isp; register short *ksp; register int symbol; #ifdef TRACE fprintf(stderr, "Entering new_itemsets\n"); #endif for (i = 0; i < nsyms; i++) kernel_end[i] = NULL; shiftcount = 0; isp = itemset; while (isp < itemsetend) { i = *isp++; symbol = ritem[i]; if (symbol > 0) { ksp = kernel_end[symbol];

if (!ksp) { shift_symbol[shiftcount++] = symbol; ksp = kernel_base[symbol]; } *ksp++ = i + 1; kernel_end[symbol] = ksp; } } }

nshifts = shiftcount;

/* Use the information computed by new_itemsets to find the state numbers reached by each shift transition from the current state. shiftset is set up as a vector of state numbers of those states. void append_states() { register int i; register int j; register int symbol; #ifdef TRACE fprintf(stderr, "Entering append_states\n"); #endif /* first sort shift_symbol into increasing order */ for (i = 1; i < nshifts; i++) { symbol = shift_symbol[i]; j = i; while (j > 0 && shift_symbol[j - 1] > symbol) { shift_symbol[j] = shift_symbol[j - 1]; j--; } shift_symbol[j] = symbol; } for (i = 0; i < nshifts; i++) { symbol = shift_symbol[i]; shiftset[i] = get_state(symbol); } */

/* find the state number for the state we would get to (from the current state) by shifting symbol.

Create a new state if no equivalent one exists already. Used by append_states */ int get_state(symbol) int symbol; { register int key; register short *isp1; register short *isp2; register short *iend; register core *sp; register int found; int n; #ifdef TRACE fprintf(stderr, "Entering get_state, symbol = %d\n", symbol); #endif isp1 = kernel_base[symbol]; iend = kernel_end[symbol]; n = iend - isp1; /* add up the target state's active item numbers to get a hash key */ key = 0; while (isp1 < iend) key += *isp1++; key = key % STATE_TABLE_SIZE; sp = state_table[key]; if (sp) { found = 0; while (!found) { if (sp->nitems == n) { found = 1; isp1 = kernel_base[symbol]; isp2 = sp->items; while (found && isp1 < iend) { if (*isp1++ != *isp2++) found = 0; }

if (!found) { if (sp->link) { sp = sp->link; }

} } else { } } }

else /* bucket exhausted and no match */ { sp = sp->link = new_state(symbol); found = 1; }

/* bucket is empty */ state_table[key] = sp = new_state(symbol);

return (sp->number);

/* subroutine of get_state. necessary. */ core * new_state(symbol) int symbol; { register int n; register core *p; register short *isp1; register short *isp2; register short *iend;

create a new state for those items, if

#ifdef TRACE fprintf(stderr, "Entering new_state, symbol = %d\n", symbol); #endif if (nstates >= MAXSHORT) toomany("states"); isp1 = kernel_base[symbol]; iend = kernel_end[symbol]; n = iend - isp1; p = (core *) xmalloc((unsigned) (sizeof(core) + (n - 1) * sizeof(short))); p->accessing_symbol = symbol; p->number = nstates; p->nitems = n; isp2 = p->items; while (isp1 < iend) *isp2++ = *isp1++; last_state->next = p; last_state = p; nstates++;

return (p);

void initialize_states() { register core *p; /* register unsigned *rp1; JF unused */ /* register unsigned *rp2; JF unused */ /* register unsigned *rend; JF unused */ p = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); first_state = last_state = this_state = p; nstates = 1;

void save_shifts() { register shifts *p; register short *sp1; register short *sp2; register short *send; p = (shifts *) xmalloc((unsigned) (sizeof(shifts) + (nshifts - 1) * sizeof(short))); p->number = this_state->number; p->nshifts = nshifts; sp1 = shiftset; sp2 = p->shifts; send = shiftset + nshifts; while (sp1 < send) *sp2++ = *sp1++; if (last_shift) { last_shift->next = p; last_shift = p; } else { first_shift = p; last_shift = p; }

/* find which rules can be used for reduction transitions from the current state and make a reductions structure for the state to record their rule numbers. */

void save_reductions() { register short *isp; register short *rp1; register short *rp2; register int item; register int count; register reductions *p; short *rend; /* find and count the active items that represent ends of rules */ count = 0; for (isp = itemset; isp < itemsetend; isp++) { item = ritem[*isp]; if (item < 0) { redset[count++] = -item; } } /* make a reductions structure and copy the data into it. */

if (count) { p = (reductions *) xmalloc((unsigned) (sizeof(reductions) + (count - 1) * sizeof(short))); p->number = this_state->number; p->nreds = count; rp1 = redset; rp2 = p->rules; rend = rp1 + count; while (rp1 < rend) *rp2++ = *rp1++; if (last_reduction) { last_reduction->next = p; last_reduction = p; } else { first_reduction = p; last_reduction = p; } } }

/* Make sure that the initial state has a shift that accepts the grammar's start symbol and goes to the next-to-final state, which has a shift going to the final state, which has a shift to the termination state. Create such states and shifts if they don't happen to exist already. void augment_automaton() { register int i; register int k; /* register int found; JF unused */ register core *statep; register shifts *sp; register shifts *sp2; register shifts *sp1; sp = first_shift; if (sp) { if (sp->number == 0) { k = sp->nshifts; statep = first_state->next;

*/

/* The states reached by shifts from first_state are numbered 1...K. Look for one reached by start_symbol. */ while (statep->accessing_symbol < start_symbol && statep->number < k) statep = statep->next; if (statep->accessing_symbol == start_symbol) { /* We already have a next-to-final state. Make sure it has a shift to what will be the final */ k = statep->number; while (sp && sp->number < k) { sp1 = sp; sp = sp->next; } if (sp && sp->number == k) { sp2 = (shifts *) xmalloc((unsigned) (sizeof(shifts) + sp->nshifts * sizeof(short))); sp2->number = k; sp2->nshifts = sp->nshifts + 1; sp2->shifts[0] = nstates; for (i = sp->nshifts; i > 0; i--) sp2->shifts[i] = sp->shifts[i - 1]; /* Patch sp2 into the chain of shifts in place of sp,

state.

following sp1. */ sp2->next = sp->next; sp1->next = sp2; if (sp == last_shift) last_shift = sp2; FREE(sp); } else { sp2 = NEW(shifts); sp2->number = k; sp2->nshifts = 1; sp2->shifts[0] = nstates; sp. */ /* Patch sp2 into the chain of shifts between sp1 and sp2->next = sp; sp1->next = sp2; if (sp == 0) last_shift = sp2; } else { }

/* There is no next-to-final state as yet. */ /* Add one more shift in first_shift, going to the next-to-final state (yet to be made). sp = first_shift;

*/

sp2 = (shifts *) xmalloc(sizeof(shifts) + sp->nshifts * sizeof(short)); sp2->nshifts = sp->nshifts + 1; /* Stick this shift into the vector at the proper place. */ statep = first_state->next; for (k = 0, i = 0; i < sp->nshifts; k++, i++) { if (statep->accessing_symbol > start_symbol && i == k) sp2->shifts[k++] = nstates; sp2->shifts[k] = sp->shifts[i]; statep = statep->next; } if (i == k) sp2->shifts[k++] = nstates; /* Patch sp2 into the chain of shifts in place of sp, at the beginning. */ sp2->next = sp->next; first_shift = sp2; if (last_shift == sp) last_shift = sp2; FREE(sp); /* Create the next-to-final state, with shift to what will be the final state. */

insert_start_shift();

} else { /* The initial state didn't even have any shifts. Give it one shift, to the next-to-final state. sp = NEW(shifts); sp->nshifts = 1; sp->shifts[0] = nstates;

*/

/* Patch sp into the chain of shifts at the beginning. sp->next = first_shift; first_shift = sp; /* Create the next-to-final state, with shift to what will be the final state. */ insert_start_shift(); } else { }

*/

/* There are no shifts for any state. Make one shift, from the initial state to the next-to-final state. */ sp = NEW(shifts); sp->nshifts = 1; sp->shifts[0] = nstates; /* Initialize the chain of shifts with sp. first_shift = sp; last_shift = sp; */

/* Create the next-to-final state, with shift to what will be the final state. */ insert_start_shift();

/* Make the final state--the one that follows a shift from the next-to-final state. The symbol for that shift is 0 (end-of-file). */ statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); statep->number = nstates; last_state->next = statep; last_state = statep; /* Make the shift from the final state to the termination state. sp = NEW(shifts); sp->number = nstates++; sp->nshifts = 1; sp->shifts[0] = nstates; last_shift->next = sp; last_shift = sp; */

/* Note that the variable `final_state' refers to what we sometimes call

the termination state. final_state = nstates;

*/

/* Make the termination state. */ statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); statep->number = nstates++; last_state->next = statep; last_state = statep; } /* subroutine of augment_automaton. Create the next-to-final state, to which a shift has already been made in the initial state. */ void insert_start_shift() { register core *statep; register shifts *sp; statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); statep->number = nstates; statep->accessing_symbol = start_symbol; last_state->next = statep; last_state = statep; /* Make a shift from this state to (what will be) the final state. sp = NEW(shifts); sp->number = nstates++; sp->nshifts = 1; sp->shifts[0] = nstates; last_shift->next = sp; last_shift = sp; } */

You might also like