DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 

(bison.info) Debugging

Info Catalog (bison.info) Context Dependency (bison.info) Top (bison.info) Invocation
 
 Debugging Your Parser
 *********************
 
    If a Bison grammar compiles properly but doesn't do what you want
 when it runs, the `yydebug' parser-trace feature can help you figure
 out why.
 
    To enable compilation of trace facilities, you must define the macro
 `YYDEBUG' when you compile the parser.  You could use `-DYYDEBUG=1' as
 a compiler option or you could put `#define YYDEBUG 1' in the C
 declarations section of the grammar file ( The C Declarations
 Section C Declarations.).  Alternatively, use the `-t' option when you
 run Bison ( Invoking Bison Invocation.).  We always define
 `YYDEBUG' so that debugging is always possible.
 
    The trace facility uses `stderr', so you must add
 `#include <stdio.h>' to the C declarations section unless it is already
 there.
 
    Once you have compiled the program with trace facilities, the way to
 request a trace is to store a nonzero value in the variable `yydebug'.
 You can do this by making the C code do it (in `main', perhaps), or you
 can alter the value with a C debugger.
 
    Each step taken by the parser when `yydebug' is nonzero produces a
 line or two of trace information, written on `stderr'.  The trace
 messages tell you these things:
 
    * Each time the parser calls `yylex', what kind of token was read.
 
    * Each time a token is shifted, the depth and complete contents of
      the state stack ( Parser States.).
 
    * Each time a rule is reduced, which rule it is, and the complete
      contents of the state stack afterward.
 
    To make sense of this information, it helps to refer to the listing
 file produced by the Bison `-v' option ( Invoking Bison
 Invocation.).  This file shows the meaning of each state in terms of
 positions in various rules, and also what each state will do with each
 possible input token.  As you read the successive trace messages, you
 can see that the parser is functioning according to its specification
 in the listing file.  Eventually you will arrive at the place where
 something undesirable happens, and you will see which parts of the
 grammar are to blame.
 
    The parser file is a C program and you can use C debuggers on it,
 but it's not easy to interpret what it is doing.  The parser function
 is a finite-state machine interpreter, and aside from the actions it
 executes the same code over and over.  Only the values of variables
 show where in the grammar it is working.
 
    The debugging information normally gives the token type of each token
 read, but not its semantic value.  You can optionally define a macro
 named `YYPRINT' to provide a way to print the value.  If you define
 `YYPRINT', it should take three arguments.  The parser will pass a
 standard I/O stream, the numeric code for the token type, and the token
 value (from `yylval').
 
    Here is an example of `YYPRINT' suitable for the multi-function
 calculator ( Declarations for `mfcalc' Mfcalc Decl.):
 
      #define YYPRINT(file, type, value)   yyprint (file, type, value)
      
      static void
      yyprint (file, type, value)
           FILE *file;
           int type;
           YYSTYPE value;
      {
        if (type == VAR)
          fprintf (file, " %s", value.tptr->name);
        else if (type == NUM)
          fprintf (file, " %d", value.val);
      }
 
Info Catalog (bison.info) Context Dependency (bison.info) Top (bison.info) Invocation
automatically generated byinfo2html