You are on page 1of 34

EXPERIMENT-1 Q. Develop a lexical analyzer to recognize a few patterns.

PROGRAM: #include #include #include #include #include #define SIZE 128 #define NONE -1 #define EOS \0 #define NUM 256 #define KEYWORD 257 #define PAREN 258 #define ID 259 #define ASSIGN 260 #define REL_OP 261 #define DONE 262 #define MAX 999 char lexemes[MAX]; char buffer[SIZE]; int lastchar = -1; int lastentry = 0; int tokenval=NONE; int lineno=1; struct entry { char *lexptr; int token; }symtable[100]; struct entry keywords[]={if,KEYWORD,else,KEYWORD,for,KEYWORD, int,KEYWORD,float,KEYWORD,double,KEYWORD,char,KEY WORD, struct,KEYWORD,return,KEYWORD,0,0}; void Error_Message(char *m) { fprint(stderr,line %d: %s,lineno,m); exit(1);

} int look_up(char s[]) { int k; for(k=lastentry;k>0;k--) if(strcmp(symtable[k].lexptr,s)==0) return k; return 0; } int insert(chars[],int tok) { int len; len=strlen(s); if(lastentry+1>=MAX) Error_Message(Symbol Table is Full); if(lastchar+len+1>=MAX) Error_Message(Lexemes Array is Full); lastentry++; symtable[lastentry].token=tok; symtable[lastentry].lexptr=&lexemes[lastcher+1]; lastchar = lastchar + len + 1; strcpy(smtable[lastentry].lexptr,s); return lastentry; } void Initialize() { struct entry *ptr; for(ptr=keywords;ptr->token;ptr++) insert(ptr->lexptr,ptr->token); } int lexer() { int t; int val,i=0; while(1) { t=getchar(); if(t == || t==\t); else if(t==\n) lineno++;

else if(t == ( || t == )) return PAREN; else if(t==< ||t==> ||t==<= ||t==>= ||t == !=) return REL_OP; else if(t == =) return ASSIGN; else if(isdigit(t)) { ungetc(t,stdin); scanf(%d,&tokenval); return NUM; } else if(isalpha(t)) { while(isalnum(t)) { buffer[i]=t; t=getchar(); i++; if(i>=SIZE) Error_Message(compiler error); } buffer[i]=EOS; if(t!=EOF) ungetc(t,stdin); val=look_up(buffer); if(val==0) val=insert(buffer,ID); tokenval=val; return symtable[val].token; } else if(t==EOF) return DONE; else { tokenval=NONE; return t; } } }

void main() { int lookahead; char ans; clrscr(); printf(\n]t]t Program for Lexical Analysis \n); Initialize(); printf(\n Enter the expression and put ; at the end); printf(\n Press Ctrl + Z to terminate... \n); lookahead=lexer(); while(lookahead!=DONE) { if(lookahead==NUM) printf(\n Number: %d,tokenval); if(lookahead==+|| lookahead==-|| lookahead==*|| lookahead==/) printf(\n Operator); if(lookahead==PAREN) printf(\n Parentesis); if(lookahead==ID) printf(\n Identifier: %s, symtable[tokenval].lexptr); if(lookahead==KEYWORD) printf(\n Keyword); if(lookahead==ASSIGN) printf(\n Assignment Operator); if(lookahead==REL_OP) printf(\n Relataional Operator); lookahead=lexer(); } }

