Sunteți pe pagina 1din 45

1. Develop a lexical analyzer to recognize a few patterns in PASCAL and C. (Ex. identifiers, constants, comments, operators etc.

)
#include<stdio.h> #include<conio.h> #include<ctype.h> #include<string.h> #include<stdlib.h> #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,KEYWORD, 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<b) a=a+b; Keyword Parenthesis Identifier: a Relational Operator Identifier: b Parenthesis Identifier: a Assigment Operator Identifier: a Operator Identifier: b ^Z

2. Develop a recursive decent parser

#include<stdio.h> #include<ctype.h> #include<stdlib.h> #include<string.h> #define #define #define #define #define #define #define #define SIZE 128 NONE -1 EOS '\0' NUM 257 KEYWORD 258 ID 259 DONE 260 MAX 999

char lexemes[MAX]; char buffer[SIZE]; int lastchar=-1; int lastentry=0; int tokenval=DONE; int lineno=1; int lookahead; struct entry { char *lexptr; int token; }symtable[100]; struct entry keywords[]={"if",KEYWORD,"else",KEYWORD,"for",KEYWORD, "int",KEYWORD,"float",KEYWORD,"double",KEYWORD, "char",KEYWORD,"struct",KEYWORD,"return",KEYWORD, 0,0}; void errormsg(char *m) { fprintf(stderr,"line %d:%s\n",lineno,m); exit(1); } int lookup(char s[]) { int k; for(k=lastentry;k>0;k=k-1) if(strcmp(symtable[k].lexptr,s)==0) return k; return 0; } int insert(char s[],int tok) {

int len; len=strlen(s); if(lastentry+1>=MAX) errormsg("symtable is full"); if(lastentry+len+1>=MAX) errormsg("lexemes array is full"); lastentry=lastentry+1; symtable[lastentry].token=tok; symtable[lastentry].lexptr=&lexemes[lastchar+1]; lastchar=lastchar+len+1; strcpy(symtable[lastentry].lexptr,s); return lastentry; } void initialise() { 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=lineno+1; 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=i+1; if(i>=SIZE) errormsg("compile error"); } buffer[i]=EOS; if(t!=EOF) ungetc(t,stdin); val=lookup(buffer); if(val==0) val=insert(buffer,ID); tokenval=val; return symtable[val].token; } else if(t==EOF)

return DONE; else { } } } void match(int t) { if(lookahead==t) lookahead=lexer(); else errormsg("syntax error"); } void display(int t,int tval) { if(t=='+'||t=='-'||t=='*'||t=='/') printf("\n arithmetic operator %c",t); else if(t==NUM) printf("\n number %d",tval); else if(t==ID) printf("\n identifier:%s",symtable[tval].lexptr); else printf("\n token:%d tokenval %d",t,tokenval); } tokenval=NONE; return t;

void F() { void E(); switch(lookahead) { case '(': match('('); E(); match(')'); break; case NUM: display(NUM,tokenval); match(NUM); break; case ID: display(ID,tokenval); match(ID); break; default: errormsg("syntax error"); } } void T() { int t; F(); while(1) { switch(lookahead)

{ case '*': t=lookahead; match(lookahead); F(); display(t,NONE); continue; case '/': t=lookahead; match(lookahead); F(); display(t,NONE); continue; default: return; } } } void E() { int t; T(); while(1) { switch(lookahead) { case '+': t=lookahead; match(lookahead); T(); display(t,NONE); continue; case '-': t=lookahead; match(lookahead); T(); display(t,NONE); continue; default: return; } } } void parser() { lookahead=lexer(); while(lookahead!=DONE) { E(); match(';'); } } int main() { char ans; clrscr();

printf("\n \t \t Program for recursive decent parsing"); initialise(); printf("enter the expression & place;at the end \n Press CTRL + Z to terminate"); parser(); return 0; }

