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 999char 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 AnalysisEnter the expression and put ; at the endPress Ctrl + Z to terminate ...2+3Number: 2OperatorNumber: 3if(a<b) a=a+b;
KeywordParenthesisIdentifier: aRelational OperatorIdentifier: bParenthesisIdentifier: aAssigment OperatorIdentifier: aOperator Identifier: b^Z
2. Develop a recursive decent parser
#include<stdio.h>#include<ctype.h>#include<stdlib.h>#include<string.h>
#define SIZE 128#define NONE -1#define EOS '\0'#define NUM 257#define KEYWORD 258#define ID 259#define DONE 260#define 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{ tokenval=NONE;
return t;}
}}
void match(int t){
if(lookahead==t)lookahead=lexer();
elseerrormsg("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);
elseprintf("\n token:%d tokenval %d",t,tokenval);
}
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 endPress CTRL + Z to terminate2+3*4;
number 2number 3number 4arithmetic operator *arithmetic operator +
2+3*4+5;number 2number 3number 4arithmetic operator *arithmetic operator +number 5arithmetic operator +
a-b;identifier aidentifier barithmetic operator –
+1Line7: syntaxerror
3. Write a program for generating for various intermediate code forms:● Three address code● Quadruple
/* Program name: intcode.l */
%{#include”y.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 {return 0;}{return yytext[0];}
%%
/* Program name: intcode.y */
%{#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);
elseprintf(“%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 CODEB:= d / eC:= c * BD:= b + BE:= a = B
QUADRUPLESID 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 CODEB:= c * dC:= B / eD:= b + BE:= a = B
QUADRUPLESID 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;
breakcase '^':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;
breakcase '^':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 functiontemp->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;
elsefound = 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(“\n”1.Insert a node as a head node”);printf(“\n”1.Insert a node as a last node”); printf(“\n”1.Insert a node as at the intermediate position in
the list ”); printf(“\n”1.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;
elsereturn 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(“\n”The Element is deleted\n”);getch();clrscr();
}}
Output:
Program to perform various operations on heap using Dynamic memory management.
1. Create2. Display3. Insert an element in a list4. Delete an element from list5. QuitEnter 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. Create2. Display3. Insert an element in a list4. Delete an element from list5. 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 Heap using Dynamic memory management.
1. Create2. Display3. Insert an element in a list4. Delete an element from list5. QuitEnter your choice(1-5) 2
10-> 30-> NULL
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]*%%
#.* {printf("\n%is a PREPROCESSOR DIRECTIVE", yytext);}
int |float |char |double |while |for |do |if |break |continue |void |switch |switch |case |long |struct |const |typedef |return |else |goto {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);}
\".*\" {if(!COMMENT)printf("\n\t% is a STRING",yytext);}
[0-9]+ {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 KEYWORDarea is an INDENTIFIERof is an INDENTIFIERcircle is an INDENTIFIER(double is a KEYWORDr is an INDENTIFIER
);
int is a KEYWORDmain is an INDENTIFIER(int is a KEYWORDargc is an INDENTIFIERchar is a KEYWORDargv[] is an INDENTIFIER
)
BLOCK BEGINSif is a KEYWORD(argc is an INDENTIFIER
< is a RELATIONAL OPERATOR2 is a NUMBER
)
BLOCK BEGINSprintf is an INDENTIFIER(“ Usage: %s radius \n”,is a STRING
argv[0] is an INDENTIFIER);
exit is an INDENTIFIER (1 is a NUMBER
);
BLOCK ENDSelse is a KEYWORD
BLOCK BEGINSdouble is a KEYWORDradius is an INDENTIFIER= is an ASSIGNMENT OPERATOR
atof is an INDENTIFIER(argv[1]is an INDENTIFIER);
double is a KEYWORDarea is an INDENTIFIER= is an ASSIGNMENT OPERATORarea is an INDENTIFIERof is an INDENTIFIERcircle is an INDENTIFIER(radius is an INDENTIFIER);
printf is an INDENTIFIER(“Area of circle with radius %f = %f \n”, is a STRINGradius is an INDENTIFIERarea is an INDENTIFIER
);
BLOCK ENDSreturn is a KEYWORD0 is a NUMBER
BLOCK ENDSTotal 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 for the expression */#include “y.tab.h”%}
%%“=” {printf(“\n Operator is EQUAL”);}“+” {printf(“\n Operator is PLUS”);}“-“ {printf(“\n Operator is MINUS”);}“/” {printf(“\n Operator is DIVISION”);}“*” {printf(“\n Operator is MULTIPLICATION”);}
[a-z A-Z]*[0-9]* { printf(“\n Identifier is %s”,yytext); return ID; }return yytext[0];
\n 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.outx=a+b;
Identifier is xOperator is EQUALIdentifier is aOperator is PLUSIdentifier 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.outint a,b;
Identifier is aIdentifier 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]# lex anb.1[root@localhost]# yacc -d anb.y[root@localhost]# gcc lex.yy.c y.tab.c[root@localhost]# ./a.out
Enter some valid stringaaaaaaaaab
Invalid string[root@localhost]# ./a.out
Enter some valid stringaaaaaaaaaaab
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*/
\n| return yytext[0];%%
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 / 4Answer = 5.25
mem = cos 45sin 45/memAnswer = 1
ln 10Answer = 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 whileif(ch ==EOF)break;Buffer[i]=’\0’;ReadInput(Bufer, Out_file);//writing to the output file
}//End whilereturn 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 forif(!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 iffflush(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 forstrcat(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 ifif (str[k] == ‘\0’)break;
}//End whilereturn 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 :6Enter the productions :S/aBDhB/cCC/bC/@D/E/FE/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 givenproductions.
#include"stdio.h"#include<conio.h>#define max 10#define MAX 15char 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 :6Enter the productions :S/aBDhB/cCC/bC/@D/E/FE/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 ]
Top Related