Re: yacc: Getting type of token on error.

Vladimir Makarov <vmakarov@cygnus.com>
18 Dec 1998 12:11:37 -0500

          From comp.compilers

Related articles
yacc: Getting type of token on error. madings@execpc.com (1998-12-13)
Re: yacc: Getting type of token on error. qjackson@wave.home.com (Quinn Tyler Jackson) (1998-12-18)
Re: yacc: Getting type of token on error. vmakarov@cygnus.com (Vladimir Makarov) (1998-12-18)
| List of all articles for this month |

From: Vladimir Makarov <vmakarov@cygnus.com>
Newsgroups: comp.compilers
Date: 18 Dec 1998 12:11:37 -0500
Organization: Cygnus Solutions
References: 98-12-028
Keywords: yacc, errors

Steve Mading wrote:


> If I match an error rule, how can I figure out what the type of the
> first token was that matched the error? For example, I'd like to be
> able to make an error message of the form: "Line 999: Expecting a foo,
> bar, or baz, but found a biz instead." However, when I match an
> error, I can't figure out the type of token that was matched.
>
> Also, another place where this is useful is that there is one kind of
> error that isn't really an error if I matched a "foo", but it's an
> error if I matched anything else. So I need to be able to tell the
> type of the token matched and do some manual ugliness to fix things up
> and go on. (I cannot re-write the grammar to handle it the 'right'
> way because doing so requires one lookahead token, which yacc cannot
> do, so I get shift/reduce conflicts all over.)
>


The solution of the problem is simple. It is necessary to place
action after the error. This action will be executed before reading
the next lexema. Of course it is true only if look ahead is not
necessary to solve that the reduce corresponding the action is to be
done or not (see y.output). In the most cases, look ahead is not
needed in this situation. For example, if you have


stmt : ...
          | error ';'


You could write


stmt :
          | error {
                              fprintf (stderr, "parser error on ");
                              print_lexema (yychar);
                          }
              ';'


(yyparse will be called before the action but you could define it with
empty body)


By the way if the lexema has been read because of look head, yychar will
be less 0.


Yacc error recovery is primitive. In the example, the parser will skip
all tokens (e.g. '}' or end) except for ';'. To solve the problem you
could add additional rule


stmt : error '}' {yychar = '}';}


All posix yacc (byacc, bison, msta) will work correctly on this code.


Vladimir Makarov
[Oh right, yychar. It's not documented, but it's certainly there in
the popular versions of yacc. -John]





Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.