OUTPUT:
Program for recursive decent parsing Enter the expression & place ; at the end Press CTRL + Z to terminate 2+3*4; number 2 number 3 number 4 arithmetic operator * arithmetic operator + 2+3*4+5; number 2 number 3 number 4 arithmetic operator * arithmetic operator + number 5 arithmetic operator + a-b; identifier a identifier b arithmetic operator +1 Line7: syntaxerror

3. Write a program for generating for various intermediate code forms: Three address code Quadruple
/* %{ #includey.tab.h extern char yyval; %} NUMBER [0-9]+ LETTER [a-zA-Z]+ %% {NUMBER} {yylval.sym=(char)yytext[0];return NUMBER;} {LETTER} {yylval.sym=(char)yytext[0];return LETTER;} \n %% /* Program name: intcode.y */ {return 0;} {return yytext[0];} Program name: intcode.l */

%{ #include<stdio.h> #include<string.h> int nIndex=0; struct InterCode { char operand1; char operand2; char opera; }; %} %union { char sym; } %token <sym> LETTER NUMBER %type <sym> expr %left - + %right * / %% statement: LETTER = expr ;

{AddToTable((char)$1.(char)$3,=);} | expr ; ; expr :expr + expr {$$ = AddToTable((char)$1.(char)$3,+);} |expr - expr {$$ = AddToTable((char)$1.(char)$3,-);} |expr * expr {$$ = AddToTable((char)$1.(char)$3,*);} |expr / expr {$$ = AddToTable((char)$1.(char)$3,/);} |(expr) {$$=(char)$2;) | NUMBER {$$=(char)$1;} | LETTER {$$=(char)$1;} ; %% yyerror(char *s) { printf(%s,s); exit(0); } struct InterCode Code[20]; char AddToTable(char operand1,char operand2,char opera) { char temp = A; Code[nIndex].operand1=operand1; Code[nIndex].operand2=operand2; Code[nIndex].opera=opera; nIndex++; temp++; return temp; } ThreeAddressCode() { int nCnt=0; char temp =A; printf(\n\n\t THREE ADDRESS CODE\n\n); temp++; while(nCnt<nIndex) { printf(%c : =\t,temp); if(isAlpha(Code[nCnt]].operand1)) printf(%c\t,Code[nCnt].operand1); else printf(%c\t,temp); printf(%c\t,Code[nCnt].opera); if(isAlpha(Code[nCnt]].operand2)) printf(%c\t,Code[nCnt].operand2); else

printf(%c\t,temp); printf(\n); nCnt++; temp++; } } void Quadruples() { int nCnt=0; char temp =A; temp++; printf(\n\n\t QUADRUPLES\n); printf(\n ID OPERATOR OPERAND1 OPERAND2 RESULT\n); while(nCnt<nIndex) { printf(\n(%d)\t%c\t,nCnt,Code[nCnt].opera); if(isAlpha(Code[nCnt]].operand1)) printf(%c\t,Code[nCnt].operand1); else printf(%c\t,temp); if(isAlpha(Code[nCnt]].operand2)) printf(%c\t,Code[nCnt].operand2); else printf(%c\t,temp); printf(%c\t,temp); nCnt++; temp++; } } main() { printf(\nEnter The Expression); yyparse(); ThreeAddressCode(); Quadruples(); } yywrap() { return 1; }

Output:
[root@localhost]# lex intcode.l [root@localhost]# yacc -d intcode.y [root@localhost]# ./a.out Enter The Expression: a=b+c*d/e; THREE ADDRESS CODE d/ e c* B b+ B a= B

B:= C:= D:= E:=

QUADRUPLES ID OPERATOR OPERAND1 OPERAND2 RESULT (0) / d e B (1) * c B C (2) + b B D (3) = a B E

[root@localhost]# ./a.out Enter The Expression: a=(b)+(c*d)/e THREE ADDRESS CODE c* d B/ e b+ B a= B

B:= C:= D:= E:=

