JavaEar 专注于收集分享传播有价值的技术资料

Getting bison parser to divulge debug information

I am having trouble writing a bison parser, and unexpectedly ran into difficulties getting the parser to print debug information. I found two solutions on the web, but neither seems to work.

This advocates to put this code in the main routine:

extern int yydebug;
yydebug = 1;

Unfortunately the C++ compiler detects an undefined reference to `yydebug'.

This suggests putting

        #if YYDEBUG == 1
           extern yydebug;
           yydebug = 1;
        #endif

into the grammar file. It compiles but does not produce output.

What does work is to edit the parser file itself, replacing

int yydebug;

by

int yydebug = 1;

The big disadvantage is that I have to redo this every time I change the grammar file, which during debugging would happen constantly. Is there any other way I can provoke the parser into coughing up its secret machinations?

I am using bison v2.4.1 to generate the parser, with the following command-line options:

bison -ldv -p osil -o $(srcdir)/OSParseosil.tab.cpp OSParseosil.y

Although the output is a C++ file, I am using the standard C skeleton.

1个回答

    最佳答案
  1. With bison and the standard C skeleton, to enable debug support you need to do one of the following:

    • Use the -t (Posix) or --debug (Bison extension) command-line option when you create your grammar. (bison -t ...)

    • Use the -DYYDEBUG=1 command-line option (gcc or clang, at least) when you compile the generated grammar (gcc -DYYDEBUG=1 parser.tab.c ...`).

    • Add the %debug directive to your bison source

    • Put #define YYDEBUG 1 in the prologue in your bison source (the part of the file between %{ and %}.

    I'd use -t in the bison command line. It's simple, and since it is Posix standard it probably will also work on other derived parser generators. However, adding %debug to the bison source is also simple; while it is not as portable, it works in bison 2.4.

    Once you've done that, simply setting yydebug to a non-zero value is sufficient to produce debug output.

    If you want to set yydebug in some translation unit other than the generated parser itself, you need to be aware of the parser prefix you declared in the bison command line. (In the parser itself, yydebug is #defined to the prefixed name.) And you need to declare the debug variable (with the correct prefix) as extern. So in your main, you probably want to use:

    extern int osildebug;
    // ...
    
    int main(int argc, char** argv) {
      osildebug = 1;
      // ...
    }
    

    If you're using bison, your best place to find information is the bison manual; most of the above answer will be found in that page.