CD Labmanual
CD Labmanual
CD Labmanual
The lexical
analyzer should ignore redundant spaces, tabs and newlines. It
should also ignore comments. Although the syntax specification
states that identifiers can be arbitrarily long, you may restrict the
length to some reasonable value.
Description:
position:=initial + rate * 60
The number 60
Program:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
main()
{
intcount,i,j,p;
char c,s,ch,st[50];
FILE *fp;
count=0;
fp=fopen("g.c","r");
if(fp==NULL)
{
printf("cannot open source file\n");
return 0; }
while(1)
{
ch=fgetc(fp);
if(ch==EOF)
break;
while(1)
if(count==1)
count=0;
if(isalpha(ch))
s=ch;
ch='x';
else if(isdigit(ch))
{
ch='y';
ch='z';
else if(ch=='/')
c=fgetc(fp);
if(c=='/')
while(c!='\n')
c=fgetc(fp);
break;
else if(c=='*')
while(1)
if(fgetc(fp)=='*')
if(fgetc(fp)=='/')
{
p=1;
break;
if(p==1)
p=0;
break;
else
ch='z';
else if(ch=='+'||ch=='*'||ch=='/'||ch=='%'||ch=='^')
ch='w';
switch(ch)
{
case '<':{c=fgetc(fp);
if(c=='=')
else
count=1;
break;
case '>':
c=fgetc(fp);
if(c=='=')
else
count=1;
break;
}
case '=':
c=fgetc(fp);
if(c=='=')
else
count=1;
break; }
case '!':
if(fgetc(fp)=='=')
break;
case 'x':
{
i=0;
st[i++]=s;
c=fgetc(fp);
while(isalpha(c)||isdigit(c)||c=='-')
st[i++]=c;
c=fgetc(fp);
st[i]='\0';
count=1;
if(strcmp(st,"int")==0||strcmp(st,"float")==0||strcmp(st,"char")==0||
strcmp(st,"static")==0||strcmp(st,"do")==0||strcmp(st,"case")==0||
strcmp(st,"while")==0||strcmp(st,"if")==0||strcmp(st,"else")==0||
strcmp(st,"auto")==0||strcmp(st,"for")==0)
printf("\n keyword\t\t");
else
printf("\n identifier\t");
break;
}
case 'y':
c=fgetc(fp);
while(isdigit(c))
c=fgetc(fp);
if(c=='.')
c=fgetc(fp);
while(isdigit(c))
c=fgetc(fp);
else
count=1;
break;
case 'z':
{
break;
case 'w':
break;
case '\n':
printf("\n");
break;
ch=c;
if(count==0)
break;
} } }
fclose(fp);
return 0;
OUTPUT:
g.c program is:
main()
{
inta,b;
a=10;
}
Output is:
identifier
special symbol
special symbol
special symbol
keyword
identifier
Implement the lexical analyzer using JLex, flex or lex or other lexical
analyzer generating tools.
Description:
Lex is an unix utility which generates the lexical analyzer in lex tool designing the
regular expressions for corresponding tokens is a logical task. The file name can
be specified as lex.l and is given to lex compiler to produce lex.yy.c. the lex.yy.c
is given to C compiler to produce executable program.
Program:
delim [ \t\n]
ws {delim}+
digit [0-9]
num {digit}+
num1 {digit}+.{digit}+
letter [a-zA-Z]
id {letter}({letter}|{digit})*
%%
{ws} { }
{num1} {printf("\n %s \t\treal\n",yytext);}
E->TE1
E1->+TE1 | Epsilon
T->FT1
T1->*FT1 | Epsilon
F->(E) | i
Description:
Recursive Descent parser is the one of the Predictive parser. In Recursive Descent
parsing, we create a separate function for each nonterminal in the given
grammar.Parser program activated by function of start symbol.
/*
implementation of recursive descent (predictive parser) for the grammer
E->TE1
E1->+TE1 | Epsilon
T->FT1
T1->*FT1 | Epsilon
F->(E) | i
*/
#include<stdio.h>
#include<string.h>
charip[100];
char *ptr;
void E(void);
void E1(void);
void T(void);
void T1(void);
void F(void);
main()
{
system("clear");
printf("\nenter the string to be parsed with $ at end\n");
scanf("%s",ip);
ptr=ip;
E();
if(*ptr=='$')
{
printf("\nSting : %s is Accepted",ip);
}
else
{
printf("\nString : %s is Rejected",ip);
}
}
void E(void)
{
T();
E1();
}
void E1(void)
{
if(*ptr=='+')
{
ptr++;
T();
E1();
}
else
{
/*do nothing as E1 -> epsilon*/
}
}
void T(void)
{
F();
T1();
}
void T1(void)
{
if(*ptr=='*')
{
ptr++;
F();
T1();
}
else
{
/*do nothing as T1 -> epsilon*/
}
}
void F(void)
{
if(*ptr=='(')
{
ptr++;
E();
if(*ptr==')')
ptr++;
else
{
printf("\nERROR");
ptr++;
}
}
else if(*ptr=='i')
ptr++;
}
OUTPUT :
enter the string to be parsed with $ at end
i+i*i$
Sting :i+i*i$ is Accepted
enter the string to be parsed with $ at end
i+i*(i+i)$
String :i+i*(i+i) is Rejected
char T[]="+*()de";
char NT[]="EATBF";
char FT[5][6];
char FLWT[5][6];
"A->+TA",
"A->e",
"T->FB",
"B->*FB",
"B->e",
"F->(E)",
"F->d" };
intgetIndex(char A[],char c)
{
int i=0;
for(i=0;i<8;i++)
if(A[i]==c)
return i;
return -1;
voidaddEpsilon(char c)
FT[getIndex(NT,c)][5]='e';
inthasEpsilon(char c)
if(FT[getIndex(NT,c)][5]=='e')
return(1);
return(0);
intisNonTerminal(char c)
int i;
for(i=0;i<8;i++)
{
if(NT[i]==c)
return 1;
return 0;
intisTerminal(char c)
int i=0;
for(i=0;i<8;i++)
if(T[i]==c)
return 1;
return 0;
voidComputeFollow()
intlen,i,j,k,added=0;
char sym1,sym2,elm1,elm2,sym;
FLWT[getIndex(NT,'E')][5]='$';
for(i=0;i<8;i++)
{
len=strlen(P[i]);
for(j=3;j<len;j++)
sym1=P[i][j];
sym2=P[i][j+1];
if(isNonTerminal(sym1) &&isTerminal(sym2))
FLWT[getIndex(NT,sym1)][getIndex(T,sym2)]=sym2;
for(i=0;i<8;i++)
len=strlen(P[i]);
for(j=3;j<len;j++)
sym1=P[i][j];
sym2=P[i][j+1];
if(isNonTerminal(sym1) &&isNonTerminal(sym2))
for(k=0;k<6;k++)
elm1=FLWT[getIndex(NT,sym1)][k];
elm2=FT[getIndex(NT,sym2)][k];
if(elm1!=elm2)
FLWT[getIndex(NT,sym1)][k]=elm2;
for(i=0;i<8;i++)
sym1=P[i][strlen(P[i])-1];
if(isNonTerminal(sym1))
sym2=P[i][0];
for(k=0;k<6;k++)
elm1=FLWT[getIndex(NT,sym1)][k];
elm2=FLWT[getIndex(NT,sym2)][k];
if(elm1!=elm2)
{
added=1;
FLWT[getIndex(NT,sym1)][k]=elm2;
sym=P[i][strlen(P[i])-1];
if(isNonTerminal(sym) &&hasEpsilon(sym))
sym1=P[i][strlen(P[i])-2];
if(isNonTerminal(sym1))
sym2=P[i][0];
for(k=0;k<6;k++)
elm1=FLWT[getIndex(NT,sym1)][k];
elm2=FLWT[getIndex(NT,sym2)][k];
if(elm1!=elm2)
added=1;
FLWT[getIndex(NT,sym1)][k]=elm2;
}
}
if(i==7)
if(added)
i=-1;
added=0;
voidComputeFirst()
int added=0,i,j,k;
char X,elm1,elm2;
clrscr();
for(i=0;i<5;i++)
for(j=0;j<6;j++)
{
FT[i][j]='\0';
for(i=0;i<8;i++)
X = P[i][3];
if(X=='e')
addEpsilon(P[i][0]);
else if(isTerminal(X))
FT[getIndex(NT,P[i][0])][getIndex(T,X)]=X;
for(i=0;i<8;i++)
X = P[i][3];
if(isNonTerminal(X))
for(j=3;j<6;j++) {
X=P[i][j];
for(k=0;k<5;k++)
{
elm1=FT[getIndex(NT,P[i][0])][k];
elm2=FT[getIndex(NT,X)][k];
if(elm1!=elm2)
if(elm2!='\0')
added=1;
FT[getIndex(NT,P[i][0])][k]=elm2;
if(!hasEpsilon(X))
break;
if(j==strlen(P[i]))
added=1;
FT[getIndex(NT,P[i][0])][5]='e';
if(i==7)
if(added)
{
i=-1;
added=0;
void main()
inti,j;
ComputeFirst();
for(i=0;i<8;i++)
printf("%s\n",P[i]);
for(i=0;i<5;i++)
printf("FIRST(%c)={",NT[i]);
for(j=0;j<6;j++)
if(FT[i][j]!='\0')
printf("%c,",FT[i][j]);
}
printf("\b}\n");
ComputeFollow();
for(i=0;i<5;i++)
printf("FOLLOW(%c)={",NT[i]);
for(j=0;j<6;j++)
if(FLWT[i][j]!='\0')
printf("%c,",FLWT[i][j]);
printf("\b}\n");
getch();
Output:
E->TA
A->+TA
A->e
T->FB
B->*FB
B->e
F->(E)
F->d
FIRST(E)={(,d}
FIRST(A)={+,e}
FIRST(T)={(,d}
FIRST(B)={*,e}
FIRST(F)={(,d}
FOLLOW(E)={),$}
FOLLOW(A)={),$}
FOLLOW(T)={+,),$}
FOLLOW(B)={+,),$}
FOLLOW(F)={+,*,),$}
YACC is one automatic tool for generating the parser program. YACC stands for
Yet Another Compiler Compiler with is basically the utility available from unix.
YACC can report conflicts in the form of error messages.
Program:
%{
#include<stdio.h>
#include"y.tab.h"
%}
%%
[0-9]+ { yylval.dval=atoi(yytext);
return DIGIT;
}
\n|. returnyytext[0];
%%
%{
#include<stdio.h>
%}
%union
{
doubledval;
}
%type <dval>expr
%type <dval> term
%type <dval> factor
%%
%%
int main()
{
printf("enter expression : ");
yyparse();
return 0;
}
yyerror(char *s)
{
printf("%s",s);
}
Execution:
$lexparser.l
$yacc -d parser.y
$cc lex.yy.cy.tab.c -ll -lm
$./a.out
enter expression :2+3*5
17
Method:
1.Let the input string to be initially the stack contains, when the reduce action takes place we
have to reach create parent child relationship.
2. See IP to pointer to the first symbol of input string and repeat forever if only $ is on the
input accept and break else begin.
3. Let 'd’ be the top most terminal on the stack and 'b' be current input IF(a<b) or a=b then
Begin push 'b' onto the stack.
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
char q[9][9]={
{'>','>','<','<','<','<','>','<','>' },
{'>','>','<','<','<','<','>','<','>' },
{'>','>','>','>','<','<','>','<','>' },
{'>','>','>','>','<','<','>','<','>' },
{'>','>','<','<','<','<','>','<','>' },
{'<','<','<','<','<','<','=','<','E' },
{'>','>','>','>','>','E','>','E','>' },
{'>','>','>','>','>','E','>','E','>' },
{'<','<','<','<','<','<','E','<','A' }
};
char s[30],st[30],qs[30];
int top=-1,r=-1,p=0;
void push(char a)
top++;
st[top]=a;
char pop()
char a;
a=st[top];
top--;
return a;
int find(char a)
switch(a)
case '+':return 0;
case '-':return 1;
case '*':return 2;
case '/':return 3;
case '^':return 4;
case '(':return 5;
case ')':return 6;
case 'a':return 7;
case '$':return 8;
void display(char a)
void display1(char a)
{
if(isalpha(a))
else if((a=='+')||(a=='-')||(a=='*')||(a=='/')||(a=='^'))
else if(a==')')
intrel(char a,charb,char d)
if(isalpha(a)!=0)
a='a';
if(isalpha(b)!=0)
b='a';
if(q[find(a)][find(b)]==d)
return 1;
else
return 0;
void main()
char s[100];
int i=-1;
clrscr();
gets(s);
push('$');
while(i)
if((s[p]=='$')&&(st[top]=='$'))
printf("\n\nAccepted");
break;
else if(rel(st[top],s[p],'<')||rel(st[top],s[p],'='))
display(s[p]);
push(s[p]);
p++;
else if(rel(st[top],s[p],'>'))
do
r++;
qs[r]=pop();
display1(qs[r]);
while(!rel(st[top],qs[r],'<'));
getch();
}
Output:
Shift a
Reduce E->a
Shift +
Shift b
Reduce E->b
Shift *
Shift a
Reduce E->a
Reduce E->E*E
Reduce E->E+E
Accepted
Program:
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
charip_sym[15],stack[15];
intip_ptr=0,st_ptr=0,len,i;
char temp[2],temp2[2];
char act[15];
void check();
void main()
clrscr();
printf("\n Grammar\n\n");
printf("E->E+E\nE->E/E\n");
printf("E->E*E\nE->a/b");
gets(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();
getch();
void check()
{
int flag=0;
temp2[0]=stack[st_ptr];
temp[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->a",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\t%s$\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",ip_sym);
getch();
exit(0);
if(flag==0)
return;
Output:
Grammar
E->E+E
E->E/E
E->E*E
E->a/b
$ a+b$ --
$a +b$ shifta
$E +b$ E->a
$E+ b$ shift+
$E+b $ shiftb
$E+E $ E->a
$E $ E->E*E
$ ☻=$ Accept
#include<stdio.h>
main(void)
int i = 0;
while (repeat--)
printf("process(%d)\n", i );
printf("process(%d)\n", i + 1);
printf("process(%d)\n", i + 2);
printf("process(%d)\n", i + 3);
printf("process(%d)\n", i + 4);
printf("process(%d)\n", i + 5);
printf("process(%d)\n", i + 6);
printf("process(%d)\n", i + 7);
i += TOGETHER;
/* at the label that will then drop through to complete the set */
switch (left)
{
}return 0;
Output:
process(0)
process(1)
process(2)
process(3)
process(4)
process(5)
process(6)
process(7)
process(8)
process(9)
process(10)
process(11)
process(12)
process(13)
process(14)
process(15)
process(16)
process(17)
process(18)
process(19)
process(20)
process(21)
process(22)
process(23)
process(24)
process(25)
process(26)
process(27)
process(28)
process(29)
process(30)
process(31)
process(32)
#include<conio.h>
#include<string.h>
void main()
char fin[10][20],st[10][20],ft[20][20],fol[20][20];
int a=0,e,i,t,b,c,n,k,l=0,j,s,m,p;
clrscr();
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%s",st[i]);
for(i=0;i<n;i++)
fol[i][0]='\0';
for(s=0;s<n;s++)
for(i=0;i<n;i++)
j=3;
l=0;
a=0;
l1:if(!((st[i][j]>64)&&(st[i][j]<91)))
for(m=0;m<l;m++)
if(ft[i][m]==st[i][j])
goto s1;
}
ft[i][l]=st[i][j];
l=l+1;
s1:j=j+1;
else
if(s>0)
while(st[i][j]!=st[a][0])
a++;
b=0;
while(ft[a][b]!='\0')
for(m=0;m<l;m++)
if(ft[i][m]==ft[a][b])
goto s2;
ft[i][l]=ft[a][b];
l=l+1;
s2:b=b+1;
}
}
while(st[i][j]!='\0')
if(st[i][j]=='|')
j=j+1;
goto l1;
j=j+1;
ft[i][l]='\0';
printf("first pos\n");
for(i=0;i<n;i++)
printf("FIRS[%c]=%s\n",st[i][0],ft[i]);
fol[0][0]='$';
for(i=0;i<n;i++)
k=0;
j=3;
if(i==0)
l=1;
else
l=0;
k1:while((st[i][0]!=st[k][j])&&(k<n))
{
if(st[k][j]=='\0')
k++;
j=2;
j++;
j=j+1;
if(st[i][0]==st[k][j-1])
if((st[k][j]!='|')&&(st[k][j]!='\0'))
a=0;
if(!((st[k][j]>64)&&(st[k][j]<91)))
for(m=0;m<l;m++)
if(fol[i][m]==st[k][j])
goto q3;
fol[i][l]=st[k][j];
l++;
q3:
else
{
while(st[k][j]!=st[a][0])
a++;
p=0;
while(ft[a][p]!='\0')
if(ft[a][p]!='@')
for(m=0;m<l;m++)
if(fol[i][m]==ft[a][p])
goto q2;
fol[i][l]=ft[a][p];
l=l+1;
else
e=1;
q2:p++;
if(e==1)
e=0;
goto a1;
}
else
a1:c=0;
a=0;
while(st[k][0]!=st[a][0])
a++;
while((fol[a][c]!='\0')&&(st[a][0]!=st[i][0]))
for(m=0;m<l;m++)
if(fol[i][m]==fol[a][c])
goto q1;
fol[i][l]=fol[a][c];
l++;
q1:c++;
goto k1;
fol[i][l]='\0';
}
printf("follow pos\n");
for(i=0;i<n;i++)
printf("FOLLOW[%c]=%s\n",st[i][0],fol[i]);
printf("\n");
s=0;
for(i=0;i<n;i++)
j=3;
while(st[i][j]!='\0')
if((st[i][j-1]=='|')||(j==3))
for(p=0;p<=2;p++)
fin[s][p]=st[i][p];
t=j;
for(p=3;((st[i][j]!='|')&&(st[i][j]!='\0'));p++)
fin[s][p]=st[i][j];
j++;
fin[s][p]='\0';
if(st[i][k]=='@')
{
b=0;
a=0;
while(st[a][0]!=st[i][0])
a++;
while(fol[a][b]!='\0')
printf("M[%c,%c]=%s\n",st[i][0],fol[a][b],fin[s]);
b++;
else if(!((st[i][t]>64)&&(st[i][t]<91)))
printf("M[%c,%c]=%s\n",st[i][0],st[i][t],fin[s]);
else
b=0;
a=0;
while(st[a][0]!=st[i][3])
a++;
while(ft[a][b]!='\0')
printf("M[%c,%c]=%s\n",st[i][0],ft[a][b],fin[s]);
b++;
}
s++;
if(st[i][j]=='|')
j++;
getch();
Output:
S->CC
C->eC|d
firstpos
FIRS[S]=ed
FIRS[C]=ed
followpos
FOLLOW[S]=$
FOLLOW[C]=ed$
M[S,e]=S->CC
M[S,d]=S->CC
M[C,e]=C->eC
M[C,d]=C->d