OUTPUT: Program for Lexical Analysis Enter the expression and put ; at the end Press Ctrl + Z to terminate ... 2+3 Number: 2 Operator Number: 3 if(a Keyword Parenthesis Identifier: a Relational Operator Identifier: b Parenthesis Identifier: a Assigment Operator Identifier: a Operator Identifier: b ^Z

EXPERIMENT-2
Q. Develop LL (1) parser (Construct parse table also). PROGRAM: #include <iostream.h> #include <conio.h> #include <string.h> #include <stdio.h> #include <stdlib.h> void main() { clrscr(); int i=0,j=0,k=0,m=0,n=0,o=0,o1=0,var=0,l=0,f=0,c=0,f1=0; char str[30],str1[40]="E",temp[20],temp1[20],temp2[20],tt[20],t3[20]; strcpy(temp1,'\0'); strcpy(temp2,'\0'); char t[10]; char array[6][5][10] = { "NT", "<id>","+","*",";", "E", "Te","Error","Error","Error", "e", "Error","+Te","Error","\0", "T", "Vt","Error","Error","Error", "t", "Error","\0","*Vt","\0", "V", "<id>","Error","Error","Error" }; cout << "\n\tLL(1) PARSER TABLE \n"; for(i=0;i<6;i++) { for(j=0;j<5;j++) { cout.setf(ios::right); cout.width(10); cout<<array[i][j]; } cout<<endl; } cout << endl; cout << "\n\tENTER THE STRING :"; gets(str);

if(str[strlen(str)-1] != ';') { cout << "END OF STRING MARKER SHOULD BE ';'"; getch(); exit(1); } cout << "\n\tCHECKING VALIDATION OF THE STRING "; cout <<"\n\t" << str1; i=0; while(i<strlen(str)) { again: if(str[i] == ' ' && i<strlen(str)) { cout << "\n\tSPACES IS NOT ALLOWED IN SOURSE STRING "; getch(); exit(1); } temp[k]=str[i]; temp[k+1]='\0'; f1=0; again1: if(i>=strlen(str)) { getch(); exit(1); } for(int l=1;l<=4;l++) { if(strcmp(temp,array[0][l])==0) { f1=1; m=0,o=0,var=0,o1=0; strcpy(temp1,'\0'); strcpy(temp2,'\0'); int len=strlen(str1); while(m<strlen(str1) && m<strlen(str)) { if(str1[m]==str[m])

{ var=m+1; temp2[o1]=str1[m]; m++; o1++; } else { if((m+1)<strlen(str1)) { m++; temp1[o]=str1[m]; o++; } else m++; } } temp2[o1] = '\0'; temp1[o] = '\0'; t[0] = str1[var]; t[1] = '\0'; for(n=1;n<=5;n++) { if(strcmp(array[n][0],t)==0) break; } strcpy(str1,temp2); strcat(str1,array[n][l]); strcat(str1,temp1); cout << "\n\t" <<str1; getch(); if(strcmp(array[n][l],'\0')==0) { if(i==(strlen(str)-1)) { int len=strlen(str1); str1[len-1]='\0';

cout << "\n\t"<<str1; cout << "\n\n\tENTERED STRING IS getch(); exit(1); } strcpy(temp1,'\0'); strcpy(temp2,'\0'); strcpy(t,'\0'); goto again1; } if(strcmp(array[n][l],"Error")==0) { cout << "\n\tERROR IN YOUR SOURCE STRING"; getch(); exit(1); } strcpy(tt,'\0'); strcpy(tt,array[n][l]); strcpy(t3,'\0'); f=0; for(c=0;c<strlen(tt);c++) { t3[c]=tt[c]; t3[c+1]='\0'; if(strcmp(t3,temp)==0) { f=0; break; } else f=1; } if(f==0) { strcpy(temp,'\0'); strcpy(temp1,'\0'); strcpy(temp2,'\0'); strcpy(t,'\0'); i++;

VALID";

k=0; goto again; } else { strcpy(temp1,'\0'); strcpy(temp2,'\0'); strcpy(t,'\0'); goto again1; } } } i++; k++; } if(f1==0) cout << "\nENTERED STRING IS INVALID"; else cout << "\n\n\tENTERED STRING IS VALID"; getch(); }

OUTPUT : LL(1) PARSER TABLE NT <id> + E Te Error e Error +Te T Vt Error t Error V <id> Error * ; Error Error Error Error Error *Vt Error Error

ENTER THE STRING :<id>+<id>*<id>; CHECKING VALIDATION OF THE STRING E Te Vte <id>te <id>e <id>+Te <id>+Vte <id>+<id>te <id>+<id>*Vte <id>+<id>*<id>te <id>+<id>*<id>e <id>+<id>*<id> ENTERED STRING IS VALID

EXPERIMENT-3
Q. Write A Program to Simulate Heap Storage Allocation Strategy. PROGRAM: #include"stdio.h" #include"conio.h" #include"stdlib.h" #define TRUE 1 #include FALSE 0 typedef struct Heap { int data; struct Heap *next; }node; node *create(); void main() { /*local declarations*/ int choice,val; char ans; node *head; void display(node *); node *search(node *,int); node *insert(node *); void dele(node **); head=NULL; do { clrscr(); printf(\n Program to perform various operations on heap using dynamic memory management); printf (\n1.Create): printf (\n2.Display): printf (\n3.Insert an element in a list); printf (\n4.Delete an element from list); printf (\n5.Quit); printf (\n Enter Your Choice(1-5));

scanf(%d,&choice); switch(choice) { case 1:head=create(); break; case 2:display(head); break; case 3:head=insert(head); break; case 4:dele(&head); break; case 5:exit(0); default:clrscr(); printf(Invalid Choice,Try again); getch(); } }while(choice!=5); } /*The create function creates a list of allocated node *Input:None *Output:Retyurns a pointer to head of list *Parameter Passing Methopd:Node **/ node *create() { node *temp,*new,* head; int val,flag; char ans=y; node *get_node(); temp=NULL; flag=TRUE; /*flag to indicate whether a new node is created for the first time or not*/ do { printf(\n Enter the Element); scanf(%d,&val); /*allocate new node*/ new =get_node();

if(new==NULL) printf(\n Memory is not allocated); new-> data=val; if (flag==TRUE)/* Executed only for the first time*/ { head=new; temp=head; /*head is the first node in the heap*/ flag=FALSE; } else { /*temp keeps track of the most recently created node*/ temp->next=new; temp=new; } printf(\nDo you want to enter more elements?(y/n)); ans=getch(); }while(ans= = y); printf(\nThe list is created); getch(); clrscr(); return head; } node *get_node() { node *temp; temp=(node*)malloc(sizeof(node)); //using the mem. Allocation function temp->next=NULL; return temp; } /* *The display function *Input:Address of the first node of the list *Output:Displays the list of allocated nodes

*Parameter Passing Method : call by value *Called by main **/ void display(node*head) { node *temp; temp=head; if(temp= =NULL) { printf(\n The list is empty\n); getch(); clrscr(); return; } while(temp!= NULL) { printf(%d->,temp-> data); temp=temp->next; } print(NULL); getch(); clrscr(); } /* *The search function *Input: Address of the starting node and the element which is *to be searched *Output:Searches for the element in list *If found returns pointer to that node Otherwise NULL *Parameter passing Method:call by value *Called by:main *Calls:None **/ node *search(node *head,int key) { node*temp; int found; temp=head;

if (temp= =Null) { printf(The linked list is empty\n); getch(); clrscr(); return NULL; } found=FALSE; While(temp!= NULL && found= =FALSE) { if(temp->data != key) temp = temp->next; else found = True; } if(found == TRUE) { printf(\n The Elements is present in the list\n); getch(); return temp; } else printf(\n The Element is not present in the list\n); getch(); return NULL; } /* *The insert function *Input: Address of starting node of the list *Output:inserts element into the list *Parameter Passing Methods: call by value *Called by : main *Calls : search() **/ node *insert(node *head) {

int choice; node *insert_head(node*); void insert_after(node*); void insert_last(node*); printf(\n1.Insert a node as a head node); printf(\n1.Insert a node as a last node); printf(\n1.Insert a node as at the intermediate position in the list ); printf(\n1.Enter your choice for insertion of node ); scanf(%d,&choice); switch(choice) { case 1:head = insert_head(head); break; case2:insert_last(head); break; case2:insert_after (head); break; } return head; } /*Insertion of node at first position*/ node *insert_head(node*head) { node *New,*temp; New = get_node(); printf (\n Enter the element which you want to insert ); scanf(%d,&New->data); if(head == NULL) head = New; else { temp=head; New->next = temp; head= New; } return head; }

/*Insertion of node at last position*/ void insert_last(node *head) { node *New,*temp; New = get_node(); printf (\n Enter the element which you want to insert ); scanf(%d,&New->data); if(head == NULL) { head = New; } else { temp=head; while(temp->next!=NULL) temp=temp->next; temp->next=New; New->next=NULL; } } /*Insertion of node at intermediate position*/ void insert_after(node *head) { int key; node *New,*temp; New = get_node(); printf(Enter the element after which you want to insert ); scanf(%d,&key); temp=head; do { if(temp->data==key) { printf (Enter element which you want to insert ); scanf(%d,&New->data); New->next=temp->next;

temp->next=New; return; } else temp=temp->next; }while(temp!=NULL); } /* *The get prev function *Input: Address of starting node and the elemnt to be *searched *Output:looks for the element in the list *If found returns pointer to the previous node otherwise NULL *Parameter Passing Methods: call by value *Called by : dele() *Calls : none **/ node *get_prev(node *head,int val) { node*temp.*prev; int flag; temp = head; if(temp == NULL) return NULL; flag = FALSE; prev = NULL; while(temp!=NULL && !flag) { if(temp->data!=val) { prev = temp; temp = temp->next; } else flag = TRUE; } if(flag) /*if Flag is true*/ return prev;

else return NULL; } /* *The get prev function *Input: Address of starting node and the elemnt to be *searched *Output:looks for the element in the list *If found returns pointer to the previous node otherwise NULL *Parameter Passing Methods: call by value *Called by : dele() *Calls : none **/ void dele(node **head) { int key; node *New,*temp; temp=*head; if (temp== NULL) { printf (\n The list is empty\n ); getch(); clrscr(); return; } clrscr(); printf("\nENTER the Element you want to delete:"); scanf("%d".&key); temp= search(*head,key); if(temp !=NULL) { prev = get_prev(*head,key); if(prev != NULL) { prev ->next = temp-> next; free(temp); } else

{ *head = temp->next; free(temp); // using the mem. Dellocation function } printf(\nThe Element is deleted\n); getch(); clrscr(); } }

EXPERIMENT-4

Q. Develop a Recursive Decent Parser. PROGRAM: #include"stdio.h" #include"conio.h" #include"string.h" #include"stdlib.h" #include"ctype.h"

char ip_sym[15],ip_ptr=0,op[50],tmp[50]; void e_prime(); void e(); void t_prime(); void t(); void f(); void advance(); int n=0; void e() { strcpy(op,"TE'"); printf("E=%-25s",op); printf("E->TE'\n"); t(); e_prime(); } void e_prime() { int i,n=0,l; for(i=0;i<=strlen(op);i++) if(op[i]!='e') tmp[n++]=op[i]; strcpy(op,tmp); l=strlen(op);

for(n=0;n < l && op[n]!='E';n++);<l&&op[n]!='e';n++);></l&&op[n]!='e';n++);> if(ip_sym[ip_ptr]=='+') { i=n+2; do { op[i+2]=op[i]; i++; }while(i<=l); op[n++]='+'; op[n++]='T'; op[n++]='E'; op[n++]=39; printf("E=%-25s",op); printf("E'->+TE'\n"); advance(); t(); e_prime(); } else { op[n]='e'; for(i=n+1;i<=strlen(op);i++) op[i]=op[i+1]; printf("E=%-25s",op); printf("E'->e"); } } void t() { int i,n=0,l; for(i=0;i<=strlen(op);i++) if(op[i]!='e') tmp[n++]=op[i]; strcpy(op,tmp); l=strlen(op); for(n=0;n < l && op[n]!='T';n++); <l&&op[n]!='t';n++);></l&&op[n]!='t';n++);> i=n+1; do

{ op[i+2]=op[i]; i++; }while(i < l); op[n++]='F'; op[n++]='T'; op[n++]=39; printf("E=%-25s",op); printf("T->FT'\n"); f(); t_prime(); } void t_prime() { int i,n=0,l; for(i=0;i<=strlen(op);i++) if(op[i]!='e') tmp[n++]=op[i]; strcpy(op,tmp); l=strlen(op); for(n=0;n < l && op[n]!='T';n++); if(ip_sym[ip_ptr]=='*') { i=n+2; do { op[i+2]=op[i]; i++; }while(i < l); op[n++]='*'; op[n++]='F'; op[n++]='T'; op[n++]=39; printf("E=%-25s",op); printf("T'->*FT'\n"); advance(); f(); t_prime(); }

else { op[n]='e'; for(i=n+1;i<=strlen(op);i++) op[i]=op[i+1]; printf("E=%-25s",op); printf("T'->e\n"); } } void f() { int i,n=0,l; for(i=0;i<=strlen(op);i++) if(op[i]!='e') tmp[n++]=op[i]; strcpy(op,tmp); l=strlen(op); for(n=0;n < l && op[n]!='F';n++); if((ip_sym[ip_ptr]=='i')||(ip_sym[ip_ptr]=='I')) { op[n]='i'; printf("E=%-25s",op); printf("F->i\n"); advance(); } else { if(ip_sym[ip_ptr]=='(') { advance(); e(); if(ip_sym[ip_ptr]==')') { advance(); i=n+2; do { op[i+2]=op[i]; i++;

}while(i<=l); op[n++]='('; op[n++]='E'; op[n++]=')'; printf("E=%-25s",op); printf("F->(E)\n"); } } else { printf("\n\t syntax error"); getch(); exit(1); } } } void advance() { ip_ptr++; } void main() { int i; clrscr(); printf("\nGrammar without left recursion"); printf("\n\t\t E->TE' \n\t\t E'->+TE'|e \n\t\t T->FT' "); printf("\n\t\t T'->*FT'|e \n\t\t F->(E)|i"); printf("\n Enter the input expression:"); gets(ip_sym); printf("Expressions"); printf("\t Sequence of production rules\n"); e(); for(i=0;i < strlen(ip_sym);i++) { if(ip_sym[i]!='+'&&ip_sym[i]!='*'&&ip_sym[i]!='('&& ip_sym[i]!=')'&&ip_sym[i]!='i'&&ip_sym[i]!='I') { printf("\nSyntax error");

break; } for(i=0;i<=strlen(op);i++) if(op[i]!='e') tmp[n++]=op[i]; strcpy(op,tmp); printf("\nE=%-25s",op); } getch(); }

