mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
doc: mfcalc: demonstrate %printer.
* doc/bison.texinfo (Printer Decl): New. Number mfcalc.y snippets so that they are output in the proper order. (The mfcalc Main): Use yydebug. (Debugging): Simplify the text. (Enabling Traces, Mfcalc Traces, The YYPRINT Macro): New. (Table of Symbols): Document YYPRINT and YYFPRINTF.
This commit is contained in:
@@ -226,6 +226,7 @@ Bison Declarations
|
|||||||
* Type Decl:: Declaring the choice of type for a nonterminal symbol.
|
* Type Decl:: Declaring the choice of type for a nonterminal symbol.
|
||||||
* Initial Action Decl:: Code run before parsing starts.
|
* Initial Action Decl:: Code run before parsing starts.
|
||||||
* Destructor Decl:: Declaring how symbols are freed.
|
* Destructor Decl:: Declaring how symbols are freed.
|
||||||
|
* Printer Decl:: Declaring how symbol values are displayed.
|
||||||
* Expect Decl:: Suppressing warnings about parsing conflicts.
|
* Expect Decl:: Suppressing warnings about parsing conflicts.
|
||||||
* Start Decl:: Specifying the start symbol.
|
* Start Decl:: Specifying the start symbol.
|
||||||
* Pure Decl:: Requesting a reentrant parser.
|
* Pure Decl:: Requesting a reentrant parser.
|
||||||
@@ -299,6 +300,12 @@ Debugging Your Parser
|
|||||||
* Understanding:: Understanding the structure of your parser.
|
* Understanding:: Understanding the structure of your parser.
|
||||||
* Tracing:: Tracing the execution of your parser.
|
* Tracing:: Tracing the execution of your parser.
|
||||||
|
|
||||||
|
Tracing Your Parser
|
||||||
|
|
||||||
|
* Enabling Traces:: Activating run-time trace support
|
||||||
|
* Mfcalc Traces:: Extending @code{mfcalc} to support traces
|
||||||
|
* The YYPRINT Macro:: Obsolete interface for semantic value reports
|
||||||
|
|
||||||
Invoking Bison
|
Invoking Bison
|
||||||
|
|
||||||
* Bison Options:: All the options described in detail,
|
* Bison Options:: All the options described in detail,
|
||||||
@@ -2376,7 +2383,7 @@ Note that multiple assignment and nested function calls are permitted.
|
|||||||
|
|
||||||
Here are the C and Bison declarations for the multi-function calculator.
|
Here are the C and Bison declarations for the multi-function calculator.
|
||||||
|
|
||||||
@comment file: mfcalc.y
|
@comment file: mfcalc.y: 1
|
||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
%@{
|
%@{
|
||||||
@@ -2387,6 +2394,7 @@ Here are the C and Bison declarations for the multi-function calculator.
|
|||||||
void yyerror (char const *);
|
void yyerror (char const *);
|
||||||
%@}
|
%@}
|
||||||
@end group
|
@end group
|
||||||
|
|
||||||
@group
|
@group
|
||||||
%union @{
|
%union @{
|
||||||
double val; /* For returning numbers. */
|
double val; /* For returning numbers. */
|
||||||
@@ -2394,7 +2402,7 @@ Here are the C and Bison declarations for the multi-function calculator.
|
|||||||
@}
|
@}
|
||||||
@end group
|
@end group
|
||||||
%token <val> NUM /* Simple double precision number. */
|
%token <val> NUM /* Simple double precision number. */
|
||||||
%token <tptr> VAR FNCT /* Variable and Function. */
|
%token <tptr> VAR FNCT /* Variable and function. */
|
||||||
%type <val> exp
|
%type <val> exp
|
||||||
|
|
||||||
@group
|
@group
|
||||||
@@ -2404,7 +2412,6 @@ Here are the C and Bison declarations for the multi-function calculator.
|
|||||||
%precedence NEG /* negation--unary minus */
|
%precedence NEG /* negation--unary minus */
|
||||||
%right '^' /* exponentiation */
|
%right '^' /* exponentiation */
|
||||||
@end group
|
@end group
|
||||||
%% /* The grammar follows. */
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The above grammar introduces only two new features of the Bison language.
|
The above grammar introduces only two new features of the Bison language.
|
||||||
@@ -2436,8 +2443,9 @@ Here are the grammar rules for the multi-function calculator.
|
|||||||
Most of them are copied directly from @code{calc}; three rules,
|
Most of them are copied directly from @code{calc}; three rules,
|
||||||
those which mention @code{VAR} or @code{FNCT}, are new.
|
those which mention @code{VAR} or @code{FNCT}, are new.
|
||||||
|
|
||||||
@comment file: mfcalc.y
|
@comment file: mfcalc.y: 3
|
||||||
@example
|
@example
|
||||||
|
%% /* The grammar follows. */
|
||||||
@group
|
@group
|
||||||
input:
|
input:
|
||||||
/* empty */
|
/* empty */
|
||||||
@@ -2521,7 +2529,7 @@ symrec *getsym (char const *);
|
|||||||
The new version of @code{main} will call @code{init_table} to initialize
|
The new version of @code{main} will call @code{init_table} to initialize
|
||||||
the symbol table:
|
the symbol table:
|
||||||
|
|
||||||
@comment file: mfcalc.y
|
@comment file: mfcalc.y: 3
|
||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
struct init
|
struct init
|
||||||
@@ -2575,7 +2583,7 @@ linked to the front of the list, and a pointer to the object is returned.
|
|||||||
The function @code{getsym} is passed the name of the symbol to look up. If
|
The function @code{getsym} is passed the name of the symbol to look up. If
|
||||||
found, a pointer to that symbol is returned; otherwise zero is returned.
|
found, a pointer to that symbol is returned; otherwise zero is returned.
|
||||||
|
|
||||||
@comment file: mfcalc.y
|
@comment file: mfcalc.y: 3
|
||||||
@example
|
@example
|
||||||
#include <stdlib.h> /* malloc. */
|
#include <stdlib.h> /* malloc. */
|
||||||
#include <string.h> /* strlen. */
|
#include <string.h> /* strlen. */
|
||||||
@@ -2627,7 +2635,7 @@ returned to @code{yyparse}.
|
|||||||
No change is needed in the handling of numeric values and arithmetic
|
No change is needed in the handling of numeric values and arithmetic
|
||||||
operators in @code{yylex}.
|
operators in @code{yylex}.
|
||||||
|
|
||||||
@comment file: mfcalc.y
|
@comment file: mfcalc.y: 3
|
||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -2712,9 +2720,10 @@ yylex (void)
|
|||||||
@subsection The @code{mfcalc} Main
|
@subsection The @code{mfcalc} Main
|
||||||
|
|
||||||
The error reporting function is unchanged, and the new version of
|
The error reporting function is unchanged, and the new version of
|
||||||
@code{main} includes a call to @code{init_table}:
|
@code{main} includes a call to @code{init_table} and sets the @code{yydebug}
|
||||||
|
on user demand (@xref{Tracing, , Tracing Your Parser}, for details):
|
||||||
|
|
||||||
@comment file: mfcalc.y
|
@comment file: mfcalc.y: 3
|
||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
/* Called by yyparse on error. */
|
/* Called by yyparse on error. */
|
||||||
@@ -2729,6 +2738,11 @@ yyerror (char const *s)
|
|||||||
int
|
int
|
||||||
main (int argc, char const* argv[])
|
main (int argc, char const* argv[])
|
||||||
@{
|
@{
|
||||||
|
int i;
|
||||||
|
/* Enable parse traces on option -p. */
|
||||||
|
for (i = 1; i < argc; ++i)
|
||||||
|
if (!strcmp(argv[i], "-p"))
|
||||||
|
yydebug = 1;
|
||||||
init_table ();
|
init_table ();
|
||||||
return yyparse ();
|
return yyparse ();
|
||||||
@}
|
@}
|
||||||
@@ -4321,6 +4335,7 @@ and Context-Free Grammars}).
|
|||||||
* Type Decl:: Declaring the choice of type for a nonterminal symbol.
|
* Type Decl:: Declaring the choice of type for a nonterminal symbol.
|
||||||
* Initial Action Decl:: Code run before parsing starts.
|
* Initial Action Decl:: Code run before parsing starts.
|
||||||
* Destructor Decl:: Declaring how symbols are freed.
|
* Destructor Decl:: Declaring how symbols are freed.
|
||||||
|
* Printer Decl:: Declaring how symbol values are displayed.
|
||||||
* Expect Decl:: Suppressing warnings about parsing conflicts.
|
* Expect Decl:: Suppressing warnings about parsing conflicts.
|
||||||
* Start Decl:: Specifying the start symbol.
|
* Start Decl:: Specifying the start symbol.
|
||||||
* Pure Decl:: Requesting a reentrant parser.
|
* Pure Decl:: Requesting a reentrant parser.
|
||||||
@@ -4780,6 +4795,69 @@ error via @code{YYERROR} are not discarded automatically. As a rule
|
|||||||
of thumb, destructors are invoked only when user actions cannot manage
|
of thumb, destructors are invoked only when user actions cannot manage
|
||||||
the memory.
|
the memory.
|
||||||
|
|
||||||
|
@node Printer Decl
|
||||||
|
@subsection Printing Semantic Values
|
||||||
|
@cindex printing semantic values
|
||||||
|
@findex %printer
|
||||||
|
@findex <*>
|
||||||
|
@findex <>
|
||||||
|
When run-time traces are enabled (@pxref{Tracing, ,Tracing Your Parser}),
|
||||||
|
the parser reports its actions, such as reductions. When a symbol involved
|
||||||
|
in an action is reported, only its kind is displayed, as the parser cannot
|
||||||
|
know how semantic values should be formatted.
|
||||||
|
|
||||||
|
The @code{%printer} directive defines code that is called when a symbol is
|
||||||
|
reported. Its syntax is the same as @code{%destructor} (@pxref{Destructor
|
||||||
|
Decl, , Freeing Discarded Symbols}).
|
||||||
|
|
||||||
|
@deffn {Directive} %printer @{ @var{code} @} @var{symbols}
|
||||||
|
@findex %printer
|
||||||
|
@vindex yyoutput
|
||||||
|
@c This is the same text as for %destructor.
|
||||||
|
Invoke the braced @var{code} whenever the parser displays one of the
|
||||||
|
@var{symbols}. Within @var{code}, @code{yyoutput} denotes the output stream
|
||||||
|
(a @code{FILE*} in C, and an @code{std::ostream&} in C++),
|
||||||
|
@code{$$} designates the semantic value associated with the symbol, and
|
||||||
|
@code{@@$} its location. The additional parser parameters are also
|
||||||
|
available (@pxref{Parser Function, , The Parser Function @code{yyparse}}).
|
||||||
|
|
||||||
|
The @var{symbols} are defined as for @code{%destructor} (@pxref{Destructor
|
||||||
|
Decl, , Freeing Discarded Symbols}.): they can be per-type (e.g.,
|
||||||
|
@samp{<ival>}), per-symbol (e.g., @samp{exp}, @samp{NUM}, @samp{"float"}),
|
||||||
|
typed per-default (i.e., @samp{<*>}, or untyped per-default (i.e.,
|
||||||
|
@samp{<>}).
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
For example:
|
||||||
|
|
||||||
|
@example
|
||||||
|
%union @{ char *string; @}
|
||||||
|
%token <string> STRING1
|
||||||
|
%token <string> STRING2
|
||||||
|
%type <string> string1
|
||||||
|
%type <string> string2
|
||||||
|
%union @{ char character; @}
|
||||||
|
%token <character> CHR
|
||||||
|
%type <character> chr
|
||||||
|
%token TAGLESS
|
||||||
|
|
||||||
|
%printer @{ fprintf (yyoutput, "'%c'", $$); @} <character>
|
||||||
|
%printer @{ fprintf (yyoutput, "&%p", $$); @} <*>
|
||||||
|
%printer @{ fprintf (yyoutput, "\"%s\"", $$); @} STRING1 string1
|
||||||
|
%printer @{ fprintf (yyoutput, "<>"); @} <>
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
guarantees that, when the parser print any symbol that has a semantic type
|
||||||
|
tag other than @code{<character>}, it display the address of the semantic
|
||||||
|
value by default. However, when the parser displays a @code{STRING1} or a
|
||||||
|
@code{string1}, it formats it as a string in double quotes. It performs
|
||||||
|
only the second @code{%printer} in this case, so it prints only once.
|
||||||
|
Finally, the parser print @samp{<>} for any symbol, such as @code{TAGLESS},
|
||||||
|
that has no semantic type tag. See also
|
||||||
|
|
||||||
|
|
||||||
@node Expect Decl
|
@node Expect Decl
|
||||||
@subsection Suppressing Conflict Warnings
|
@subsection Suppressing Conflict Warnings
|
||||||
@cindex suppressing conflict warnings
|
@cindex suppressing conflict warnings
|
||||||
@@ -8219,12 +8297,10 @@ clear the flag.
|
|||||||
@node Debugging
|
@node Debugging
|
||||||
@chapter Debugging Your Parser
|
@chapter Debugging Your Parser
|
||||||
|
|
||||||
Developing a parser can be a challenge, especially if you don't
|
Developing a parser can be a challenge, especially if you don't understand
|
||||||
understand the algorithm (@pxref{Algorithm, ,The Bison Parser
|
the algorithm (@pxref{Algorithm, ,The Bison Parser Algorithm}). This
|
||||||
Algorithm}). Even so, sometimes a detailed description of the automaton
|
chapter explains how to generate and read the detailed description of the
|
||||||
can help (@pxref{Understanding, , Understanding Your Parser}), or
|
automaton, and how to enable and understand the parser run-time traces.
|
||||||
tracing the execution of the parser can give some insight on why it
|
|
||||||
behaves improperly (@pxref{Tracing, , Tracing Your Parser}).
|
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Understanding:: Understanding the structure of your parser.
|
* Understanding:: Understanding the structure of your parser.
|
||||||
@@ -8651,9 +8727,17 @@ associativity of @samp{/} is not specified.
|
|||||||
@cindex debugging
|
@cindex debugging
|
||||||
@cindex tracing the parser
|
@cindex tracing the parser
|
||||||
|
|
||||||
If a Bison grammar compiles properly but doesn't do what you want when it
|
When a Bison grammar compiles properly but parses ``incorrectly'', the
|
||||||
runs, the @code{yydebug} parser-trace feature can help you figure out why.
|
@code{yydebug} parser-trace feature helps figuring out why.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Enabling Traces:: Activating run-time trace support
|
||||||
|
* Mfcalc Traces:: Extending @code{mfcalc} to support traces
|
||||||
|
* The YYPRINT Macro:: Obsolete interface for semantic value reports
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Enabling Traces
|
||||||
|
@subsection Enabling Traces
|
||||||
There are several means to enable compilation of trace facilities:
|
There are several means to enable compilation of trace facilities:
|
||||||
|
|
||||||
@table @asis
|
@table @asis
|
||||||
@@ -8687,6 +8771,7 @@ portability matter to you, this is the preferred solution.
|
|||||||
We suggest that you always enable the trace option so that debugging is
|
We suggest that you always enable the trace option so that debugging is
|
||||||
always possible.
|
always possible.
|
||||||
|
|
||||||
|
@findex YYFPRINTF
|
||||||
The trace facility outputs messages with macro calls of the form
|
The trace facility outputs messages with macro calls of the form
|
||||||
@code{YYFPRINTF (stderr, @var{format}, @var{args})} where
|
@code{YYFPRINTF (stderr, @var{format}, @var{args})} where
|
||||||
@var{format} and @var{args} are the usual @code{printf} format and variadic
|
@var{format} and @var{args} are the usual @code{printf} format and variadic
|
||||||
@@ -8716,9 +8801,9 @@ Each time a rule is reduced, which rule it is, and the complete contents
|
|||||||
of the state stack afterward.
|
of the state stack afterward.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
To make sense of this information, it helps to refer to the listing file
|
To make sense of this information, it helps to refer to the automaton
|
||||||
produced by the Bison @samp{-v} option (@pxref{Invocation, ,Invoking
|
description file (@pxref{Understanding, ,Understanding Your Parser}).
|
||||||
Bison}). This file shows the meaning of each state in terms of
|
This file shows the meaning of each state in terms of
|
||||||
positions in various rules, and also what each state will do with each
|
positions in various rules, and also what each state will do with each
|
||||||
possible input token. As you read the successive trace messages, you
|
possible input token. As you read the successive trace messages, you
|
||||||
can see that the parser is functioning according to its specification in
|
can see that the parser is functioning according to its specification in
|
||||||
@@ -8726,19 +8811,197 @@ the listing file. Eventually you will arrive at the place where
|
|||||||
something undesirable happens, and you will see which parts of the
|
something undesirable happens, and you will see which parts of the
|
||||||
grammar are to blame.
|
grammar are to blame.
|
||||||
|
|
||||||
The parser implementation file is a C program and you can use C
|
The parser implementation file is a C/C++/Java program and you can use
|
||||||
debuggers on it, but it's not easy to interpret what it is doing. The
|
debuggers on it, but it's not easy to interpret what it is doing. The
|
||||||
parser function is a finite-state machine interpreter, and aside from
|
parser function is a finite-state machine interpreter, and aside from
|
||||||
the actions it executes the same code over and over. Only the values
|
the actions it executes the same code over and over. Only the values
|
||||||
of variables show where in the grammar it is working.
|
of variables show where in the grammar it is working.
|
||||||
|
|
||||||
|
@node Mfcalc Traces
|
||||||
|
@subsection Enabling Debug Traces for @code{mfcalc}
|
||||||
|
|
||||||
|
The debugging information normally gives the token type of each token read,
|
||||||
|
but not its semantic value. The @code{%printer} directive allows specify
|
||||||
|
how semantic values are reported, see @ref{Printer Decl, , Printing
|
||||||
|
Semantic Values}. For backward compatibility, Yacc like C parsers may also
|
||||||
|
use the @code{YYPRINT} (@pxref{The YYPRINT Macro, , The @code{YYPRINT}
|
||||||
|
Macro}), but its use is discouraged.
|
||||||
|
|
||||||
|
As a demonstration of @code{%printer}, consider the multi-function
|
||||||
|
calculator, @code{mfcalc} (@pxref{Multi-function Calc}). To enable run-time
|
||||||
|
traces, and semantic value reports, insert the following directives in its
|
||||||
|
prologue:
|
||||||
|
|
||||||
|
@comment file: mfcalc.y: 2
|
||||||
|
@example
|
||||||
|
/* Generate the parser description file. */
|
||||||
|
%verbose
|
||||||
|
/* Enable run-time traces (yydebug). */
|
||||||
|
%define parse.trace
|
||||||
|
|
||||||
|
/* Formatting semantic values. */
|
||||||
|
%printer @{ fprintf (yyoutput, "%s", $$->name); @} VAR;
|
||||||
|
%printer @{ fprintf (yyoutput, "%s()", $$->name); @} FNCT;
|
||||||
|
%printer @{ fprintf (yyoutput, "%g", $$); @} <val>;
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The @code{%define} directive instructs Bison to generate run-time trace
|
||||||
|
support. Then, activation of these traces is controlled at run-time by the
|
||||||
|
@code{yydebug} variable, which is disabled by default. Because these traces
|
||||||
|
will refer to the ``states'' of the parser, it is helpful to ask for the
|
||||||
|
creation of a description of that parser; this is the purpose of (admittedly
|
||||||
|
ill-named) @code{%verbose} directive.
|
||||||
|
|
||||||
|
The set of @code{%printer} directives demonstrates how to format the
|
||||||
|
semantic value in the traces. Note that the specification can be done
|
||||||
|
either on the symbol type (e.g., @code{VAR} or @code{FNCT}), or on the type
|
||||||
|
tag: since @code{<val>} is the type for both @code{NUM} and @code{exp}, this
|
||||||
|
printer will be used for them.
|
||||||
|
|
||||||
|
Here is a sample of the information provided by run-time traces. The traces
|
||||||
|
are sent onto standard error.
|
||||||
|
|
||||||
|
@example
|
||||||
|
$ @kbd{echo 'sin(1-1)' | ./mfcalc -p}
|
||||||
|
Starting parse
|
||||||
|
Entering state 0
|
||||||
|
Reducing stack by rule 1 (line 34):
|
||||||
|
-> $$ = nterm input ()
|
||||||
|
Stack now 0
|
||||||
|
Entering state 1
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
This first batch shows a specific feature of this grammar: the first rule
|
||||||
|
(which is in line 34 of @file{mfcalc.y} can be reduced without even having
|
||||||
|
to look for the first token. The resulting left-hand symbol (@code{$$}) is
|
||||||
|
a valueless (@samp{()}) @code{input} non terminal (@code{nterm}).
|
||||||
|
|
||||||
|
Then the parser calls the scanner.
|
||||||
|
@example
|
||||||
|
Reading a token: Next token is token FNCT (sin())
|
||||||
|
Shifting token FNCT (sin())
|
||||||
|
Entering state 6
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
That token (@code{token}) is a function (@code{FNCT}) whose value is
|
||||||
|
@samp{sin} as formatted per our @code{%printer} specification: @samp{sin()}.
|
||||||
|
The parser stores (@code{Shifting}) that token, and others, until it can do
|
||||||
|
something about it.
|
||||||
|
|
||||||
|
@example
|
||||||
|
Reading a token: Next token is token '(' ()
|
||||||
|
Shifting token '(' ()
|
||||||
|
Entering state 14
|
||||||
|
Reading a token: Next token is token NUM (1.000000)
|
||||||
|
Shifting token NUM (1.000000)
|
||||||
|
Entering state 4
|
||||||
|
Reducing stack by rule 6 (line 44):
|
||||||
|
$1 = token NUM (1.000000)
|
||||||
|
-> $$ = nterm exp (1.000000)
|
||||||
|
Stack now 0 1 6 14
|
||||||
|
Entering state 24
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
The previous reduction demonstrates the @code{%printer} directive for
|
||||||
|
@code{<val>}: both the token @code{NUM} and the resulting non-terminal
|
||||||
|
@code{exp} have @samp{1} as value.
|
||||||
|
|
||||||
|
@example
|
||||||
|
Reading a token: Next token is token '-' ()
|
||||||
|
Shifting token '-' ()
|
||||||
|
Entering state 17
|
||||||
|
Reading a token: Next token is token NUM (1.000000)
|
||||||
|
Shifting token NUM (1.000000)
|
||||||
|
Entering state 4
|
||||||
|
Reducing stack by rule 6 (line 44):
|
||||||
|
$1 = token NUM (1.000000)
|
||||||
|
-> $$ = nterm exp (1.000000)
|
||||||
|
Stack now 0 1 6 14 24 17
|
||||||
|
Entering state 26
|
||||||
|
Reading a token: Next token is token ')' ()
|
||||||
|
Reducing stack by rule 11 (line 49):
|
||||||
|
$1 = nterm exp (1.000000)
|
||||||
|
$2 = token '-' ()
|
||||||
|
$3 = nterm exp (1.000000)
|
||||||
|
-> $$ = nterm exp (0.000000)
|
||||||
|
Stack now 0 1 6 14
|
||||||
|
Entering state 24
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
The rule for the subtraction was just reduced. The parser is about to
|
||||||
|
discover the end of the call to @code{sin}.
|
||||||
|
|
||||||
|
@example
|
||||||
|
Next token is token ')' ()
|
||||||
|
Shifting token ')' ()
|
||||||
|
Entering state 31
|
||||||
|
Reducing stack by rule 9 (line 47):
|
||||||
|
$1 = token FNCT (sin())
|
||||||
|
$2 = token '(' ()
|
||||||
|
$3 = nterm exp (0.000000)
|
||||||
|
$4 = token ')' ()
|
||||||
|
-> $$ = nterm exp (0.000000)
|
||||||
|
Stack now 0 1
|
||||||
|
Entering state 11
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
Finally, the end-of-line allow the parser to complete the computation, and
|
||||||
|
display its result.
|
||||||
|
|
||||||
|
@example
|
||||||
|
Reading a token: Next token is token '\n' ()
|
||||||
|
Shifting token '\n' ()
|
||||||
|
Entering state 22
|
||||||
|
Reducing stack by rule 4 (line 40):
|
||||||
|
$1 = nterm exp (0.000000)
|
||||||
|
$2 = token '\n' ()
|
||||||
|
@result{} 0
|
||||||
|
-> $$ = nterm line ()
|
||||||
|
Stack now 0 1
|
||||||
|
Entering state 10
|
||||||
|
Reducing stack by rule 2 (line 35):
|
||||||
|
$1 = nterm input ()
|
||||||
|
$2 = nterm line ()
|
||||||
|
-> $$ = nterm input ()
|
||||||
|
Stack now 0
|
||||||
|
Entering state 1
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The parser has returned into state 1, in which it is waiting for the next
|
||||||
|
expression to evaluate, or for the end-of-file token, which causes the
|
||||||
|
completion of the parsing.
|
||||||
|
|
||||||
|
@example
|
||||||
|
Reading a token: Now at end of input.
|
||||||
|
Shifting token $end ()
|
||||||
|
Entering state 2
|
||||||
|
Stack now 0 1 2
|
||||||
|
Cleanup: popping token $end ()
|
||||||
|
Cleanup: popping nterm input ()
|
||||||
|
@end example
|
||||||
|
|
||||||
|
|
||||||
|
@node The YYPRINT Macro
|
||||||
|
@subsection The @code{YYPRINT} Macro
|
||||||
|
|
||||||
@findex YYPRINT
|
@findex YYPRINT
|
||||||
The debugging information normally gives the token type of each token
|
Before @code{%printer} support, semantic values could be displayed using the
|
||||||
read, but not its semantic value. You can optionally define a macro
|
@code{YYPRINT} macro, which works only for terminal symbols and only with
|
||||||
named @code{YYPRINT} to provide a way to print the value. If you define
|
the @file{yacc.c} skeleton.
|
||||||
@code{YYPRINT}, it should take three arguments. The parser will pass a
|
|
||||||
standard I/O stream, the numeric code for the token type, and the token
|
@deffn {Macro} YYPRINT (@var{stream}, @var{token}, @var{value});
|
||||||
value (from @code{yylval}).
|
@findex YYPRINT
|
||||||
|
If you define @code{YYPRINT}, it should take three arguments. The parser
|
||||||
|
will pass a standard I/O stream, the numeric code for the token type, and
|
||||||
|
the token value (from @code{yylval}).
|
||||||
|
|
||||||
|
For @file{yacc.c} only. Obsoleted by @code{%printer}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
Here is an example of @code{YYPRINT} suitable for the multi-function
|
Here is an example of @code{YYPRINT} suitable for the multi-function
|
||||||
calculator (@pxref{Mfcalc Declarations, ,Declarations for @code{mfcalc}}):
|
calculator (@pxref{Mfcalc Declarations, ,Declarations for @code{mfcalc}}):
|
||||||
@@ -8746,8 +9009,8 @@ calculator (@pxref{Mfcalc Declarations, ,Declarations for @code{mfcalc}}):
|
|||||||
@example
|
@example
|
||||||
%@{
|
%@{
|
||||||
static void print_token_value (FILE *, int, YYSTYPE);
|
static void print_token_value (FILE *, int, YYSTYPE);
|
||||||
#define YYPRINT(file, type, value) \
|
#define YYPRINT(File, Type, Value) \
|
||||||
print_token_value (file, type, value)
|
print_token_value (File, Type, Value)
|
||||||
%@}
|
%@}
|
||||||
|
|
||||||
@dots{} %% @dots{} %% @dots{}
|
@dots{} %% @dots{} %% @dots{}
|
||||||
@@ -10144,7 +10407,7 @@ void
|
|||||||
calcxx_driver::scan_begin ()
|
calcxx_driver::scan_begin ()
|
||||||
@{
|
@{
|
||||||
yy_flex_debug = trace_scanning;
|
yy_flex_debug = trace_scanning;
|
||||||
if (file == "-")
|
if (file.empty () || file == "-")
|
||||||
yyin = stdin;
|
yyin = stdin;
|
||||||
else if (!(yyin = fopen (file.c_str (), "r")))
|
else if (!(yyin = fopen (file.c_str (), "r")))
|
||||||
@{
|
@{
|
||||||
@@ -10179,12 +10442,12 @@ main (int argc, char *argv[])
|
|||||||
@{
|
@{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
calcxx_driver driver;
|
calcxx_driver driver;
|
||||||
for (++argv; argv[0]; ++argv)
|
for (int i = 1; i < argc; ++i)
|
||||||
if (*argv == std::string ("-p"))
|
if (argv[i] == std::string ("-p"))
|
||||||
driver.trace_parsing = true;
|
driver.trace_parsing = true;
|
||||||
else if (*argv == std::string ("-s"))
|
else if (argv[i] == std::string ("-s"))
|
||||||
driver.trace_scanning = true;
|
driver.trace_scanning = true;
|
||||||
else if (!driver.parse (*argv))
|
else if (!driver.parse (argv[i]))
|
||||||
std::cout << driver.result << std::endl;
|
std::cout << driver.result << std::endl;
|
||||||
else
|
else
|
||||||
res = 1;
|
res = 1;
|
||||||
@@ -11616,6 +11879,11 @@ it. Using @samp{%define parse.error verbose} is preferred
|
|||||||
(@pxref{Error Reporting, ,The Error Reporting Function @code{yyerror}}).
|
(@pxref{Error Reporting, ,The Error Reporting Function @code{yyerror}}).
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Macro} YYFPRINTF
|
||||||
|
Macro used to output run-time traces.
|
||||||
|
@xref{Enabling Traces}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@deffn {Macro} YYINITDEPTH
|
@deffn {Macro} YYINITDEPTH
|
||||||
Macro for specifying the initial size of the parser stack.
|
Macro for specifying the initial size of the parser stack.
|
||||||
@xref{Memory Management}.
|
@xref{Memory Management}.
|
||||||
@@ -11678,6 +11946,12 @@ The parser function produced by Bison; call this function to start
|
|||||||
parsing. @xref{Parser Function, ,The Parser Function @code{yyparse}}.
|
parsing. @xref{Parser Function, ,The Parser Function @code{yyparse}}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Macro} YYPRINT
|
||||||
|
Macro used to output token semantic values. For @file{yacc.c} only.
|
||||||
|
Obsoleted by @code{%printer}.
|
||||||
|
@xref{The YYPRINT Macro, , The @code{YYPRINT} Macro}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@deffn {Function} yypstate_delete
|
@deffn {Function} yypstate_delete
|
||||||
The function to delete a parser instance, produced by Bison in push mode;
|
The function to delete a parser instance, produced by Bison in push mode;
|
||||||
call this function to delete the memory associated with a parser.
|
call this function to delete the memory associated with a parser.
|
||||||
|
|||||||
Reference in New Issue
Block a user