QUADRUPLES ID OPERATOR OPERAND1 OPERAND2 RESULT (0) * c d B (1) / B e C (2) + b B D (3) = a B E

4. Write a program to generate the intermediate code in the form of Polish Notation
#include<stdio.h> #include<conio.h> #include<string.h> #incldue<stdlib.h> struct stack {char s[30]; int top; }st; void main() { char input[30]; void input_to_code(char infix[30]); clrscr(); printf("\n Enter an input in the form of expression "); scanf("%s",input); input_to_code(input); getch(); }

void input_to_code(char input[30]) { st.top=-1; st.s[st.top]='$'; char polish[30]; int i,j; char ch; int instack(char ch); int incoming(char ch); void push(char item); char pop(); j=0; strrev(input); for(i=0;input[i]!='\0';i++) { ch =input[i]; while(instack(st.s[st.top])>incoming(sh)) { polish[j]=pop(); j++; } if(instack(st.s[st.top])!=incoming(ch)) push(ch); else pop(); }

while((ch=pop()!='$') { polish[j]=ch; j++; } polish[j]='\0;; strrev(polish); printf("\n The Polish Notation is %s",polish); } int instack(char ch) { int priority; switch(ch) { case ')':priority=0; break; case '+': case '-':priority=1; break; case '*'; case '/':priority=3; break case '^':priority=6; break; case '$':priority=-1; break; default:priority=8;//when it is operand break; } return priority; } int incoming(char ch) { int priority; switch(ch) { case '+': case '-':priority=2; break; case '*'; case '/':priority=4; break case '^':priority=5; break; case '(':priority=0; break; case ')':priority=9; break; default:priority=7;//when it is operand } return priority; }

void push(char item) { st.top++; st.s[st.top]=item; } char pop() { char e; e=st.s[st.top]; st.top--; return e; }

Output:
Enter an input in the form of expression (a+b)*(c-d) The polish notation is *+ab-cd

5. Write a program to Simulate Heap storage allocation strategy


/************************************************************ Program to perform various operations such as creation, insertion, deletion, display of heap *************************************************************/
#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 *searched *Output:looks for the element in *If found returns pointer to the *Parameter Passing Methods: call *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; }

and the elemnt to be the list previous node otherwise NULL by value

/* *The get prev function *Input: Address of starting node *searched *Output:looks for the element in *If found returns pointer to the *Parameter Passing Methods: call *Called by : dele() *Calls : none **/

and the elemnt to be the list previous node otherwise NULL by value

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(); } }

Output:
Program to perform various operations on heap using Dynamic memory management. 1. Create 2. Display 3. Insert an element in a list 4. Delete an element from list 5. Quit Enter your choice(1-5) 1 Enter the element: 10 Do you want to enter more elements? (y/n) y Enter the element:20 Do you want to enter more elements?(y/n)y Enter the element:30 Do you want to enter more elements?(y/n)n The List is created

Program to perform various operations on Heap using Dynamic memory management. 1. Create 2. Display 3. Insert an element in a list 4. Delete an element from list 5. Quit Enter your choice(1-5) 4 Enter the element you want to delete: 20 The element is present in the list The element is deleted Program to perform various operations on management. 1. Create 2. Display 3. Insert an element in a list 4. Delete an element from list 5. Quit Enter your choice(1-5) 2 10-> 30-> NULL Heap using Dynamic memory

6. Generate Lexical analyzer using LEX.


%{ /******************************************************************* Program to obtain tokens from a c program using LEX <lexp.l> *******************************************************************/ int COMMENT = 0; int cnt = 0; %}

identifier[a-zA-Z][a-zA-Z0-9]* %%

#.* int | float | char | double | while | for | do | if | break | continue | void | switch | switch | case | long | struct | const | typedef | return | else | goto

{printf("\n%is a PREPROCESSOR DIRECTIVE", yytext);}

{printf("\n\t%s is a KEYWORD",yytext);}

"*/"

{COMMENT = 1;}

