Search code examples
c++compiler-constructionc++17bisonflex-lexer

How to do something else in Bison after Flex returns 0?


The Bison yyparse() function stop to read its input (file or stream) when 0 is returned.

I was wondering if there is a way to execute some more commands after it occurs.

I mean, is possible to tread 0 (or some token thrown by its return) in bison file?


Something like:

Flex

<<EOF>>      { return 0; }

Bison

%token start

start   : start '0' {
           // Desired something else
        }

Solution

  • Suppose program is the top-level symbol in a grammar. That is, it is the non-terminal which must be matched by the parser's input.

    Of course, it's possible that program will also be matched several times before the input terminates. For example, the grammar might look something like:

    %start program
    %%
    program: %empty
           | program declaration
    

    In that grammar, there is no way to inject an action which is only executed when the input is fully parsed. I gather that is what you want to do.

    But it's very simple to create a non-terminal whose action will only be executed once, at the end of the parse. All we need to do is insert a new "unit production" at the top of the grammar:

    %start start
    %%
    start  : program { /* Completion action */ }
    program: %empty
           | program declaration
    

    Since start does not appear on the right-hand side of any production in the grammar, it can only be reduced at the end of the parse, when the parser reduced the %start symbol. So even though the production does not explicitly include the end token, we know that that the end token is the lookahead token when the reduction action is executed.

    Unit productions -- productions whose right-hand side contains just one symbol -- are frequently used to trigger actions at strategic points of the parse, and the above is just one example of the technique.