Search code examples
c++bisonflex-lexeryacclex

Why is yyerror() being called even when string is valid?


This is a yacc program to recognize all strings ending with b preceded by n a’s using the grammar a n b (note: input n value).



%{
#include "y.tab.h"
%}
%%
a {return A;}
b {return B;}
\n {return 0;}
. {return yytext[0];}
%%

The yacc part

YACC PART
%{
#include <stdio.h>
int aCount=0,n;
%}
%token A
%token B
%%
s : X  B {   if (aCount<n || aCount>n) 
        {
    YYFAIL();
}
 }
X : X T | T
T : A { aCount++;} 
  ;
%%

int main()
{   printf("Enter the value of n \n");
scanf("%d",&n);
    printf("Enter the string\n");
    yyparse();
    printf("Valid string\n");
}

int YYFAIL()
{
    printf("Invalid count of 'a'\n");
    exit(0);
}

int yyerror()
{
    printf("Invalid string\n");
    exit(0);
}

output

invalid string 

It displays invalid string even for valid string like aab for n value 2. For every string i enter,yyerror() is called. Please help me resolve this! TIA


Solution

  • scanf("%d",&n);
    

    reads a number from standard input.

    It does not read a number and the following newline. It just reads a number. Whatever follows the number will be returned from the next operation which reads from stdin.

    So when you attempt to parse, the character read by the lexer is the newline character which you typed after the number. That newline character causes the lexer to return 0 to the parser, which the parser interprets as the end of input. But the grammar doesn't allow empty inputs, so the parser reports a syntax error.

    On my system, the parser reports a syntax error before it gives me the opportunity to type any input. The fact that it allows you to type an input line is a bit puzzling to me, but it might have something to do with whatever IDE you are using to run your program.