"*/" {COMMENT = 0;} cnt++; } {identifier}\(if(COMMENT){printf("\n\nFUNCTIONAL\n\t%s",yytext);} \{ {if(!COMMENT) printf("\n BLOCK BEGINS");}

\}

{if(!COMMENT)printf("\nBLOCK ENDS");}

{identifier}(\[0-9]*\])?

{if(!COMMENT)printf("\n\t%s is an IDENTIFIER",yytext);}

\".*\" [0-9]+ \)(\;)? \( = \+| \-

{if(!COMMENT)printf("\n\t% is a STRING",yytext);} {if(!COMMENT)printf("\n\t%is a NUMBER",yytext);} {if(!COMMENT)printf("\n\t");ECHO;print("\n";)}

ECHO; {if(!COMMENT)printf("\n\t%s is an ASSIGNMENT OPERATOR",yytext)}

{if(!COMMENT)printf("\n\t%s is an OPERATOR",yytext);}

\<=| \>=| \<| ==| \>

{if(!COMMENT)printf(\n\t%s is a RELATIONAL OPERATOR",yytext);}

|\n

%% int main(int argc.char**argv) { if(argc>1) { FILE *file'; file fopen(argv[1]."r"); if(file) { printf(\n Could not open %s,argv[1]; exit(0); } yyin = file; } yylex(); printf( \n Total number of comments are %d,cnt); return 0; } int yywrap() { return 1; }

Input File:
#include<stdio.h> #include<stdlib.h> double area_of_circle(double r); int main(int argc,char *argv[]) { if(argc < 2) { printf( Usage: %s radius \n,argv[0]); exit(1); } else { /* This is a double line comment */ double radius = atof(argv[1]); double area = area_of_circle(radius); printf( Area of circle with radius %f = %f \n,radius,area); } return 0; }

Output:
[root@localhost]# lex lexp.l [root@localhost]# gcc lex.yy.c [root@localhost]# ./a.out area.c #include<stdio.h> #include<stdlib.h> double is a KEYWORD area is an INDENTIFIER of is an INDENTIFIER circle is an INDENTIFIER (double is a KEYWORD r is an INDENTIFIER ); int is a KEYWORD main is an INDENTIFIER (int is a KEYWORD argc is an INDENTIFIER char is a KEYWORD argv[] is an INDENTIFIER ) BLOCK if is (argc < is 2 is ) BEGINS a KEYWORD is an INDENTIFIER a RELATIONAL OPERATOR a NUMBER

BLOCK BEGINS printf is an INDENTIFIER ( Usage: %s radius \n,is a STRING argv[0] is an INDENTIFIER ); exit is an INDENTIFIER (1 is a NUMBER ); BLOCK ENDS else is a KEYWORD

BLOCK BEGINS double is a KEYWORD radius is an INDENTIFIER = is an ASSIGNMENT OPERATOR

atof is an INDENTIFIER (argv[1]is an INDENTIFIER ); double is a KEYWORD area is an INDENTIFIER = is an ASSIGNMENT OPERATOR area is an INDENTIFIER of is an INDENTIFIER circle is an INDENTIFIER (radius is an INDENTIFIER ); printf is an INDENTIFIER (Area of circle with radius %f = %f \n, is a STRING radius is an INDENTIFIER area is an INDENTIFIER );

BLOCK ENDS return is a KEYWORD 0 is a NUMBER BLOCK ENDS Total number of comments are 3{root@localhost]#

7. Generate YACC specification for a few syntactic categories. a) Program to recognize a valid arithmetic expression that uses operator +, - , * and /. Program name:arith_id.l
%{ /* This LEX program returns the tokens #include y.tab.h %} %% = + - / * for the expression */

{printf(\n {printf(\n {printf(\n {printf(\n {printf(\n

Operator Operator Operator Operator Operator

is is is is is

EQUAL);} PLUS);} MINUS);} DIVISION);} MULTIPLICATION);}

[a-z A-Z]*[0-9]*

{ printf(\n Identifier is %s,yytext); return ID;

\n %%

} return yytext[0]; return 0;

int yywrap() { return 1; }

Program Name : arith_id.y


%{ #include<stdio.h> /* This YYAC program is for recognizing the Expression */ %} %% statement: A=E | E { printf(\n Valid arithmetic expression); $$ = $1; }; E: E+ID | E-ID | E*ID | E/ID | ID ;

%%
extern FILE *yyin;

main() { do { yyparse(); }while(!feof(yyin)); } yyerror(char*s) { }

Output:
[root@localhost]# lex arith_id.1 [root@localhost]# yacc d arith_id.y [root@localhost]# gcc lex.yy.c y.tab.c [root@localhost]# ./a.out x=a+b; Identifier is x Operator is EQUAL Identifier is a Operator is PLUS Identifier is b

b) Program to recognise a valid variable which starts with a letter followed by any number of letters or digits. Program name: variable_test.l
%{ /* This LEX program returns the tokens for the Expression */ #include "y.tab.h" %} %% "int " {return INT;} "float" {return FLOAT;} "double" {return DOUBLE;} [a-zA-Z]*[0-9]*{ printf("\nIdentifier is %s",yytext); return ID; } return yytext[0]; \n return 0; int yywrap() { return 1; }

Program name: variable_test.y


%{ #include <stdio.h> /* This YACC program is for recognising the Expression*/ %} %token ID INT FLOAT DOUBLE %% D;T L ; L:L,ID |ID ; T:INT |FLOAT |DOUBLE ; %% extern FILE *yyin; main() { do { yyparse(); }while(!feof(yyin)); } yyerror(char*s) { }

Output:
[root@localhost]# lex variable_test.I [root@localhost]# yacc d variable_test.y [root@localhost]# gcc lex.yy.c y.tab.c [root@localhost]# ./a.out int a,b; Identifier is a Identifier is b[root@localhost]#

c) Program to recognise the gramar(anb where n>=10) Program name: anb.l


%{ /*Lex Program for anb(n>=10)*/ %} %% a {return A;} b {return B;} . {return yytext[10];} \n return('\n'); %% int yywrap() { return 1; }

Program name:anb.y
%{ /*YACC program for recognising anb(n>=10)*/ %} %token A B %% stmt:A A A A A A A A A A anb'\n'{printf("\n Valid string"); return 0; } ; anb:A anb |A B ; %% main() { printf("\nEnter some valid string\n"); yyparse(); } int yyerror(char*s) { printf("\nInvalid string\n"); }

Output:
[root@localhost]# [root@localhost]# [root@localhost]# [root@localhost]# lex anb.1 yacc -d anb.y gcc lex.yy.c y.tab.c ./a.out

Enter some valid string aaaaaaaaab Invalid string [root@localhost]# ./a.out Enter some valid string aaaaaaaaaaab Valid string [root@localhost]#

d) Implementation of Calculator using LEX and YACC Program name:calci.l


%{ #include "y.tab.h" /*defines the tokens*/ #include ,math.h. %} %% /*To recognise a valid number*/ ([0-9] + |([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {yylval.dval = atof(yytext); return NUMBER;} /*For log no | Log no (log base 10)*/ log | LOG {return LOG;} /*For ln no (Natural Log)*/ ln {return nLOG;} /*For sin angle*/ sin | SIN {return SINE;} /*For cos angle*/ cos | COS {return COS;} /*For tan angle*/ tan | TAN {return TAN;} /*For memory*/ mem {return MEM;} [\t] ; /*Ignore white spaces*/

\$

/*End of input*/ {return 0;} /*Catch the remaining and return a single character token to the parser*/ return yytext[0];

\n| %%

Program Name : calci.y


%{ double memvar; %} /*To define possible symbol types*/ %token <dval> NUMBER %token <dval> MEM %token LOG SINE nLOG COS TAN /*Defining the precedences and associativity*/ %left - + /*Lowest precedence*/ %left * / %right ^ %left LOG SINE nLOG COS TAN /*Highest precence*/ /*No associativity*/ %nonassoc UMINUS /*Unary Minus*/ /*Sets the type for non-terminal*/ %type <dual> expression %% /*Start state*/ start: statement \n | start statement \n ; /*For storing the answer(memory)*/ statement: MEM= expression {memvar=$3;} | expression {printf(Answer = %g\n,$1);} ; /*For printing the Answer*/

/*For binary arithmetic operations*/ expression: expression + expression {$$ = $1 + $3;} | expression - expression {$$ = $1 - $3;} | expression * expression {$$ = $1 * $3;} | expression / expression { /*Tohandle divide by zero case*/ If($3 == 0) yyerror(divide by zero); else $$ = $1 / $3; } | expression ^ expression {$$ = pow($1,$3);} ;

/*For unary operators*/ expression: -expression %prec UMINUS {$$ = -$2;} /*%prec UMINUS signifies that unary minus should have the highest precedence*/

| | | | | | | | ;

( expression ) {$$ = $2} LOG expression {$$ = log($2)/log(10);} nLOG expression {$$ = log($2);} */Trigonometric functions*/ SINE expression {$$ = sin($2 * 3.141592654 / 180);} COS expression {$$ = cos($2 * 3.141592654 / 180);} TAN expression {$$ = tan($2 * 3.141592654 / 180);} NUMBER {$$ = $1;} MEM {$$ = $1;} /*Retrieving the memory contents*/

%% main() { printf(Enter the expression:); yyparse(); } int yyerror(char *error) { fprintf(stderr,%s\n,error); }

Output:
The output of the program can be obtained by following commands [root@localhost]]# lex calci.l [root@localhost]]# yacc d calci.y [root@localhost]]# cc y.tab.c lexyy.c ll ly lm [root@localhost]]# ./a.out Enter the expression: 2+@ Answer = 4 2 * 2 + 5 / 4 Answer = 5.25 mem = cos 45 sin 45/mem Answer = 1 ln 10 Answer = 2.30259

8. Given any intermediate code form implement code optimization techniques.


/******************************************************************* Program for Code Optimization Technique of Constant Folding *******************************************************************/ #include<stdio.h> #include<string.h> #include<conio.h> #include<stdlib.h> #include<ctype.h> struct ConstFold ( char new_Str[10]; char str[10]; }Opt_Data[20]; void ReadInput(char Buffer[],FILE *Out_file); int Gen_token(char str[],char Tokens[][10]); int New_Index=0; int main() { file *In_file,*Out_file; char Buffer[100],ch; int i=0; In_file = fopen(d:\\code.txt,r); Out_file = fopen(d:\\output.txt,w); clrscr(); while(1) { Ch = fgetc(In_file); i=0; while(1) { If(ch == \n) break; Buffer[i++]=ch; ch = fgetc(_file); if(ch == EOF) break; }//End while if(ch ==EOF) break; Buffer[i]=\0; ReadInput(Bufer, Out_file);//writing to the output file }//End while return 0; }//End main

void ReadInput(char Buffer[],FILE *Out_file) { char temp[100],Token[10][10]; int n,I,j,flag=0; strcpy(temp,Buffer); n= Gen_token(temp,Token); for(i=0;i<n;i++) { if(!strcmp(Token[i],=)) { if(isdigit(Token[i+1][0])||Token[i+1][0] == .) { /*If yes then saving that number and its variable In the Opt_Data array*/ flag=1; strcpy(Opt_Data[New_Index].New_Str,Token[i-1]); strcpy(Opt_Data[New_Index++].str,Token[i+1]); }//End if }//End if }//End for if(!flag) { for(i=0;i<New_index;i++) { for(j=0;j<n;j++) { if(!strcmp(Opt_Data[i].new_Str,Token[j])) strcpy(Token[j],Opt_Data[i].str); }//End for }//End for }//End if fflush(Out_file); strcpy(temp,); for(i=0;i<n;i++) /*Loop to obtain complete tokens*/ { strcat(tem,Token[i]); if(Token[i+1][0]!=,||Token[i+1][0] != ,) strcat(temp, ); }//End for strcat(temp,\n\0); fwrite(&temp,strlen(temp),1,Out_file); }

/*The Gen_Token function breaks the input line into tokens*/ int Gen_Token(char str[], char Token[][10]) { int i=0;j=0,k=0; while(str[k]!=\0) { j=0; while(str[k] == || str[k] ==\t) k++;

while(str[k])!= && str[k]!=\0 && str[k]!= = && str[k] != / && str[k]!= + && str[k] != - && str[k]!= * && str[k] != , && str[k]!= ;) Token[i][j++] = str[k++]; Token[i++][j] = \0; if(str[k] == =|| str[k] == /|| str[k] == +|| str[k] == -|| str[k] == *|| str[k] == *|| str[k] == ,|| str[k] == ;) { Token[i][0] = str[k++]; Token[i++][1] = \0; }//End if if (str[k] == \0) break; }//End while return i; }

Input File: code.txt


#include<stdio.h> main() { float pi=3.14,r,a; a = pi*r*r; printf(a = %f,a); return 0; }

Output File: output.txt


#include<stdio.h> main() { float pi = 3.14, r, a; a = 3.14 * r * r; printf(a = %f,a); return 0; }

9. Write a program to find FIRST of NON TERMINALS of the given grammar.

#include"stdio.h" #include<conio.h> char array[10][20],temp[10]; int c,n;void fun(int,int[]); int fun2(int i,int j,int p[],int key) { int k; if(!key) { for(k=0;k<n;k++) if(array[i][j]==array[k][0]) break; p[0]=i;p[1]=j+1; fun(k,p); return 0; } else { for(k=0;k<=c;k++) { if(array[i][j]==temp[k]) break; } if(k>c)return 1; else return 0; } } void fun(int i,int p[]) { int j,k,key; for(j=2;array[i][j]!='\0';j++) { if(array[i][j-1]=='/') { if(array[i][j]>='A'&&array[i][j]<='Z') { key=0; fun2(i,j,p,key); } else { key=1; if(fun2(i,j,p,key)) temp[++c]=array[i][j]; if(array[i][j]=='@'&&p[0]!=-1) { //taking ,@, as null symbol. if(array[p[0]][p[1]]>='A'&&array[p[0]][p[1]]<='Z') {

key=0; fun2(p[0],p[1],p,key); } else if(array[p[0]][p[1]]!='/'&&array[p[0]][p[1]]!='\0') { if(fun2(p[0],p[1],p,key)) temp[++c]=array[p[0]][p[1]]; } } } } } } void main() { int p[2],i,j; clrscr(); printf("Enter the no. of productions :"); scanf("%d",&n); printf("Enter the productions :\n"); for(i=0;i<n;i++) scanf("%s",array[i]); for(i=0;i<n;i++) { c=-1,p[0]=-1,p[1]=-1; fun(i,p); printf("First(%c) : [ ",array[i][0]); for(j=0;j<=c;j++) printf("%c,",temp[j]); printf("\b ].\n"); getch(); } }

Output:
Enter the no. of productions :6 Enter the productions : S/aBDh B/cC C/bC/@ D/E/F E/g/@ F/f/@ First(S) : [ a ]. First(B) : [ c ]. First(C) : [ b,@ ]. First(D) : [ g,@,f ]. First(E) : [ g,@ ]. First(F) : [ f,@ ].

10. Write a program to find out FOLLOW of NONTERMINALS of given productions.


#include"stdio.h" #include<conio.h> #define max 10 #define MAX 15 char array[max][MAX],temp[max][MAX]; int c,n,t;void fun(int,int[]); int fun2(int i,int j,int p[],int key) { int k; if(!key) { for(k=0;k<n;k++) if(array[i][j]==array[k][0]) break; p[0]=i;p[1]=j+1; fun(k,p); return 0; } else { for(k=0;k<=c;k++) { if(array[i][j]==temp[t][k]) break; } if(k>c)return 1; else return 0; } } void fun(int i,int p[]) { int j,k,key; for(j=2;array[i][j]!='\0';j++) { if(array[i][j-1]=='/') { if(array[i][j]>='A'&&array[i][j]<='Z') { key=0; fun2(i,j,p,key); } else { key=1; if(fun2(i,j,p,key)) temp[t][++c]=array[i][j]; if(array[i][j]=='@'&&p[0]!=-1) { //taking ,@, as null symbol. if(array[p[0]][p[1]]>='A'&&array[p[0]][p[1]]<='Z')

{ key=0; fun2(p[0],p[1],p,key); } else if(array[p[0]][p[1]]!='/'&&array[p[0]][p[1]]!='\0') { if(fun2(p[0],p[1],p,key)) temp[t][++c]=array[p[0]][p[1]]; } } } } } } char fol[max][MAX],ff[max];int f,l,ff0; void ffun(int,int); void follow(int i) { int j,k; for(j=0;j<=ff0;j++) if(array[i][0]==ff[j]) return 0; if(j>ff0)ff[++ff0]=array[i][0]; if(i==0)fol[l][++f]='$'; for(j=0;j<n;j++) for(k=2;array[j][k]!='\0';k++) if(array[j][k]==array[i][0]) ffun(j,k); } void ffun(int j,int k) { int ii,null=0,tt,cc; if(array[j][k+1]=='/'||array[j][k+1]=='\0') null=1; for(ii=k+1;array[j][ii]!='/'&&array[j][ii]!='\0';ii++) { if(array[j][ii]<='Z'&&array[j][ii]>='A') { for(tt=0;tt<n;tt++) if(temp[tt][0]==array[j][ii])break; for(cc=1;temp[tt][cc]!='\0';cc++) { if(temp[tt][cc]=='@')null=1; else fol[l][++f]=temp[tt][cc]; } } else fol[l][++f]=array[j][ii]; } if(null)follow(j); }