OUTPUT:

EXPERIMEXT-5

Q. Develop a Operator Precedence Parser(Construct Parse table Also). PROGRAM: #include #include #include void main() { int i,j,x,x1,k,k1,z1,z; char a[20],b[20][20],c[20],p[10]="*+$"; char fp[10][10]={"id1","id2","id3"},d[10]; clrscr(); printf("ENTER INPUT STRING: "); gets(a); i=0;j=0;x=0;x1=0; printf("$ "); while(a[i]!='\0') { j=0; while(1) { if(a[i]!='+' && a[i]!='*' && a[i]!='$') { b[x][j]=a[i]; i++; j++; } else { c[x]=a[i]; break; } } b[x][j]='\0'; for(k=0;k<3;k++) if(!strcmp(b[x],fp[k]))

for(k1=0;k1<3;k1++) if(c[x]==p[k1]) printf("< %s > %c ",b[x],c[x]); x++; i++; } c[x]='\0'; i=0; printf("\n$ <"); while(c[i]!='\0') { for(k=0;k<3;k++) if(c[i]==p[k]) z=k; i++; printf(" %c",c[i-1]); for(k=0;k<3;k++) if(c[i]==p[k]) z1=k; i++; if(z>z1) printf(" <"); else printf(" >"); printf(" %c",c[i-1]); i++; } printf(" > $"); for(i=0;i<3;i++) { if(c[i]==p[0]) c[i]=' '; } i=0; printf("\n$ <"); for(k=0;k<3;k++) if(c[i]==p[k]) z=k; printf(" %c",c[i]); i++;

