11. Frequently Asked Questions
Several questions about Bison come up occasionally. Here some of them
are addressed.
11.1 Memory Exhausted
| | My parser returns with error with a `memory exhausted'
message. What can I do?
|
This question is already addressed elsewhere, See section Recursive Rules.
11.2 How Can I Reset the Parser
The following phenomenon has several symptoms, resulting in the
following typical questions:
| | I invoke yyparse several times, and on correct input it works
properly; but when a parse error is found, all the other calls fail
too. How can I reset the error flag of yyparse?
|
or
| | My parser includes support for an `#include'-like feature, in
which case I run yyparse from yyparse. This fails
although I did specify %define api.pure.
|
These problems typically come not from Bison itself, but from
Lex-generated scanners. Because these scanners use large buffers for
speed, they might not notice a change of input file. As a
demonstration, consider the following source file,
`first-line.l':
%{
#include <stdio.h>
#include <stdlib.h>
%}
%%
.*\n ECHO; return 1;
%%
int
yyparse (char const *file)
{
yyin = fopen (file, "r");
if (!yyin)
exit (2);
/* One token only. */
yylex ();
if (fclose (yyin) != 0)
exit (3);
return 0;
}
int
main (void)
{
yyparse ("input");
yyparse ("input");
return 0;
}
If the file `input' contains
input:1: Hello,
input:2: World!
then instead of getting the first line twice, you get:
| | $ flex -ofirst-line.c first-line.l
$ gcc -ofirst-line first-line.c -ll
$ ./first-line
input:1: Hello,
input:2: World!
|
Therefore, whenever you change yyin, you must tell the
Lex-generated scanner to discard its current buffer and switch to the
new one. This depends upon your implementation of Lex; see its
documentation for more. For Flex, it suffices to call
`YY_FLUSH_BUFFER' after each change to yyin. If your
Flex-generated scanner needs to read from several input streams to
handle features like include files, you might consider using Flex
functions like `yy_switch_to_buffer' that manipulate multiple
input buffers.
If your Flex-generated scanner uses start conditions (see (flex)Start conditions section `Start conditions' in The Flex Manual), you might
also want to reset the scanner's state, i.e., go back to the initial
start condition, through a call to `BEGIN (0)'.
11.3 Strings are Destroyed
| | My parser seems to destroy old strings, or maybe it loses track of
them. Instead of reporting `"foo", "bar"', it reports
`"bar", "bar"', or even `"foo\nbar", "bar"'.
|
This error is probably the single most frequent "bug report" sent to
Bison lists, but is only concerned with a misunderstanding of the role
of the scanner. Consider the following Lex code:
%{
#include <stdio.h>
char *yylval = NULL;
%}
%%
.* yylval = yytext; return 1;
\n /* IGNORE */
%%
int
main ()
{
/* Similar to using $1, $2 in a Bison action. */
char *fst = (yylex (), yylval);
char *snd = (yylex (), yylval);
printf ("\"%s\", \"%s\"\n", fst, snd);
return 0;
}
If you compile and run this code, you get:
| | $ flex -osplit-lines.c split-lines.l
$ gcc -osplit-lines split-lines.c -ll
$ printf 'one\ntwo\n' | ./split-lines
"one
two", "two"
|
this is because yytext is a buffer provided for reading
in the action, but if you want to keep it, you have to duplicate it
(e.g., using strdup). Note that the output may depend on how
your implementation of Lex handles yytext. For instance, when
given the Lex compatibility option `-l' (which triggers the
option `%array') Flex generates a different behavior:
| | $ flex -l -osplit-lines.c split-lines.l
$ gcc -osplit-lines split-lines.c -ll
$ printf 'one\ntwo\n' | ./split-lines
"two", "two"
|
11.4 Implementing Gotos/Loops
| | My simple calculator supports variables, assignments, and functions,
but how can I implement gotos, or loops?
|
Although very pedagogical, the examples included in the document blur
the distinction to make between the parser--whose job is to recover
the structure of a text and to transmit it to subsequent modules of
the program--and the processing (such as the execution) of this
structure. This works well with so called straight line programs,
i.e., precisely those that have a straightforward execution model:
execute simple instructions one after the others.
If you want a richer model, you will probably need to use the parser
to construct a tree that does represent the structure it has
recovered; this tree is usually called the abstract syntax tree,
or AST for short. Then, walking through this tree,
traversing it in various ways, will enable treatments such as its
execution or its translation, which will result in an interpreter or a
compiler.
This topic is way beyond the scope of this manual, and the reader is
invited to consult the dedicated literature.
11.5 Multiple start-symbols
| | I have several closely related grammars, and I would like to share their
implementations. In fact, I could use a single grammar but with
multiple entry points.
|
Bison does not support multiple start-symbols, but there is a very
simple means to simulate them. If foo and bar are the two
pseudo start-symbols, then introduce two new tokens, say
START_FOO and START_BAR, and use them as switches from the
real start-symbol:
| | %token START_FOO START_BAR;
%start start;
start: START_FOO foo
| START_BAR bar;
|
These tokens prevents the introduction of new conflicts. As far as the
parser goes, that is all that is needed.
Now the difficult part is ensuring that the scanner will send these
tokens first. If your scanner is hand-written, that should be
straightforward. If your scanner is generated by Lex, them there is
simple means to do it: recall that anything between `%{ ... %}'
after the first %% is copied verbatim in the top of the generated
yylex function. Make sure a variable start_token is
available in the scanner (e.g., a global variable or using
%lex-param etc.), and use the following:
| | /* Prologue. */
%%
%{
if (start_token)
{
int t = start_token;
start_token = 0;
return t;
}
%}
/* The rules. */
|
11.6 Secure? Conform?
| | Is Bison secure? Does it conform to POSIX?
|
If you're looking for a guarantee or certification, we don't provide it.
However, Bison is intended to be a reliable program that conforms to the
POSIX specification for Yacc. If you run into problems,
please send us a bug report.
11.7 I can't build Bison
| | I can't build Bison because make complains that
msgfmt is not found.
What should I do?
|
Like most GNU packages with internationalization support, that feature
is turned on by default. If you have problems building in the `po'
subdirectory, it indicates that your system's internationalization
support is lacking. You can re-configure Bison with
`--disable-nls' to turn off this support, or you can install GNU
gettext from ftp://ftp.gnu.org/gnu/gettext/ and re-configure
Bison. See the file `ABOUT-NLS' for more information.
11.8 Where can I find help?
| | I'm having trouble using Bison. Where can I find help?
|
First, read this fine manual. Beyond that, you can send mail to
help-bison@gnu.org. This mailing list is intended to be
populated with people who are willing to answer questions about using
and installing Bison. Please keep in mind that (most of) the people on
the list have aspects of their lives which are not related to Bison (!),
so you may not receive an answer to your question right away. This can
be frustrating, but please try not to honk them off; remember that any
help they provide is purely voluntary and out of the kindness of their
hearts.
11.9 Bug Reports
| | I found a bug. What should I include in the bug report?
|
Before you send a bug report, make sure you are using the latest
version. Check ftp://ftp.gnu.org/pub/gnu/bison/ or one of its
mirrors. Be sure to include the version number in your bug report. If
the bug is present in the latest version but not in a previous version,
try to determine the most recent version which did not contain the bug.
If the bug is parser-related, you should include the smallest grammar
you can which demonstrates the bug. The grammar file should also be
complete (i.e., I should be able to run it through Bison without having
to edit or add anything). The smaller and simpler the grammar, the
easier it will be to fix the bug.
Include information about your compilation environment, including your
operating system's name and version and your compiler's name and
version. If you have trouble compiling, you should also include a
transcript of the build session, starting with the invocation of
`configure'. Depending on the nature of the bug, you may be asked to
send additional files as well (such as `config.h' or `config.cache').
Patches are most welcome, but not required. That is, do not hesitate to
send a bug report just because you can not provide a fix.
Send bug reports to bug-bison@gnu.org.
11.10 More Languages
| | Will Bison ever have C++ and Java support? How about insert your
favorite language here?
|
C++ and Java support is there now, and is documented. We'd love to add other
languages; contributions are welcome.
11.11 Beta Testing
| | What is involved in being a beta tester?
|
It's not terribly involved. Basically, you would download a test
release, compile it, and use it to build and run a parser or two. After
that, you would submit either a bug report or a message saying that
everything is okay. It is important to report successes as well as
failures because test releases eventually become mainstream releases,
but only if they are adequately tested. If no one tests, development is
essentially halted.
Beta testers are particularly needed for operating systems to which the
developers do not have easy access. They currently have easy access to
recent GNU/Linux and Solaris versions. Reports about other operating
systems are especially welcome.
11.12 Mailing Lists
| | How do I join the help-bison and bug-bison mailing lists?
|
See http://lists.gnu.org/.
This document was generated on February, 15 2009 using texi2html 1.76.