void main() { int p[2],i,j; clrscr(); printf("Enter the no. of productions :"); scanf("%d",&n); printf("Enter the productions :\n"); for(i=0;i<n;i++) scanf("%s",array[i]); for(i=0,t=0;i<n;i++,t++) { c=0,p[0]=-1,p[1]=-1; temp[t][0]=array[i][0]; fun(i,p); temp[t][++c]='\0'; printf("First(%c) : [ ",temp[t][0]); for(j=1;j<c;j++) printf("%c,",temp[t][j]); printf("\b ].\n"); getch(); } /* Follow Finding */ for(i=0,l=0;i<n;i++,l++) { f=-1;ff0=-1; fol[l][++f]=array[i][0]; follow(i); fol[l][++f]='\0'; } for(i=0;i<n;i++) { printf("\nFollow[%c] : [ ",fol[i][0]); for(j=1;fol[i][j]!='\0';j++) printf("%c,",fol[i][j]); printf("\b ]"); getch(); } }

Output:
Enter the no. of productions :6 Enter the productions : S/aBDh B/cC C/bC/@ D/E/F E/g/@ F/f/@ First(S) : [ a ]. First(B) : [ c ]. First(C) : [ b,@ ]. First(D) : [ g,@,f ].

First(E) : [ g,@ ]. First(F) : [ f,@ ]. Follow[S] : [ $ ] Follow[B] : [ g,f,h,$ ] Follow[C] : [ g,f,h,$ ] Follow[D] : [ h ] Follow[E] : [ h ] Follow[F] : [ h ]

S-ar putea să vă placă și