Frequently Asked Questions
* Parser Stack Overflow:: Breaking the Stack Limits
-* How Can I Reset @code{yyparse}:: @code{yyparse} Keeps some State
+* How Can I Reset the Parser:: @code{yyparse} Keeps some State
* Strings are Destroyed:: @code{yylval} Loses Track of Strings
* C++ Parsers:: Compiling Parsers with C++ Compilers
* Implementing Loops:: Control Flow in the Calculator
@example
@group
-#define YYLLOC_DEFAULT(Current, Rhs, N) \
- Current.first_line = Rhs[1].first_line; \
- Current.first_column = Rhs[1].first_column; \
- Current.last_line = Rhs[N].last_line; \
- Current.last_column = Rhs[N].last_column;
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ ((Current).first_line = (Rhs)[1].first_line, \
+ (Current).first_column = (Rhs)[1].first_column, \
+ (Current).last_line = (Rhs)[N].last_line, \
+ (Current).last_column = (Rhs)[N].last_column)
@end group
@end example
@example
@group
-#define YYLLOC_DEFAULT(Current, Rhs, N) \
- Current.first_line = YYRHSLOC(Rhs,1).first_line; \
- Current.first_column = YYRHSLOC(Rhs,1).first_column; \
- Current.last_line = YYRHSLOC(Rhs,N).last_line; \
- Current.last_column = YYRHSLOC(Rhs,N).last_column;
+# define YYLLOC_DEFAULT(yyCurrent, yyRhs, YYN) \
+ ((yyCurrent).first_line = YYRHSLOC(yyRhs, 1).first_line, \
+ (yyCurrent).first_column = YYRHSLOC(yyRhs, 1).first_column, \
+ (yyCurrent).last_line = YYRHSLOC(yyRhs, YYN).last_line, \
+ (yyCurrent).last_column = YYRHSLOC(yyRhs, YYN).last_column)
@end group
@end example
@item
For consistency with semantic actions, valid indexes for the location
array range from 1 to @var{n}.
+
+@item
+Your macro should parenthesize its arguments, if need be, since the
+actual arguments may not be surrounded by parentheses. Also, your
+macro should expand to something that can be used as a single
+statement when it is followed by a semicolon.
@end itemize
@node Declarations
@menu
* Parser Stack Overflow:: Breaking the Stack Limits
-* How Can I Reset @code{yyparse}:: @code{yyparse} Keeps some State
+* How Can I Reset the Parser:: @code{yyparse} Keeps some State
* Strings are Destroyed:: @code{yylval} Loses Track of Strings
* C++ Parsers:: Compiling Parsers with C++ Compilers
* Implementing Loops:: Control Flow in the Calculator
This question is already addressed elsewhere, @xref{Recursion,
,Recursive Rules}.
-@node How Can I Reset @code{yyparse}
-@section How Can I Reset @code{yyparse}
+@node How Can I Reset the Parser
+@section How Can I Reset the Parser
-The following phenomenon gives raise to several incarnations,
-resulting in the following typical questions:
+The following phenomenon has several symptoms, resulting in the
+following typical questions:
@display
I invoke @code{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 @code{yyparse}'s error flag?
+too. How can I reset the error flag of @code{yyparse}?
@end display
@noindent
or
@display
-My parser includes support for a @samp{#include} like feature, in
+My parser includes support for an @samp{#include}-like feature, in
which case I run @code{yyparse} from @code{yyparse}. This fails
although I did specify I needed a @code{%pure-parser}.
@end display
-These problems are not related to Bison itself, but with the Lex
-generated scanners. Because these scanners use large buffers for
+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,
@file{first-line.l}:
.*\n ECHO; return 1;
%%
int
-yyparse (const char *file)
+yyparse (char const *file)
{
yyin = fopen (file, "r");
if (!yyin)
exit (2);
/* One token only. */
yylex ();
- if (!fclose (yyin))
+ if (fclose (yyin) != 0)
exit (3);
return 0;
}
int
-main ()
+main (void)
{
yyparse ("input");
yyparse ("input");
@end verbatim
@noindent
-then instead of getting twice the first line, you get:
+then instead of getting the first line twice, you get:
@example
$ @kbd{flex -ofirst-line.c first-line.l}
input:2: World!
@end example
-Therefore, whenever you change @code{yyin}, you must tell the Lex
-generated scanner to discard its current buffer, and to switch to the
-new one. This depends upon your implementation of Lex, see its
-documentation for more. For instance, in the case of Flex, a simple
-call @samp{yyrestart (yyin)} suffices after each change to
-@code{yyin}.
+Therefore, whenever you change @code{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
+@samp{YY_FLUSH_BUFFER} after each change to @code{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 @samp{yy_switch_to_buffer} that manipulate multiple
+input buffers.
@node Strings are Destroyed
@section Strings are Destroyed