help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Push parser documentation/example not accurate


From: Christoph Lechner
Subject: Push parser documentation/example not accurate
Date: Fri, 03 Sep 2010 17:50:52 +0200
User-agent: Thunderbird 2.0.0.24 (X11/20100317)

Hi,

the parser/scanner chain I've implemented works fine in pull mode. To parse multiple input streams at the same time (and in the same process) I had to modify it to a pure push parser+fully reentrant parser/scanner chain.

I'm using bison 2.4.3 and flex 2.5.34.

The question I asked myself was: How does one pass the semantic values the scanner finds to the parser? Passing the token id is no problem, but I had a hard time to get the push parsing to work. To be precise, interfacing scanner and parser was causing the pain.

The problem is that the manual (see http://www.gnu.org/software/bison/manual/html_node/Push-Decl.html#Push-Decl) is somewhat inaccurate in how to pass the semantic values (=the contents of the YYSVAL structure). I understand that the push parser interface is still to be hammered out. But wouldn't it be better to have an example for the push parser that is not "too simple", so with a _real_ third argument and not NULL?

After one afternoon reading source code generated by flex and bison, I found the solution. I'm posting it here, hoping it will be useful.

        yyclipstate *ps;
        yyscan_t scanner;
        YYSTYPE fake_it;
        int status;

        ps = yyclipstate_new();
        yyclilex_init(&scanner);

        /*
* current state of the push parser: The interface between scanner and
         * parsers works, but the semantic values are lost!
         * Send mail to the bison mailing list how to circumvent this.
         */
        do {
                memset(&fake_it, 0, sizeof(YYSTYPE));
                /*
* from the C source code generated by bison 2.4.3, one finds * that the third argument of yyclipush_parse takes a YYSTYPE * . * So it looks like this is the way how to pass the semantic
                 * values from the scanner to the parser.
                 */
status = yyclipush_parse (ps, yyclilex(&fake_it, scanner), &fake_it);
        } while (status == YYPUSH_MORE);

(I'm using the prefix yycli in my bison and flex generated files!)

'fake_it' is just a YYSTYPE allocated in my main function. fake_it is set by the scanner and passed to the parser. 'scanner' has been initialized in the main program as well. So yyclilex stores semantic values (if any) in 'fake_it' and yyclipush_parse reads the variable 'fake_it' to obtain the semantic values.

In the header of my flex input file, I declared
%option noyywrap nounput
%option reentrant
/* tell flex to add yylval argument to yylex() */
%option bison-bridge

In the header of my bison file
/* these directives work fine with GNU bison version 2.4.3 */
%define api.pure
%define api.push_pull "push"

CU
- Christoph



reply via email to

[Prev in Thread] Current Thread [Next in Thread]