Hello Friend,
In this post we will discuss how to find FIRST of a grammar using C.
The rules for finding FIRST of a given grammar is:
- If X is terminal, FIRST(X) = {X}.
- If X → ε is a production, then add ε to FIRST(X).
- If X is a non-terminal, and X → Y1 Y2 … Yk is a production, and ε is in all of FIRST(Y1), …, FIRST(Yk), then add ε to FIRST(X).
- If X is a non-terminal, and X → Y1 Y2 … Yk is a production, then add a to FIRST(X) if for some i, a is in FIRST(Yi), and ε is in all of FIRST(Y1), …, FIRST(Yi-1).
- Each Non terminal character is represented by one Uppercase letter.
- Each Terminal character is represented by one lowercase letter.
- LHS and RHS of each production will be separated by a "=" symbol.
- There will be no Blank space within a production string.
- Assumed that Left recursion is avoided in all input productions.
* mail: vipinnarayantvm@gmail.com
*Modified on : 23/03/2105
*/
#include<stdio.h>
#include<ctype.h>
void FIRST(char[],char );
void addToResultSet(char[],char);
int numOfProductions;
char productionSet[10][10];
main()
{
int i;
char choice;
char c;
char result[20];
printf("How many number of productions ? :");
scanf(" %d",&numOfProductions);
for(i=0;i<numOfProductions;i++)//read production string eg: E=E+T
{
printf("Enter productions Number %d : ",i+1);
scanf(" %s",productionSet[i]);
}
do
{
printf("\n Find the FIRST of :");
scanf(" %c",&c);
FIRST(result,c); //Compute FIRST; Get Answer in 'result' array
printf("\n FIRST(%c)= { ",c);
for(i=0;result[i]!='\0';i++)
printf(" %c ",result[i]); //Display result
printf("}\n");
printf("press 'y' to continue : "); scanf(" %c",&choice);
}
while(choice=='y'||choice =='Y');
}
/*
*Function FIRST:
*Compute the elements in FIRST(c) and write them
*in Result Array.
*/
void FIRST(char* Result,char c)
{
int i,j,k;
char subResult[20];
int foundEpsilon;
subResult[0]='\0';
Result[0]='\0';
//If X is terminal, FIRST(X) = {X}.
if(!(isupper(c)))
{
addToResultSet(Result,c);
return ;
}
//If X is non terminal
//Read each production
for(i=0;i<numOfProductions;i++)
{
//Find production with X as LHS
if(productionSet[i][0]==c)
{
//If X → ε is a production, then add ε to FIRST(X).
if(productionSet[i][2]=='$') addToResultSet(Result,'$');
//If X is a non-terminal, and X → Y1 Y2 … Yk
//is a production, then add a to FIRST(X)
//if for some i, a is in FIRST(Yi),
//and ε is in all of FIRST(Y1), …, FIRST(Yi-1).
else
{
j=2;
while(productionSet[i][j]!='\0')
{
foundEpsilon=0;
FIRST(subResult,productionSet[i][j]);
for(k=0;subResult[k]!='\0';k++)
addToResultSet(Result,subResult[k]);
for(k=0;subResult[k]!='\0';k++)
if(subResult[k]=='$')
{
foundEpsilon=1;
break;
}
//No ε found, no need to check next element
if(!foundEpsilon)
break;
j++;
}
}
}
}
return ;
}
/* addToResultSet adds the computed
*element to result set.
*This code avoids multiple inclusion of elements
*/
void addToResultSet(char Result[],char val)
{
int k;
for(k=0 ;Result[k]!='\0';k++)
if(Result[k]==val)
return;
Result[k]=val;
Result[k+1]='\0';
}
Output
can u pls help me to execute this program with one input output example.
ReplyDelete@rahul
ReplyDeleteOk... Look at this sample execution..
Input:
How many productions? 8
Enter 8 productions:
E = TD
D=+TD
D=$
T=FS
S=*FS
S=$
F=(E)
F=a
output
FIRST (E) = FIRST (T) =FIRST (F) = { ( , a}
FIRST (D) = { + , ε }
FIRST (S)= { * , ε }
what does this code do pls explain line wise
ReplyDeletevoid FIRST(char c)
{
int j;
if(!(isupper(c)))first[n++]=c;
for(j=0;j<count;j++)
{
if(prodn[j][0]==c)
{
if(prodn[j][2]=='$') first[n++]='$';
else if(islower(prodn[j][2]))first[n++]=prodn[j][2];
else FIRST(prodn[j][2]);
}
explain the code?
ReplyDeletethank u its very easy
ReplyDeletehey can you tell me how to implement follow for any grammer in c...plz help for that...i need for practical exam
ReplyDeleteHW TO TERMINATE DIZ........??its jus asking..press 1 to continue...no termination specified..:(
ReplyDelete@Anonymous
ReplyDeleteenter zero for termination
can u please tell me why you have used charachter 'ch' over here
ReplyDeletecan u plz explain the code
ReplyDeletewhy are we using ' ch ' here ?? when i tried removing it and executing, it is not taking input for element.
ReplyDeleteThis one is good.
ReplyDeleteesrtsertaedrg
ReplyDeleteHello @Rashmi,
ReplyDeleteYou can find the C implementation of FOLLOW of a grammar in this link.. Hope this will be useful for you!
http://vipinnpillai.blogspot.in/2011/11/follow-of-given-grammar-using-c-program.html
Hello @Anonymous Code explanation has been included in modified code.. Please check it out.!!
ReplyDeleteHey @Abhi abhinay , Thanking you for your Nice words..!! :)
ReplyDeletehey @Anonymous, The termination method is made more simpler. You have to press Y or y key to continue.. If you press any key other than them, code will be terminated
ReplyDelete@PRIYANKA KUMARI Hai... if 'ch' is not included the '\n' value which is read by stdin buffer while we pressing enter key will be assigned to next scanf() statement. This anomaly is called "Dangling newline" character.
ReplyDeleteTo avoid this problem, scanf should be written like this.
scanf(" %c",&character)
not like this:
scanf("%c",&character);
The blank space before %c will flush out dangling characters.!!
I hope this explanation could satisfy you.!!
Thank you for the feedback..
PS: dangling character issue has been solved in modified code
may i get first and follow of given grammar in a single program
ReplyDeletehello naga pavan,
ReplyDeleteCHECK THIS LINK to get code to find FOLLOW of a grammar.
Hope it will help you.!
Hi Vipin,
ReplyDeleteDo you have an algorithm if the input productions has left recursions in it.
Thanks,
Chandra
Hello @Anonymous thanks for the algorithm.It really helped me a lot.:)
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThank you very much for programs(FIST AND FOLLOW).
ReplyDeleteYou are welcome, Yogesh Pawar
ReplyDeleteits not working with global inputs like S->ABC|CAab|q|^
ReplyDeleteThanks a lot :)
ReplyDeleteHow Can I set an empty set that is epsilon not in the input? And one more question. why it is not working with global inputs like S->ABC|CAab|q|^
ReplyDeleteNo ε found, no need to check next element
ReplyDeletei want to know why?
Its Showing the first value only for selected var. m trying to show all the first value at a time. but whenever m trying this i cant stop the result
ReplyDelete@Tapasy Rabeya
ReplyDeleteWe can print FIRST of all variables at a time. How you are trying to print?
can you just share the mail snippet?
You are welcome @Unknown
ReplyDeleteThis comment has been removed by the author.
ReplyDeletecan you please provide a code for first and follow together? Thanks in advance :)
ReplyDeletecan u explain it pls..
ReplyDeletevoid FIRST(char* Result,char c)
ReplyDeletewhy is the result is of that type
how to denote null as a production like A-> c | NULL
ReplyDeletehow to denote null as a production like A-> c | NULL
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDelete@Anonymous
ReplyDeletegoogle and check the function of isuper(INT C) function u will get it
To this production Rule it is not working
ReplyDeleteE:E+T
T:T*F
F:(E)
F:id
Is it the code for left recursive grammar ?
ReplyDeletefirst.c: In function ‘first’:
ReplyDeletefirst.c:40: error: invalid initializer
first.c:83: error: expected declaration or statement at end of input
40:Result[0]='\0';
83:Result[k+1]='\0';
}
it shows errors like this,and i didn't understandit.
4
ReplyDeleteS=AaAb
S=BbBa
A=$
B=$
It shows wrong output.
It contain an error .
ReplyDeletefor the productions
A=Ba
B=$
output for A is { $, a}
but it must be { a }