[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Several questions about Bison come up occasionally. Here some of them are addressed.
11.1 Memory Exhausted | Breaking the Stack Limits | |
11.2 How Can I Reset the Parser | yyparse Keeps some State
| |
11.3 Strings are Destroyed | yylval Loses Track of Strings
| |
11.4 Implementing Gotos/Loops | Control Flow in the Calculator | |
11.5 Multiple start-symbols | Factoring closely related grammars | |
11.6 Secure? Conform? | Is Bison POSIX safe? | |
11.7 I can’t build Bison | Troubleshooting | |
11.8 Where can I find help? | Troubleshouting | |
11.9 Bug Reports | Troublereporting | |
11.10 More Languages | Parsers in C++, Java, and so on | |
11.11 Beta Testing | Experimenting development versions | |
11.12 Mailing Lists | Meeting other Bison users |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
My parser returns with error with a ‘memory exhausted’ message. What can I do?
This question is already addressed elsewhere, see Recursive Rules.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 ofyyparse
?
or
My parser includes support for an ‘#include’-like feature, in which case I run
yyparse
fromyyparse
. This fails although I did specify ‘%define api.pure full’.
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) { perror ("fopen"); exit (EXIT_FAILURE); } /* One token only. */ yylex (); if (fclose (yyin) != 0) { perror ("fclose"); exit (EXIT_FAILURE); } 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)’.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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" |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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. */ |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
I can’t build Bison because
make
complains thatmsgfmt
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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 cannot provide a fix.
Send bug reports to bug-bison@gnu.org.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
How do I join the help-bison and bug-bison mailing lists?
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Rick Perry on December 29, 2013 using texi2html 1.82.