[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Push parser documentation/example not accurate,
Christoph Lechner <=