Compilerdesignlab Mannual
Compilerdesignlab Mannual
Compilerdesignlab Mannual
PROGRAM:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void keyword(char str[10])
{
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||
strcmp("int",str)==0||strcmp("float",str)==0||strcmp("char",str)==0||
strcmp("double",str)==0||strcmp("static",str)==0||
strcmp("switch",str)==0||strcmp("case",str)==0)
printf("\n%s is a keyword",str);
else
printf("\n%s is an identifier",str);
}
main()
{
FILE *f1,*f2,*f3;
char c,str[10],st1[10];
int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;
printf("\nEnter the c program");/*gets(st1);*/
f1=fopen("input","w");
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen("input","r");
f2=fopen("identifier","w");
f3=fopen("specialchar","w");
while((c=getc(f1))!=EOF){
if(isdigit(c))
{
tokenvalue=c-'0';
c=getc(f1);
while(isdigit(c)){
tokenvalue*=10+c-'0';
c=getc(f1);
}
num[i++]=tokenvalue;
ungetc(c,f1);
}
else if(isalpha(c))
{
putc(c,f2);
c=getc(f1);
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
{
putc(c,f2);
c=getc(f1);
}
putc(' ',f2);
ungetc(c,f1);
}
else if(c==' '||c=='\t')
printf(" ");
else
if(c=='\n')
lineno++;
else
putc(c,f3);
}
fclose(f2);
fclose(f3);
fclose(f1);
printf("\nThe no's in the program are");
for(j=0;j
printf("%d",num[j]);
printf("\n");
f2=fopen("identifier","r");
k=0;
printf("The keywords and identifiersare:");
while((c=getc(f2))!=EOF){
if(c!=' ')
str[k++]=c;
else
{
str[k]='\0';
keyword(str);
k=0;
}
}
fclose(f2);
f3=fopen("specialchar","r");
printf("\nSpecial characters are");
while((c=getc(f3))!=EOF)
printf("%c",c);
printf("\n");
fclose(f3);
printf("Total no. of lines are:%d",lineno);
}
Input:
Enter Program $ for termination:
{
int a[3],t1,t2;
t1=2; a[0]=1; a[1]=2; a[t1]=3;
t2=-(a[2]+t1*6)/(a[2]-t1);
if t2>5 then
print(t2);
else {
int t3;
t3=99;
t2=-25;
print(-t1+t2*t3); /* this is a comment on 2 lines */
} endif
}
(cntrl+z)
Output:
Variables : a[3] t1 t2 t3
Operator : - + * / >
Constants : 2 1 3 6 5 99 -25
Keywords : int if then else endif
Special Symbols : , ; ( ) { }
Comments : this is a comment on 2 lines
2. Implement a Lexical Analyzer for a given program
using Lex Tool.
AIM:
ALGORITHM:
Step1: Lex program contains three sections: definitions, rules, and user
subroutines. Each section must be separated from the others by a line
containing only the delimiter, %%. The format is as follows: definitions %%
rules %% user_subroutines
Step2: In definition section, the variables make up the left column, and their
definitions make up the right column. Any C statements should be enclosed in
%{..}%. Identifier is defined such that the first letter of an identifier is
alphabet and remaining letters are alphanumeric.
Step3: In rules section, the left column contains the pattern to be recognized
in an input file to yylex(). The right column contains the C program fragment
executed when that pattern is recognized. The various patterns are keywords,
operators, new line character, number, string, identifier, beginning and end of
block, comment statements, preprocessor directive statements etc.
Step4: Each pattern may have a corresponding action, that is, a fragment of C
source code to execute when the pattern is matched.
Step5: When yylex() matches a string in the input stream, it copies the
matched text to an external character array, yytext, before it executes any
actions in the rules section.
Step6: In user subroutine section, main routine calls yylex(). yywrap() is used
to get more input.
Step7: The lex command uses the rules and actions contained in file to
generate a program, lex.yy.c, which can be compiled with the cc command.
That program can then receive input, break the input into the logical pieces
defined by the rules in file, and run program fragments contained in the
actions in file.
PROGRAM CODE:
Input:
#include<stdio.h>
main()
{
int a,b;
}
Output:
#include<stdio.h> is a PREPROCESSOR DIRECTIVE
FUNCTION
main (
)
BLOCK BEGINS
int is a KEYWORD
a IDENTIFIER
b IDENTIFIER
BLOCK ENDS
3. Source Code to count the numbers of lines, words,
spaces, and characters in a given statement
in a given statement*/
%{
#include<stdio.h>
int sc=0,wc=0,lc=0,cc=0;
%}
%%
[\n] { lc++; cc+=yyleng;}
[ \t] { sc++; cc+=yyleng;}
[^\t\n ]+ { wc++; cc+=yyleng;}
%%
int yywrap( )
{
return 1;
}
Output:
maheshgh@maheshgh:~/LexYacc$ lex demo.l
maheshgh@maheshgh:~/LexYacc$ gcc lex.yy.c
maheshgh@maheshgh:~/LexYacc$ ./a.out
Enter the input: Greetings from VTUPulse.com
Welcome to VTUPulse.com
Lex Yacc Tutorial
(Note: After input string press enter and ctrl+d)
The number of lines=3
The number of spaces=6
The number of words=9
The number of characters are=70
Program to count the numbers of lines, words, spaces, and characters from
a given file
%{
#include<stdio.h>
int sc=0,wc=0,lc=0,cc=0;
%}
%%
[\n] { lc++; cc+=yyleng;}
[ \t] { sc++; cc+=yyleng;}
[^\t\n ]+ { wc++; cc+=yyleng;}
%%
int yywrap( )
{
return 1;
}
Output:
maheshgh@maheshgh:~/LexYacc$ lex demo.l
maheshgh@maheshgh:~/LexYacc$ gcc lex.yy.c
maheshgh@maheshgh:~/LexYacc$ ./a.out input.txt
(Note: input.txt is the input file containing input text)
The number of lines=3
The number of spaces=6
The number of words=9
The number of characters are=70
4. Write a LEX Program to convert the substring abc to
ABC from the given input string.
%{
#include<stdio.h>
#include<ctype.h>
int i;
%}
%%
[a-z A-Z]* {
for(i=0;i<=yyleng;i++)
{
if((yytext[i]=='a')&&
(yytext[i+1]=='b')&&(yytext[i+2]=='c'))
{
yytext[i]='A';
yytext[i+1]='B';
yytext[i+2]='C';
}
}
printf("%s",yytext);
}
[\t]* return;
.* {ECHO;}
\n {printf("%s",yytext);}
%%
main()
{
yylex();
}
int yywrap()
{
return 1;
}
OUTPUT:
abc
ABC
5. LEX program to count the number of vowels and
consonants in a given string
Given a string containing both vowels and consonants, write a LEX program to
count the number of vowels and consonants in given string.
%{
int vow_count=0;
int const_count =0;
%}
%%
[aeiouAEIOU] {vow_count++;}
[a-zA-Z] {const_count++;}
%%
int yywrap(){}
int main(int argc,char *argv[])
{
if (argc==2){yyin=fopen(argv[1],”r”);}
else printf("Enter the string of vowels and consonents:");
yylex();
printf("Number of vowels are: %d\n", vow_count);
printf("Number of consonants are: %d\n", const_count);
return 0;
}
Output
6. Generate a YACC specification to recognize a valid
arithmetic expression that uses operators +, – , *,/ and
parenthesis.
AIM:
To write a Yacc program to valid arithmetic expression using Yacc.
ALGORITHM:
Step1: Start the program.
Step2: Reading an expression .
Step3: Checking the validating of the given expression according to the rule
using yacc.
Step4: Using expression rule print the result of the given values
Step5: Stop the program.
PROGRAM:
LEX PART:
%{
#include "y.tab.h"
%}
%%
[a-zA-Z_][a-zA-Z_0-9]* return id;
[0-9]+(\.[0-9]+)? return num;
[-+/*] return op;
. return yytext[0];
\n return 0;
%%
int yywrap()
{
return 1;
}
YACC PART:
%{
#include<stdio.h>
int valid=1;
%}
%token num id op
%%
start : id '=' s ';'
s : id x
| num x
| '-' num x
| '(' s ')' x
;
x : op s
| '-' s
|
;
%%
int yyerror()
{
valid=0;
printf("\nInvalid expression!\n");
return 0;
}
int main()
{
printf("\nEnter the expression:\n");
yyparse();
if(valid)
{
printf("\nValid expression!\n");
}
}
Output:
7. Generate a YACC specification to recognize a valid
identifier which starts with a letter/ underscore followed
by any number of letters or digits.
AIM :
To write a yacc program to check valid variable followed by letter or digits
ALGORITHM:
Step3: Checking the validating of the given expression according to the rule using yacc.
Step4: Using expression rule print the result of the given values
PROGRAM CODE:
LEX PART:
%{
#include "y.tab.h"
%}
%%
[a-zA-Z_] return letter;
[0-9] return digit;
. return yytext[0];
\n return 0;
%%
int yywrap()
{
return 1;
}
YACC PART:
%{
#include<stdio.h>
int valid=1;
%}
%%
int yyerror()
{
printf("\nIts not an identifier!\n");
valid=0;
return 0;
}
int main()
{
printf("\nEnter a name to tested for identifier ");
yyparse();
if(valid)
{
printf("\nIt is an identifier!\n");
}
}
Output:
8. Implementation of Calculator using LEX and YACC
AIM:
To write a program for implementing a calculator for computing the given expression using
semantic rules of the YACC tool and LEX.
ALGORITHM:
Declarations
%%
translation rules
%%
supporting C routines
iv. Define the tokens used by the parser. v. Define the operators and their precedence.
Step5: main()- The required main program that calls the yyparse subroutine to start the program.
Step6: yyerror(s) -This error-handling subroutine only prints a syntax error message.
Step7: yywrap -The wrap-up subroutine that returns a value of 1 when the end of input occurs. The
calc.lex file contains include statements for standard input and output, as programmar file
information if we use the -d flag with the yacc command. The y.tab.h file contains definitions for
the tokens that the parser program uses.
Step8: calc.lex contains the rules to generate these tokens from the input stream.
PROGRAM CODE:
%{
#include<stdio.h>
#include "y.tab.h"
extern int yylval;
%}
%%
[0-9]+ {
yylval=atoi(yytext);
return NUMBER;
}
[\t] ;
[\n] return 0;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
YACC PART:
%{
#include<stdio.h>
int flag=0;
%}
%token NUMBER
%left '+' '-'
%left '*' '/' '%'
%left '(' ')'
%%
ArithmeticExpression: E{ printf("\nResult=%d\n",$$);
return 0;
};
E:E'+'E {$$=$1+$3;}
|E'-'E {$$=$1-$3;}
|E'*'E {$$=$1*$3;}
|E'/'E {$$=$1/$3;}
|E'%'E {$$=$1%$3;}
|'('E')' {$$=$2;}
| NUMBER {$$=$1;}
%%
void main()
void yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");
flag=1;
}
Output
9. Convert the BNF rules into YACC form and write code
to generate abstract syntax tree.
AIM:
To write a yacc program to change yacc form into abstract syntax Tree
ALGORITHM:
Step1: Reading an expression.
Step2: Calculate the value of given expression
Step3: Display the value of the nodes based on the precedence.
Step4: Using expression rule print the result of the given values
PROGRAM CODE:
LEX PART:
%{
#include"y.tab.h"
#include<stdio.h>
#include<string.h>
int LineNo=1;
%}
identifier [a-zA-Z][_a-zA-Z0-9]*
number [0-9]+|([0-9]*\.[0-9]+)
%%
main\(\) return MAIN;
if return IF;
else return ELSE;
while return WHILE;
int |
char |
float return TYPE;
{identifier} {strcpy(yylval.var,yytext);
return VAR;}
{number} {strcpy(yylval.var,yytext);
return NUM;}
\< |
\> |
\>= |
\<= |
== {strcpy(yylval.var,yytext);
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
YACC PART:
%{
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
struct quad
{
char op[5];
char arg1[10];
char arg2[10];
char result[10];
}QUAD[30];
struct stack
{
int items[100];
int top;
}stk;
int Index=0,tIndex=0,StNo,Ind,tInd;
extern int LineNo;
%}
%union
{
char var[10];
}
%token <var> NUM VAR RELOP
%token MAIN IF ELSE WHILE TYPE
%type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
%left '-' '+'
%left '*' '/'
%%
PROGRAM : MAIN BLOCK
;
BLOCK: '{' CODE '}'
;
CODE: BLOCK
| STATEMENT CODE
| STATEMENT
;
#include<stdio.h>
#include<string.h>
char result[20][20],copy[3],states[20][20];
for(k=0;k<n;k++){
i=0;
strcpy(state,states[k]);
strcpy(copy,state);
add_state(state,i++);
while(1){
end=fscanf(INPUT,"%s%s%s",state1,input,state2);
if(end==EOF){
break;
}
if(strcmp(state,state1)==0){
if(strcmp(input,"e")==0){
add_state(state2,i++);
strcpy(state,state2);
}
}
}
display(i);
rewind(INPUT);
}
return 0;
}
Input-
q0 0 q0
q0 1 q1
q0 e q1
q1 1 q2
q1 e q2
Output-
Enter the no of states: 3
Enter the states
q0
q1
q2
Epsilon closure of q0 = { q0 q1 q2 }
Epsilon closure of q1 = { q1 q2 }
Epsilon closure of q2 = { q2 }
11. Write a program to convert NFA with ε transition to
NFA without ε transition.
#include<stdio.h>
#include<stdlib.h>
struct node
{
int st;
struct node *link;
};
void findclosure(int,int);
void insert_trantbl(int ,char, int);
int findalpha(char);
void findfinalstate(void);
void unionclosure(int);
void print_e_closure(int);
static int
set[20],nostate,noalpha,s,notransition,nofinal,start,finalstate[20],c,r,b
uffer[20];
char alphabet[20];
static int e_closure[20][20]={0};
struct node * transition[20][20]={NULL};
void main()
{
int i,j,k,m,t,n;
int findalpha(char c)
{
int i;
for(i=0;i<noalpha;i++)
if(alphabet[i]==c)
return i;
return(999);
}
void unionclosure(int i)
{
int j=0,k;
while(e_closure[i][j]!=0)
{
k=e_closure[i][j];
set[k]=1;
j++;
}
}
void findfinalstate()
{
int i,j,k,t;
for(i=0;i<nofinal;i++)
{
for(j=1;j<=nostate;j++)
{
for(k=0;e_closure[j][k]!=0;k++)
{
if(e_closure[j][k]==finalstate[i])
{
print_e_closure(j);
}
}
}
}
void print_e_closure(int i)
{
int j;
printf("{");
for(j=0;e_closure[i][j]!=0;j++)
printf("q%d,",e_closure[i][j]);
printf("}\t");
}
sample output
12. Write a program to convert NFA to DFA
#include<stdio.h>
int Fa[10][10][10],states[2][10],row=0,col=0,sr=0,sc=0,th=0,
in,stat,new_state[10][10],max_inp=-1,no_stat;
FILE *fp;
int i;
for(i=0;i<no_stat;i++)
if(search_var == states[1][i])
return 1;
return 0;
}
t=0;
for(j=i;j<c;j++)
{
arr[j]=new_state[temp][t];
t++;
}
}
}
c=0;
for(i=0;arr[i]!=-1;i++)
c++;
*count=c;
return 0;
}
for(t=0;t<=max_inp;t++)
{
count=0;
for(k=0;k<10;k++)
arr[k]=-1;
trans(i,j,t,c,&count,arr);
checkcon(arr,&count);
sort(arr,count);
remove_duplicate(arr,&count);
for(k=0;k<count;k++)
Fa[stat][t][k]=arr[k];
}
Fa[i][j][0]=stat++;
for(t=1;t<c;t++)
Fa[i][j][t]=-1;
}
else
{
Fa[i][j][0]=name ;
for(t=1;t<c;t++)
Fa[i][j][t]=-1;
}
}
}
}
return 0;
}
int main()
{
int i,j,k,flag=0,start,end;
char c,ch;
fp=fopen("Nfa_ip.txt","r+");
for(i=0;i<2;i++)
for(j=0;j<10;j++)
states[i][j]=-1;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
new_state[i][j]=-1;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
for(k=0;k<10;k++)
Fa[i][j][k]=-1;
while(fscanf(fp,"%d",&in)!=EOF)
{
fscanf(fp,"%c",&c);
if(flag)
{
states[sr][sc++]=in;
if(c=='\n')
{
sr++;
sc=0;
}
}
else if(c=='#')
{
flag=1;
Fa[row][col][th]=in;
}
else if(!flag)
{
Fa[row][col][th]=in;
if(c==',')
{
th++;
}
else if(c=='\n')
{
if(max_inp<col)
max_inp=col;
col=0;
row++;
th=0;
}
else if(c!=',')
{
col++;
th=0;
}
}
}
no_stat=0;
i=0;
while(states[1][i++]!=-1)
no_stat++;
stat=row+1;
start=0;end=row;
while(1)
{
nfa2dfa(start,end);
start=end+1;
end=row;
if(start>end)
break;
}
printf("\n\nDFA IS : \n\n\n");
for(i=0;i<=max_inp;i++)
printf("\t%d",i);
printf("\n");
printf("----------------------------\n");
for(i=0;i<stat;i++)
{
printf("%d-> |",i);
for(j=0;j<=max_inp;j++)
{
printf("%2d ",Fa[i][j][0]);
}
printf("\n");
}
printf("\n\n");
printf("Total Number Of State Is : %d \n\n",stat);
printf("Final States Are : ");
for(i=0;states[1][i]!=-1;i++)
printf("%d ",states[1][i]);
printf("\n\n");
getch();
return 0;
}
13. Write a program to minimize any given DFA.
C program for construction of minimized DFA from a given regular
expression.
OBJECTIVE: write a program for construction of minimized DFA from a given regular expression
using C.
ALGORITHM:
1. Get the start state, final state, input symbols as input and also give the edge value for each
state.
2. Maintain a stack required for transition from one state to other state.
3. Using Pop or push function perform the insertion and deletion of elements when required.
4. Finally conversion has been made to change from regular expression to minimized DFA and
the output is displayed as DFA transition table.
PROGRAM:
#include
#include
#define STATES 50
struct Dstate
char name;
char StateString[STATES+1];
char trans[10];
int is_final;
}Dstates[50];
struct tran
char sym;
int tostates[50];
int notran;
};
struct state
int no;
struct tran tranlist[50];
};
int stackA[100],stackB[100],c[100],Cptr=-1,Aptr=-1,Bptr=-1;
char temp[STATES+1],inp[10];
int nos,noi,nof,j,k,nods=-1;
void pushA(int z)
stackA[++Aptr]=z;
void pushB(int z)
stackB[++Bptr]=z;
int popA()
return stackA[Aptr--];
void copy(int i)
int k=0;
Bptr=-1;
strcpy(temp,Dstates[i].StateString);
while(temp[k]!='\0')
pushB(temp[k]-'0');
k++;
}
int popB()
return stackB[Bptr--];
int peekA()
return stackA[Aptr];
int peekB()
return stackA[Bptr];
int i;
for(i=0;i<=ptr;i++)
if(s==arr[i])
return 1;
return 0;
void sort()
int i,j,temp;
for(i=0;i
{
for(j=0;j<(Bptr-i);j++)
if(stackB[j]>stackB[j+1])
temp=stackB[j];
stackB[j]=stackB[j+1];
stackB[j+1]=temp;
void tostring()
int i=0;
sort();
for(i=0;i<=Bptr;i++)
temp[i]=stackB[i]+'0';
temp[i]='\0';
void display_DTran()
int i,j;
for(i=0;i
{
printf("\t %c",inp[i]);
for(i=0;i
if(Dstates[i].is_final==0)
printf("\n%c",Dstates[i].name);
else
printf("\n*%c",Dstates[i].name);
printf("\t%s",Dstates[i].StateString);
for(j=0;j
printf("\t%c",Dstates[i].trans[j]);
printf("\n");
int ctr=0;
while(ctr
pushA(States[st].tranlist[j].tostates[ctr++]);
int ctr=0,in_state=st,curst=st,chk;
while(Aptr!=-1)
{
curst=popA();
ctr=0;
in_state=curst;
while(ctr<=States[curst].tranlist[noi].notran)
chk=seek(stackB,Bptr,in_state);
if(chk==0)
pushB(in_state);
in_state=States[curst].tranlist[noi].tostates[ctr++];
chk=seek(stackA,Aptr,in_state);
pushA(in_state);
void main()
int i,final[20],start,fin=0;
char c,ans,st[20];
scanf("%d",&nos);
for(i=0;i
States[i].no=i;
scanf("%d",&start);
for(i=0;i
scanf("%d",&final[i]);
scanf("%d",&noi);
c=getchar();
for(i=0;i
scanf("%c",&inp[i]);
c=getchar();
//g1inp[i]='e';
inp=[i]=’e’;
for(i=0;i
for(j=0;j<=noi;j++)
States[i].tranlist[j].sym=inp[j];
k=0;
ans='y';
while(ans=='y')
printf("move(%d,%c);",i,inp[j]);
scanf("%d",&States[i].tranlist[j].tostates[k++]);
if((States[i].tranlist[j].tostates[k-1]==-1))
{
k--;
ans='n';
break;
States[i].tranlist[j].notran=k;
i=0;nods=0,fin=0;
pushA(start);
lambda_closure(peekA());
tostring();
Dstates[nods].name='A';
nods++;
strcpy(Dstates[0].StateString,temp);
while(i
for(j=0;j
fin=0;
copy(i);
while(Bptr!=-1)
move(popB(),j);
while(Aptr!=-1)
lambda_closure(peekA());
tostring();
for(k=0;k
if((strcmp(temp,Dstates[k].StateString)==0))
Dstates[i].trans[j]=Dstates[k].name;
break;
if(k==nods)
nods++;
for(k=0;k
fin=seek(stackB,Bptr,final[k]);
if(fin==1)
Dstates[nods-1].is_final=1;
break;
strcpy(Dstates[nods-1].StateString,temp);
Dstates[nods-1].name='A'+nods-1;
Dstates[i].trans[j]=Dstates[nods-1].name;
i++;
display_DTran();
}
OUTPUT:
a ,b
move(0,a);-1
move(0,b);-1
move(0,e);1
move(0,e);7
move(0,e);-1
move(1,a);-1
move(1,b);-1
move( 1,e);2
move(1,e);4
move(1,e);-1
move(2,a);3
move(2,a);3
move(2,a);-1
move(2,b);-1
move(2,e);-1
move(3,a);-1
move(3,b);-1
move(3,e);6
move(3,e);-1
move(4,a);-1
move(4,b);-1
move(4,e);-1
move(5,a);-1
move(5,b);-1
move(5,e);6
move(5,e);1
move(5,e);-1
move(6,a);-1
move(6,b);-1
move(6,e);-1
move(7,a);-1
move(7,b);-1
move(7,e);-1
a b
-------------------------------------------------
A 01247 B C
B 36 C C
C C C
int i,j,l,m,n=0,o,p,nv,z=0,x=0;
char str[10],temp,temp2[10],temp3[20],*ptr;
struct prod
{
char lhs[10],rhs[10][10],ft[10],fol[10];
int n;
}pro[10];
void findter()
{
int k,t;
for(k=0;k<n;k++)
{
if(temp==pro[k].lhs[0])
{
for(t=0;t<pro[k].n;t++)
{
if( pro[k].rhs[t][0]<65 || pro[k].rhs[t][0]>90 )
pro[i].ft[strlen(pro[i].ft)]=pro[k].rhs[t][0];
else if( pro[k].rhs[t][0]>=65 && pro[k].rhs[t]
[0]<=90 )
{
temp=pro[k].rhs[t][0];
if(temp=='S')
pro[i].ft[strlen(pro[i].ft)]='#';
findter();
}
}
break;
}
}
}
void findfol()
{
int k,t,p1,o1,chk;
char *ptr1;
for(k=0;k<n;k++)
{
chk=0;
for(t=0;t<pro[k].n;t++)
{
ptr1=strchr(pro[k].rhs[t],temp);
if( ptr1 )
{
p1=ptr1-pro[k].rhs[t];
if(pro[k].rhs[t][p1+1]>=65 && pro[k].rhs[t]
[p1+1]<=90)
{
for(o1=0;o1<n;o1++)
if(pro[o1].lhs[0]==pro[k].rhs[t][p1+1])
{
strcat(pro[i].fol,pro[o1].ft);
chk++;
}
}
else if(pro[k].rhs[t][p1+1]=='\0')
{
temp=pro[k].lhs[0];
if(pro[l].rhs[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
chk++;
}
else
{
pro[i].fol[strlen(pro[i].fol)]=pro[k].rhs[t]
[p1+1];
chk++;
}
}
}
if(chk>0)
break;
}
}
int main()
{
FILE *f;
//clrscr();
for(i=0;i<10;i++)
pro[i].n=0;
f=fopen("tab5.txt","r");
while(!feof(f))
{
fscanf(f,"%s",pro[n].lhs);
if(n>0)
{
if( strcmp(pro[n].lhs,pro[n-1].lhs) == 0 )
{
pro[n].lhs[0]='\0';
fscanf(f,"%s",pro[n-1].rhs[pro[n-1].n]);
pro[n-1].n++;
continue;
}
}
fscanf(f,"%s",pro[n].rhs[pro[n].n]);
pro[n].n++;
n++;
}
pro[0].ft[0]='#';
for(i=0;i<n;i++)
{
for(j=0;j<pro[i].n;j++)
{
if( pro[i].rhs[j][0]<65 || pro[i].rhs[j][0]>90 )
{
pro[i].ft[strlen(pro[i].ft)]=pro[i].rhs[j][0];
}
else if( pro[i].rhs[j][0]>=65 && pro[i].rhs[j]
[0]<=90 )
{
temp=pro[i].rhs[j][0];
if(temp=='S')
pro[i].ft[strlen(pro[i].ft)]='#';
findter();
}
}
}
printf("\n\nFIRST\n");
for(i=0;i<n;i++)
{
printf("\n%s -> ",pro[i].lhs);
for(j=0;j<strlen(pro[i].ft);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].ft[l]==pro[i].ft[j])
break;
if(l==-1)
printf("%c",pro[i].ft[j]);
}
}
for(i=0;i<n;i++)
temp2[i]=pro[i].lhs[0];
pro[0].fol[0]='$';
for(i=0;i<n;i++)
{
for(l=0;l<n;l++)
{
for(j=0;j<pro[i].n;j++)
{
ptr=strchr(pro[l].rhs[j],temp2[i]);
if( ptr )
{
p=ptr-pro[l].rhs[j];
if(pro[l].rhs[j][p+1]>=65 && pro[l].rhs[j]
[p+1]<=90)
{
for(o=0;o<n;o++)
if(pro[o].lhs[0]==pro[l].rhs[j][p+1])
strcat(pro[i].fol,pro[o].ft);
}
else if(pro[l].rhs[j][p+1]=='\0')
{
temp=pro[l].lhs[0];
if(pro[l].rhs[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
}
else
pro[i].fol[strlen(pro[i].fol)]=pro[l].rhs[j][p+1];
}
}
}
}
printf("\n\nFOLLOW\n");
for(i=0;i<n;i++)
{
printf("\n%s -> ",pro[i].lhs);
for(j=0;j<strlen(pro[i].fol);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].fol[l]==pro[i].fol[j])
break;
if(l==-1)
printf("%c",pro[i].fol[j]);
}
}
printf("\n");
//getch();
}
S ABE
Sa
Ap
At
B Aq
Sf
Aw
15. Design and implement a recursive descent parser for
a given grammar.
LOGIC: Read the input string. Write procedures for the non
terminals Verify the next token equals to non terminals if it
satisfies match the non terminal. If the input string does not
match print error.
PROGRAM:
#include
#include
#include
char input[100];
int i,l;
void main()
clrscr();
if(E())
if(input[i+1]=='\0')
printf("\nString is accepted");
else
else
getch();
E()
if(T())
if(EP())
return(1);
else
return(0);
else
return(0);
EP()
if(input[i]=='+')
i++;
if(T())
{
if(EP())
return(1);
else
return(0);
else
return(0);
else
return(1);
T()
if(F())
if(TP())
return(1);
else
return(0);
else
return(0);
TP()
if(input[i]=='*')
{
i++;
if(F())
if(TP())
return(1);
else
return(0);
else
return(0);
else
return(1);
F()
if(input[i]=='(')
i++;
if(E())
if(input[i]==')')
i++;
return(1);
}
else
return(0);
else
return(0);
else if(input[i]>='a'&&input[i]<='z'||
input[i]>='A'&&input[i]<='Z')
i++;
return(1);
else
return(0);
E->TE'
E'->+TE'/@
T->FT'
T'->*FT'/@
F->(E)/ID
String is accepted
E->TE'
E'->+TE'/@
T->FT'
T'->*FT'/@
F->(E)/id
ALGORITHM:
1. Get the input expression and store it in the input buffer.
2. Read the data from the input buffer one at the time.
3. Using stack and push & pop operation shift and reduce symbols with respect to production
rules available.
4. Continue the process till symbol shift and production rule reduce reaches the start symbol.
5. Display the Stack Implementation table with corresponding Stack actions with input
symbols.
PROGRAM:
#include
#include
#include
#include
char ip_sym[15],stack[15];
int ip_ptr=0,st_ptr=0,len,i;
char temp[2],temp2[2];
char act[15];
void check();
void main()
clrscr();
printf("\n GRAMMER\n");
gets(ip_sym);
printf("\n________\t\t____________\t\t____________\n");
printf("\n $\t\t%s$\t\t\t--",ip_sym);
strcpy(act,"shift");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
len=strlen(ip_sym);
for(i=0;i<=len-1;i++)
stack[st_ptr]=ip_sym[ip_ptr];
stack[st_ptr+1]='\0';
ip_sym[ip_ptr]=' ';
ip_ptr++;
printf("\n $%s\t\t%s$\t\t\t%s",stack,ip_sym,act);
strcpy(act,"shift");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
check();
st_ptr++;
st_ptr++;
check();
void check()
{
int flag=0;
temp2[0]=stack[st_ptr];
temp2[1]='\0';
if((!strcmpi(temp2,"a"))||(!strcmpi(temp2,"b")))
stack[st_ptr]='E';
if(!strcmpi(temp2,"a"))
printf("\n $%s\t\t%s$\t\t\tE->a",stack,ip_sym);
else
printf("\n $%s\t\t%s$\t\t\tE->b",stack,ip_sym);
flag=1;
if((!strcmpi(temp2,"+"))||(strcmpi(temp2,"*"))||(!
strcmpi(temp2,"/")))
flag=1;
if((!strcmpi(stack,"E+E"))||(!strcmpi(stack,"E\E"))||(!
strcmpi(stack,"E*E")))
strcpy(stack,"E");
st_ptr=0;
if(!strcmpi(stack,"E+E"))
printf("\n $%s\t\t%s$\t\t\tE->E+E",stack,ip_sym);
else
if(!strcmpi(stack,"E\E"))
printf("\n $%s\t\t%s$\t\t\tE->E\E",stack,ip_sym);
else
if(!strcmpi(stack,"E*E"))
printf("\n $%s\t\t%s$\t\t\tE->E*E",stack,ip_sym);
else
printf("\n $%s\t\t%s$\t\t\tE->E+E",stack,ip_sym);
flag=1;
if(!strcmpi(stack,"E")&&ip_ptr==len)
printf("\n $%s\t\t%s$\t\t\tACCEPT",stack,ip_sym);
getch();
exit(0);
if(flag==0)
printf("\n%s\t\t\t%s\t\t reject",stack,ip_sym);
exit(0);
return;
OUTPUT:
GRAMMER
E->E+E
E->E/E
E->E*E
E->a/b
$ a+b$ --
$a +b$ shift a
$E +b$ E->a
$E+ b$ shift +
$E+b $ shift b
$E+E $ E->b
$E $ E->E+E
$E $ ACCEPT
17. Write a program to perform constant propagation.
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<conio.h>
void input();
void output();
void change(int p,char *res);
void constant();
struct expr
{
char op[2],op1[5],op2[5],res[5];
int flag;
}arr[10];
int n;
void main()
{
clrscr();
input();
constant();
output();
getch();
}
void input()
{
int i;
printf("\n\nEnter the maximum number of expressions : ");
scanf("%d",&n);
printf("\nEnter the input : \n");
for(i=0;i<n;i++)
{
scanf("%s",arr[i].op);
scanf("%s",arr[i].op1);
scanf("%s",arr[i].op2);
scanf("%s",arr[i].res);
arr[i].flag=0;
}
}
void constant()
{
int i;
int op1,op2,res;
char op,res1[5];
for(i=0;i<n;i++)
{
if(isdigit(arr[i].op1[0]) && isdigit(arr[i].op2[0]) ||
strcmp(arr[i].op,"=")==0) /*if both digits, store them in
variables*/
{
op1=atoi(arr[i].op1);
op2=atoi(arr[i].op2);
op=arr[i].op[0];
switch(op)
{
case '+':
res=op1+op2;
break;
case '-':
res=op1-op2;
break;
case '*':
res=op1*op2;
break;
case '/':
res=op1/op2;
break;
case '=':
res=op1;
break;
}
sprintf(res1,"%d",res);
arr[i].flag=1; /*eliminate expr and replace any operand below that
uses result of this expr */
change(i,res1);
}
}
}
void output()
{
int i=0;
printf("\nOptimized code is : ");
for(i=0;i<n;i++)
{
if(!arr[i].flag)
{
printf("\n%s %s %s
%s",arr[i].op,arr[i].op1,arr[i].op2,arr[i].res);
}
}
}
void change(int p,char *res)
{
int i;
for(i=p+1;i<n;i++)
{
if(strcmp(arr[p].res,arr[i].op1)==0)
strcpy(arr[i].op1,res);
else if(strcmp(arr[p].res,arr[i].op2)==0)
strcpy(arr[i].op2,res);
}
}
INPUT:
OUTPUT:
Optimized code is :
+ 3 b t1
+ 3 c t2
+ t1 t2 t3
18. C program to implement intermediate code
generation for simple expression.
Program
#include<stdio.h>
#include<conio.h>
#include<string.h>
int i=1,j=0,no=0,tmpch=90;
char str[100],left[15],right[15];
void findopr();
void explore();
void fleft(int);
void fright(int);
struct exp
{
int pos;
char op;
}k[15];
void main()
{
printf("\t\tINTERMEDIATE CODE GENERATION\n\n");
printf("Enter the Expression :");
scanf("%s",str);
printf("The intermediate code:\n");
findopr();
explore();
}
void findopr()
{
for(i=0;str[i]!='\0';i++)
if(str[i]==':')
{
k[j].pos=i;
k[j++].op=':';
}
for(i=0;str[i]!='\0';i++)
if(str[i]=='/')
{
k[j].pos=i;
k[j++].op='/';
}
for(i=0;str[i]!='\0';i++)
if(str[i]=='*')
{
k[j].pos=i;
k[j++].op='*';
}
for(i=0;str[i]!='\0';i++)
if(str[i]=='+')
{
k[j].pos=i;
k[j++].op='+';
}
for(i=0;str[i]!='\0';i++)
if(str[i]=='-')
{
k[j].pos=i;
k[j++].op='-';
}
}
void explore()
{
i=1;
while(k[i].op!='\0')
{
fleft(k[i].pos);
fright(k[i].pos);
str[k[i].pos]=tmpch--;
printf("\t%c := %s%c%s\t\t",str[k[i].pos],left,k[i].op,right);
printf("\n");
i++;
}
fright(-1);
if(no==0)
{
fleft(strlen(str));
printf("\t%s := %s",right,left);
getch();
exit(0);
}
printf("\t%s := %c",right,str[k[--i].pos]);
getch();
}
void fleft(int x)
{
int w=0,flag=0;
x--;
while(x!= -1 &&str[x]!= '+' &&str[x]!='*'&&str[x]!='='&&str[x]!
='\0'&&str[x]!='-'&&str[x]!='/'&&str[x]!=':')
{
if(str[x]!='$'&& flag==0)
{
left[w++]=str[x];
left[w]='\0';
str[x]='$';
flag=1;
}
x--;
}
}
void fright(int x)
{
int w=0,flag=0;
x++;
while(x!= -1 && str[x]!= '+'&&str[x]!='*'&&str[x]!='\0'&&str[x]!
='='&&str[x]!=':'&&str[x]!='-'&&str[x]!='/')
{
if(str[x]!='$'&& flag==0)
{
right[w++]=str[x];
right[w]='\0';
str[x]='$';
flag=1;
}
x++;
}
}
19. Implement the back end of the compiler which takes
the three address code and produces the 8086 assembly
language instructions that can be assembled and run
using an 8086 assembler. The target assembly
instructions can be simple move, add, sub, jump etc.
#include<stdio.h>
#include<stdio.h>
//#include<conio.h>
#include<string.h>
void main(){
char icode[10][30],str[20],opr[10];
int i=0;
//clrscr();
printf("\n Enter the set ofintermediate code (terminated
byexit):\n");
do{
scanf("%s",icode[i]);
} while(strcmp(icode[i++],"exit")!=0);
printf("\n target code generation");
printf("\n************************");
i=0;
do{strcpy(str,icode[i]);
switch(str[3]){
case '+':strcpy(opr,"ADD");break;
case '-':strcpy(opr,"SUB");break;
case '*':strcpy(opr,"MUL");break;
case '/':strcpy(opr,"DIV");break;}
printf("\n\tMov %c,R%d",str[2],i);
printf("\n\t%s%c,R%d",opr,str[4],i);
printf("\n\tMov R%d,%c",i,str[0]);}while(strcmp(icode[+
+i],"exit")!=0);
//getch();}