i++; for(k=0;k<3;k++) if(c[i]==p[k]) z1=k; if(z>z1) printf(" <"); else printf(" >"); printf(" %c",c[i]); getch(); }

EXPERIMENT-6
Q. Given any intermediate code form implement code optimization techniques. PROGRAM: " The code optimization phase attempts to improve the intermediate code, so that faster running machine code will result. the term code optimization refers to techniques a compiler can employ in an attempt to produce a better language program then the most obvious for a given source program. The code generator produces the target program from the transformed intermediate code. In the code optimizer, programs are represented by flow graphs, in which edges indicate the flow of control and nodes represents basic blocks. Many ways to improve the program without changing function it computes, such as copy propagation, constant folding, dead code elimination and common sub expression elimination. #include<stdio.h> #include<conio.h> #define BLOCKSIZE (8) void main(void) { int i = 0; int limit = 33; /* could be anything */ int blocklimit; /* The limit may not be divisible by BLOCKSIZE, * go as near as we can first, then tidy up. */ blocklimit = (limit / BLOCKSIZE) * BLOCKSIZE; clrscr(); /* unroll the loop in blocks of 8 */ while( i < blocklimit ) { printf("process(%d)\n", i); printf("process(%d)\n", i+1); printf("process(%d)\n", i+2); printf("process(%d)\n", i+3); printf("process(%d)\n", i+4); printf("process(%d)\n", i+5); printf("process(%d)\n", i+6); printf("process(%d)\n", i+7); /* update the counter */

