3

I have found out that I can use 'error' in the grammar rule as a mechanism for error recovery. So if there was an error, the parser must discard the current line and resume parsing from the next line. An example from bison manual to achieve this could be something like this:

stmts:
      exp
      |stmts exp
      | error '\n'

But I cannot use that; because I had to make flex ignores '\n' in my scannar, so that an expression is not restricted to be expressed in one line. How can I make the parser -when encountering an error- continue parsing to the following line, given that there is no special character (i.e. semicolon) to indicate an end of expression and there is no 'newline' token?

Thanks..

mhmhsh
  • 161
  • 1
  • 13

1 Answers1

7

Since you've eliminated the marker used by the example, you're going to have to pull a stunt to get the equivalent effect.

I think you can use this:

stmts:
      exp
    | stmts exp
    | error { eat_to_newline(); }

Where eat_to_newline() is a function in the scanner (source file) that arranges to discard any saved tokens and read up to the next newline.

extern void eat_to_newline(void);

void eat_to_newline(void)
{
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        ;
}

It probably needs to be a little more complex than that, but not a lot more complex than that. You might need to use yyerrok; (and, as the comment reminds me, yyclearin; too) after calling eat_to_newline().

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks alot! I had to use yyclearin; yyerrok; besides eating - just for the record. – mhmhsh Oct 27 '12 at 05:57
  • Hey Jonathan, the while loop goes infinite when there is only one line in the input file and that line is 'error'. I don't know why the 'while' doesn't stop while it suppose to read EOF!!!! any suggestion? thanks.. – mhmhsh Oct 28 '12 at 20:54
  • I think it'll be related to the 'must shift 3 tokens while in error state' rule. Or you need to allow for 'nothing' as a valid alternative. – Jonathan Leffler Oct 28 '12 at 21:46
  • After big time thinking and wondering, I finally found out the solution was to have: c != '\0' in the while loop instead of: c != EOF. – mhmhsh Nov 04 '12 at 02:18