Pages

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.


40 comments:

  1. sample output
    a+(a*a)

    Accepted!!

    ReplyDelete
  2. Accepts (((a
    that cannot be generated by the grammar

    ReplyDelete
  3. void F()
    {
    if(input[i]=='a')i++;
    else if(input[i]=='(')
    {
    i++;
    E();
    if(input[i]==')')
    i++;
    else
    error=1;
    }

    else error=1;
    }

    ReplyDelete
  4. it showing that rejected

    ReplyDelete
  5. if i want to enter the string not only 'a' but "a" to "z" and "A" to "Z"

    ReplyDelete
  6. #include
    #include
    char input[10];
    int i=0,error=0;
    void E();
    void T();
    void Eprime();
    void Tprime();
    void F();
    main()
    {
    printf("Enter an arithmetic expression : ");
    gets(input);
    E();
    if(strlen(input)==i&&error==0)printf("\nAccepted..!!!");
    else printf("\nRejected..!!!");
    }



    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(input[i]=='a'&&input[i]=='z'||input[i]=='A'&&input[i]=='Z')i++;
    else if(input[i]=='(')
    {
    i++;
    E();
    if(input[i]==')')
    i++;
    }

    else error=1;
    }
    this program can be used for any string which is consisting of small letters as well as capital letter.....

    ReplyDelete
  7. //this code is for all the characters
    void F()
    {
    if((input[i]>64&&input[i]<91)||input[i]>96&&input[i]<123)i++;
    else if(input[i]=='(')
    {
    i++;
    E();
    if(input[i]==')')
    i++;
    }

    ReplyDelete
  8. will this string be accepted or rejected:a+a*a

    ReplyDelete
  9. @rohit crackulous
    How can the amendment to this code so that if we have introduced outputs the output figures

    ReplyDelete
  10. plz give complete information of output

    ReplyDelete
  11. its not working for any input string.....there something wrong with code .

    ReplyDelete
  12. @Uchiha Hello Uchiha.. Thank you for spotting the bug... It is fixed now..!!

    ReplyDelete
  13. Hello @sachin patil ,
    The Saple input output test cases has been included in updated post.. Check it out

    ReplyDelete
  14. Hello @Anonymous , can you please comment for which input string you have tried

    ReplyDelete
  15. Hello @Anonymous, You can use isalnum(your_character) to check whether it is an alphanumeric. your suggestion has been included in the updated code.

    ReplyDelete
  16. #include
    #include

    void E(),E1(),T(),T1(),F();

    int ip=0;
    static char s[10];

    int main()
    {
    char k;
    int l;
    ip=0;
    printf("Enter the string:\n");
    scanf("%s",s);
    printf("The string is: %s",s);
    E();
    if(s[ip]=='$')
    printf("\nString is accepted.\nThe length of the string is %d\n",strlen(s)-1);
    else
    printf("\nString not accepted.\n");
    return 0;
    }

    void E()
    {
    T();
    E1();
    return;
    }

    void E1()
    {
    if(s[ip]=='+')
    {
    ip++;
    T();
    E1();
    }
    return;
    }

    void T()
    {
    F();
    T1();
    return;
    }

    void T1()
    {
    if(s[ip]=='*')
    {
    ip++;
    F();
    T1();
    }
    return;
    }

    void F()
    {
    if(s[ip]=='(')
    {
    ip++;
    E();
    if(s[ip]==')')
    {
    ip++;
    }
    }
    else if(s[ip]=='i')
    ip++;
    else
    printf("\nId expected ");
    return;
    }

    ReplyDelete
  17. it rejects a+a string!!

    ReplyDelete
  18. Hello sir. This coding style makes me puke. I am currently on my mobile and it is very hard to read (even on my laptop).

    I don't understand how hardcoding every 'rule' solves the problem.

    ReplyDelete
  19. plz upload correct code asap a++ is not working

    ReplyDelete
  20. kay rao code ach chalat nahe shatta

    ReplyDelete
  21. tender nako marat jao re....changla code asal tarach upload karat ja....lavda pana nako karu

    ReplyDelete
  22. @abhishek deshpande
    ho na rao kya chuta code takla .......bhau sapdala tar kar send ....yetha....aai ghal vipin cha blog che

    ReplyDelete
  23. You vipin Mother f****r you have no right to play with student future ...I used your code in practical exam and i failed....

    ReplyDelete
  24. After Running That Code I am getting This warning
    b7.c: In function ‘main’:
    b7.c:16:1: warning: ‘gets’ is deprecated (declared at /usr/include/stdio.h:638) [-Wdeprecated-declarations]
    gets(input);
    ^
    /tmp/ccD9kUtA.o: In function `main':
    b7.c:(.text+0x19): warning: the `gets' function is dangerous and should not be used.

    ReplyDelete
  25. This comment has been removed by the author.

    ReplyDelete
  26. if i input a + a Rejected, i know its because using gets(input); if im using scanf("%c",input); or scanf("%s",input); and i input a a is Accpeted,
    how if i do:
    1. input a + a (Accepted)
    2. input a a (Rejected)

    can you help me?

    ReplyDelete
  27. how to check whitespace of this function:

    void F()
    {
    if(isalnum(input[i]))
    {
    i++;
    if(input[i] == ' ' && isalnum(input[i+1]))
    {
    error = 1;
    }
    }
    else if(input[i]=='(')
    {
    i++;
    E();
    if(input[i]==')')
    {
    i++;
    }
    else
    {
    error = 1;
    }
    }
    else
    {
    error=1;
    }

    ReplyDelete
  28. no it did not accept the string you mentioned it gave me the correct output

    ReplyDelete
  29. this is predictive parser not recursive descent parser

    ReplyDelete
  30. lol there is a way indded ou gotta make a them for yourself in editor

    ReplyDelete
  31. @Bhargav

    Dont know and dont care

    ReplyDelete
  32. This comment has been removed by a blog administrator.

    ReplyDelete