i += 8; } OUTPUT: process(0) process(1) process(2) process(3) process(4) process(5) process(6) process(7) process(8) process(9) process(10) process(11) process(12) process(13) process(14) process(15) process(16) process(17) process(18) process(19) process(20) process(21) process(22) process(23) process(24)

EXPERIMENT-7
Q. Study of an Object Oriented Compiler. PROGRAM: A Compiler is a program that can read a program in one language the source language and translate it into an equivalent program in another language the Target language . An important role of the compiler is to report any errors in the source program that it detects during the translation process. An object-oriented language is one that supports object-oriented programming, a programming style in which a program consists of a collection of objects (i.e. classes) that interact with one another. The obvious candidate for object technology in a compiler is the symbol table, a mapping from user-defined names to their properties as expressed in the program. If the internal representation is a tree of objects, semantic checking and generation can be accomplished by sending a message to these objects or by visiting each object. If the result of generation is a set of persistent objects, program execution can consist of sending a message to a distinguished object in this set. Object orientation was first introduced in Simula ( in 1967), and has been incorporated in languages such as Smalltalk, C++, C#, and Java. We have gained them in several projects and used them to great advantage in two courses on compiler construction with Objective C and Java It turns out that OOP can be applied productively in every phase of a compiler implementation and it delivers the expected benefits as : Objects enforce information hiding and state encapsulation, Methods help to develop by divide and conquer technique. All work is carried out by messages , which can be debugged by instrumenting their methods. Most importantly, classes encourage code reuse between projects . Inheritance allows code reuse within a project and modifications from one project to another. Modern class libraries contain many pre-fabricated algorithms and data structures.

EXPERIMENT-8
Q. Write a programme to parse using Brute force technique of Topdown parsing. PROGRAM: #include<stdio.h> #include<conio.h> #include<iostream.h> void main() { int a[30]; clrscr(); int min=1000,temp=0,I,lev,n,noofc,z; printf(please enter how many number); cin>>n; for(i=1;i<n;i++) a[i]=0; cout<<enter the value of root; cin>>a[0]; for(i=1;i<=n/2;i++) { cout<<please enter no. of child of parent with value<<a[i-1]<<:; cin>>noofc; } for(int j=j+1;j>=1;j++) { temp=0; for(int j=j+1;j>=1;j=j/2) temp=temp+a[j-1]; if(temp<min) min=temp; cout<<temp min is:<<temp<<\n; } } cout<<min is<<min; getch(); }

You might also like