Monday, October 17

Recursive Descent Parser using C program


Updated on 09/02/15

Hello reader,

Here is the updated post considering your valuable suggestions. check it out.


The grammar on which we are going to do recursive descent parsing is:

E -> E+T | T
T -> T*F | F
F -> (E) | id
  RD parser will verify whether the syntax of the input stream is correct by checking each character  from left to right. A basic operation necessary is reading characters from the input stream and matching then with terminals from the grammar that describes the syntax of the input.

 The given grammar can accept all arithmetic equations involving +, * and ().
eg:
 a+(a*a)  a+a*a , (a), a , a+a+a*a+a.... etc are accepted
a++a, a***a, +a, a*, ((a . . . etc are rejected.

Solution:
First we have to avoid left recursion

E -> TE'
E' -> +TE' | ε
T -> FT'
T' -> *FT' | ε
F -> (E) | id

After eliminating Left recursion, we have to simply move from one character to next by checking whether it follow the grammar. In this program, ε is indicated as $.


recursive.c

#include<stdio.h>
#include<string.h>

#include<ctype.h>
 
char input[10];
int i,error;
void E();
void T();
void Eprime();
void Tprime();
void F();
 
          main()
          {

i=0;
error=0;
                printf("Enter an arithmetic expression   :  "); // Eg: a+a*a
                gets(input);
                E();
                if(strlen(input)==i&&error==0)

                        printf("\nAccepted..!!!\n");
                else printf("\nRejected..!!!\n");
                          }
         
         
 
void E()
{
     T();
     Eprime();
}

void Eprime()
{
     if(input[i]=='+')
     {
     i++;
     T();
     Eprime();
     }
     }
void T()
{
     F();
     Tprime();
}
void Tprime()
{
     if(input[i]=='*')
     {
                      i++;
                      F();
                      Tprime();
                      }
                      }
     void F()
     {
          if(
isalnum(input[i]))i++;
          else if(input[i]=='(')
          {
          i++;
          E();
          if(input[i]==')')
          i++;


          else error=1;
            }
        
          else error=1;
          }
           


Output:
 a+(a*a)  a+a*a , (a), a , a+a+a*a+a.... etc are  accepted
++a, a***a, +a, a*, ((a . . . etc are rejected.


Monday, October 10

SEMAPHORES TO IMPLEMENT PRODUCER CONSUMER PROBLEM

#include<sys/sem.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdio.h>
#include<sys/ipc.h>
void up(int);
void down(int);
union value
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminto *_buf;
}
main()
{
int mutex,full,empty,pid,i,key,j,k;
union value arg;
key=ftok("",'a');
mutex=semget(key,1,0660|IPC_CREAT);
arg.val=0;
semctl(full,0,SETVAL,arg);
key=ftok("",'c');
empty=semget(key,1,0660|IPC_CREAT);
arg.val=4;
semctl(empty,0,SETVAL,arg);
pid=fork();
switch(pid)
{
case -1:
printf("Error");
case 0:
sleep(13);
printf("\n");
printf("Consumer consuming items\n");
for(i=0;i<5;i++)
{
down(full);
down(mutex);
for(j=4-i;j>=1;j--)
printf("*");
for(k=0;k<=i;k++)
printf("_");
printf("\n");
fflush(stdout);
up(mutex);
up(empty);
sleep(1);
}
printf("Buffer empty\n");
break;
default:
printf("Producer producing items\n");
for(i=0;i<5;i++)
{
down(full);
down(mutex);
//printf("producer is producing %dth item\n",i);
for(j=4-i;j>=1;j--)
printf("_");
for(k=0;k<=i;k++)
printf("*");
printf("\n");
fflush(stdout);
up(mutex);
up(full);
sleep(1);
}
printf("Buffer full\n");
break;
}}
void down(int id)
{
struct sembuf sb={0,-1,0};
semop(id,&sb,1);
}
void up(int id)
{
struct sembuf sb={0,1,0};
semop(id,&sb,1);
}

Saturday, October 8

Calculator using YACC program



Here is the Yacc program implementing a simple calculator:

%{
#include<stdio.h>
#include<ctype.h>
%}
%token num
%left '+''-'
%left '*''/'
%right '^'
%%
s:e'\n'{printf("%d",$1);}
e:    e '+' e{$$=$1+$3;}
 |e '-' e{$$=$1-$3;}
 |e '*' e{$$=$1*$3;}
 |e '/' e{$$=$1/$3;}
 |e '^' e {
  int i,j=$1;
  for(i=1;i<$3;i++)
  {
  j=j*$1;
  $$=j;
  }
  }
 |'('e')'{$$=$2;}
 |num1;
num1:num1 num{$$ = $1*10 + $2;}
 |num
 ;
%%
yylex()
{
int c;
c=getchar();
if(isdigit(c))
{
yylval=c-'0';
return num;
}
return c;
}

int main()
{
yyparse();
return 1;
}
int yyerror()
{
return 1;
}
int yywrap()
{
return 1;
}




Illustration:

Let the Input be 2+5

Moving from first definition s:e'\n'
--> move to DEF(e)
e: e '+' e is selected. Evaluate first 'e' ie e-->num1
num1 extracts the token (i.e, number here 2 is extracted and stored in $1)
Then '+' is extracted and stored in $2.
Then move to e--> num1, thus 5 is  extracted and stored  in $3.
Now add them and store result in $$.

Go back to S: e'\n' and print result (which is 'e' here..!!)


If you have any doubt regarding this post feel free to comment here.
Thank U..!!

For more Yacc programs click here..!!

YACC program to convert infix

%{#include<stdio.h>
#include<ctype.h>
%}
%token num
%left '+''-'
%left '*' '/'
%%
s:e'\n'{}
e:e'+'e{printf("+");}
|e'-'e{printf("-");}
|e'/'e{printf("/");}
|e'*'e{printf("*");}
|num1{printf("%d",$1);}
num1:num1 num {$$=$1*10+$2;}
|num
;
%%
yylex()
{
 int c;
 c=getchar();
if(isdigit(c))
{ yylval=c-'0';
 return num;
}return c;
}
int main()
{
 yyparse();
return 1;
}
int yyerror()
{
return 1;
}
int yywrap()
{
 return 1;
}

Yacc program to evaluate POSTFIX expression



%{#include<stdio.h>
#include<ctype.h>
%}
%token num
%left '+''-'
%left '*' '/'
%right '^'
%%
s:e'\n'{printf("\n%d",$1);}
e:e e'+'{$$=$1+$2;}
|e e'-'{$$=$1-$2;}
|e e'*'{$$=$1*$2;}
|e e'/'{$$=$1/$2;}
|num
;
%%
yylex()
{
int c;
c=getchar();
if(isdigit(c))
{ yylval=c-'0';
 return num;
}return c;
}
int main()
{
 yyparse();
return 1;
}
int yyerror()
{
return 1;
}
int yywrap()
{
 return 1;
}


Illustraion:

Evaluation of postfix expression can be done very easily.

34+
3--> store value in $1
4--> store value in $2
+--> add $1 and $2 and store result in $$

For more Yacc programs click here..!!

C Program to generate Intermediate code



#include<stdio.h>
#include<ctype.h>
#include<string.h>

main()
{
char a[20];
int i=2,n;
printf("Exp  :");
scanf("%s", a);
if(isdigit(a[0]))
printf("MVI A,%c\n",a[0]);
else printf("MOV A,%c\n",a[0]);
n=strlen(a);
while(i<n)
{
switch(a[i])
{
case '+':printf("ADD B\n");i+=3;break;
case '-':printf("SUB B\n");i+=3;break;



default:if(isdigit(a[i]))
printf("MVI B,%c\n",a[i]);
else
printf("MOV B,%c\n",a[i]);
i--;
}
}
}

LEX program to check the syntax of SCANF statement

%{
#include<stdio.h>
#include<ctype.h>
int i=0,j=0;
%}
a "%d"|"%f"|"%c"|"%s"
id [a-zA-Z][a-zA-Z0-9]*
%%
scanf\((\"({a}*|.*)*\"(,\&{id})*\))\;

{for(i=0;i<yyleng;i++)
{if(yytext[i]=='%')
j++;
if(yytext[i]==',')
j--;
}

if(j==0)
printf("Correct");
else
printf("Incorrect");
}
%%
main()
{ yyin=fopen("sample.c","r");
yylex();
}
int yywrap()
{

return 1;
}        

LEX program to check the syntax of PRINTF statement



%{
#include<stdio.h>
#include<ctype.h>
int i=0,j=0;
%}
a "%d"|"%f"|"%c"|"%s"
id [a-zA-Z][a-zA-Z0-9]*
%%

printf\((\"({a}*|.*)*\"(,{id})*\))\; {for(i=0;i<yyleng;i++) {
if(yytext[i]=='%')
j++;
if(yytext[i]==',')
j--;
}

if(j==0)
printf("Correct..!!");
else
printf("Incorrect..!!");
}
%%

main()
{

yyin=fopen("sample.c","r");
yylex();
}


int yywrap()
{

return 1;
}      




Explanation:

Well, checking syntax of printf statement is very easy.
The syntax should be "printf" followed by "(" and  . It can include a usual string or %d,%f type expression delimited by another ".

The entities specified by %f typed expression should be specified before ")" separated by commas.

The number of arguments is then checked within rule part ( i.e, no. of % is equal to no. of commas).


For more interesting LEX programs , click here...!!


                            

udp communication

Hi Viewer,

Here is a simple java program showing client-server interacion using UDP.
In tgis example, client will send a message and the sever will reply back with same message after converting it to Uppercase..!!



server.java


import java.io.*;
import java.net.*;
class UDPServer
{
public static void main(String args[])throws Exception
{
DatagramSocket serverSocket=new DatagramSocket(1249);
byte[] receiveData=new byte[1024];
byte[] sendData=new byte[1024];
while(true)
{
DatagramPacket receivePacket=new DatagramPacket(receiveData,receiveData.length);
serverSocket.receive(receivePacket);
String sentence=new String(receivePacket.getData());
InetAddress IPAddress=receivePacket.getAddress();
int port=receivePacket.getPort();
String capitalizedSentence=sentence.toUpperCase();
sendData=capitalizedSentence.getBytes();
DatagramPacket sendPacket=new DatagramPacket(sendData,sendData.length,IPAddress,port);
serverSocket.send(sendPacket);
}
}
}










client.java


import java.io.*;
import java.net.*;
class UDPClient
{
public static void main(String args[])throws Exception
{
BufferedReader inFromUser=new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket=new DatagramSocket();
InetAddress IPAddress=InetAddress.getByName("localhost");
byte[] sendData=new byte[1024];
byte[] receiveData=new byte[1024];
System.out.println("Enter msg:");
String sentence=inFromUser.readLine();
sendData=sentence.getBytes();
DatagramPacket sendPacket=new DatagramPacket(sendData,sendData.length,IPAddress,1249);
clientSocket.send(sendPacket);
DatagramPacket receivePacket=new DatagramPacket(receiveData,receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence=new String(receivePacket.getData());
System.out.println("FROM SERVER:"+modifiedSentence);
clientSocket.close();
}
}




If you have any suggestion, or doubt on it, please do comment here.!! Thank you.!! :)

Lex program to check the syntax of FOR loop



%{
#include<stdio.h>
#include<ctype.h>
int c=1;
%}
op "++"|"--"
rop "<"|">"|"<="|">="|"=="|"!="
id [a-zA-Z][a-zA-Z0-9]*
no [0-9]*
pp [\n]
%%
for\(({id}=({no}|{id}))?\;{id}{rop}({id}|{no})\;{id}{op}\){pp}+\{(.*\n)*.*\} {printf("correct");c=0;}
%%
main()
{ yyin=fopen("file11.c","r");
yylex();
if(c==1)
printf("incorrect");
}
int yywrap()
{
return 1;
}

FIRST of a Given Grammar using C program


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:
  1. If X is terminal, FIRST(X) = {X}.
  2. If X → ε is a production, then add ε to FIRST(X).
  3. 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).
  4. 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).




  1. Each Non terminal character is represented by one Uppercase letter.
  2. Each Terminal character is represented by one lowercase letter.
  3. LHS and RHS of each production will be separated by a "=" symbol.
  4. There will be no Blank space within a production string. 
  5. Assumed that Left recursion is avoided in all input productions. 



/* Author : Vipin
* 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