* doc/bison.texinfo: Use $' as shell prompt, not %'.

Use @kbd to denote user input.
(Language and Grammar): ANSIfy the example.
Adjust its layout for info/notinfo.
(Location Tracking Calc): Output error messages to stderr.
Output locations in a more GNUtically correct way.
Fix a couple of Englishos.
Adjust @group/@end group pairs.
This commit is contained in:
Akim Demaille
2001-11-12 09:36:31 +00:00
parent 7da99edea7
commit 9edcd89542
3 changed files with 101 additions and 79 deletions

View File

@@ -1,3 +1,14 @@
2001-11-12 Akim Demaille <akim@epita.fr>
* doc/bison.texinfo: Use `$' as shell prompt, not `%'.
Use @kbd to denote user input.
(Language and Grammar): ANSIfy the example.
Adjust its layout for info/notinfo.
(Location Tracking Calc): Output error messages to stderr.
Output locations in a more GNUtically correct way.
Fix a couple of Englishos.
Adjust @group/@end group pairs.
2001-11-12 Akim Demaille <akim@epita.fr> 2001-11-12 Akim Demaille <akim@epita.fr>
%expext was not functioning at all. %expext was not functioning at all.

View File

@@ -99,8 +99,8 @@ AM_GNU_GETTEXT(, need-ngettext)
# This is necessary so that .o files in LIBOBJS are also built via # This is necessary so that .o files in LIBOBJS are also built via
# the ANSI2KNR-filtering rules. # the ANSI2KNR-filtering rules.
LIBOBJS=`echo $LIBOBJS|sed 's/\.o /\$U.o /g;s/\.o$/\$U.o/'` LIB@&t@OBJS=`echo $LIB@&t@OBJS|sed 's/\.o /\$U.o /g;s/\.o$/\$U.o/'`
AC_SUBST(LIBOBJS) AC_SUBST(LIB@&t@OBJS)
AC_OUTPUT([Makefile AC_OUTPUT([Makefile
config/Makefile config/Makefile

View File

@@ -447,16 +447,26 @@ lexicography, not grammar.)
Here is a simple C function subdivided into tokens: Here is a simple C function subdivided into tokens:
@ifinfo
@example @example
int /* @r{keyword `int'} */ int /* @r{keyword `int'} */
square (x) /* @r{identifier, open-paren,} */ square (int x) /* @r{identifier, open-paren, identifier,}
/* @r{identifier, close-paren} */ @r{identifier, close-paren} */
int x; /* @r{keyword `int', identifier, semicolon} */
@{ /* @r{open-brace} */ @{ /* @r{open-brace} */
return x * x; /* @r{keyword `return', identifier,} */ return x * x; /* @r{keyword `return', identifier, asterisk,
/* @r{asterisk, identifier, semicolon} */ identifier, semicolon} */
@} /* @r{close-brace} */ @} /* @r{close-brace} */
@end example @end example
@end ifinfo
@ifnotinfo
@example
int /* @r{keyword `int'} */
square (int x) /* @r{identifier, open-paren, identifier, identifier, close-paren} */
@{ /* @r{open-brace} */
return x * x; /* @r{keyword `return', identifier, asterisk, identifier, semicolon} */
@} /* @r{close-brace} */
@end example
@end ifnotinfo
The syntactic groupings of C include the expression, the statement, the The syntactic groupings of C include the expression, the statement, the
declaration, and the function definition. These are represented in the declaration, and the function definition. These are represented in the
@@ -1204,19 +1214,19 @@ Here is how to compile and run the parser file:
@example @example
@group @group
# @r{List files in current directory.} # @r{List files in current directory.}
% ls $ @kbd{ls}
rpcalc.tab.c rpcalc.y rpcalc.tab.c rpcalc.y
@end group @end group
@group @group
# @r{Compile the Bison parser.} # @r{Compile the Bison parser.}
# @r{@samp{-lm} tells compiler to search math library for @code{pow}.} # @r{@samp{-lm} tells compiler to search math library for @code{pow}.}
% cc rpcalc.tab.c -lm -o rpcalc $ @kbd{cc rpcalc.tab.c -lm -o rpcalc}
@end group @end group
@group @group
# @r{List files again.} # @r{List files again.}
% ls $ @kbd{ls}
rpcalc rpcalc.tab.c rpcalc.y rpcalc rpcalc.tab.c rpcalc.y
@end group @end group
@end example @end example
@@ -1225,19 +1235,19 @@ The file @file{rpcalc} now contains the executable code. Here is an
example session using @code{rpcalc}. example session using @code{rpcalc}.
@example @example
% rpcalc $ @kbd{rpcalc}
4 9 + @kbd{4 9 +}
13 13
3 7 + 3 4 5 *+- @kbd{3 7 + 3 4 5 *+-}
-13 -13
3 7 + 3 4 5 * + - n @r{Note the unary minus, @samp{n}} @kbd{3 7 + 3 4 5 * + - n} @r{Note the unary minus, @samp{n}}
13 13
5 6 / 4 n + @kbd{5 6 / 4 n +}
-3.166666667 -3.166666667
3 4 ^ @r{Exponentiation} @kbd{3 4 ^} @r{Exponentiation}
81 81
^D @r{End-of-file indicator} @kbd{^D} @r{End-of-file indicator}
% $
@end example @end example
@node Infix Calc @node Infix Calc
@@ -1317,12 +1327,12 @@ Here is a sample run of @file{calc.y}:
@need 500 @need 500
@example @example
% calc $ @kbd{calc}
4 + 4.5 - (34/(8*3+-3)) @kbd{4 + 4.5 - (34/(8*3+-3))}
6.880952381 6.880952381
-56 + 2 @kbd{-56 + 2}
-54 -54
3 ^ 2 @kbd{3 ^ 2}
9 9
@end example @end example
@@ -1374,13 +1384,11 @@ Bison programs.
@cindex @code{ltcalc} @cindex @code{ltcalc}
@cindex calculator, location tracking @cindex calculator, location tracking
This example extends the infix notation calculator with location tracking. This example extends the infix notation calculator with location
This feature will be used to improve error reporting, and provide better tracking. This feature will be used to improve the error messages. For
error messages. the sake of clarity, this example is a simple integer calculator, since
most of the work needed to use locations will be done in the lexical
For the sake of clarity, we will switch for this example to an integer analyser.
calculator, since most of the work needed to use locations will be done
in the lexical analyser.
@menu @menu
* Decls: Ltcalc Decls. Bison and C declarations for ltcalc. * Decls: Ltcalc Decls. Bison and C declarations for ltcalc.
@@ -1391,8 +1399,8 @@ in the lexical analyser.
@node Ltcalc Decls @node Ltcalc Decls
@subsection Declarations for @code{ltcalc} @subsection Declarations for @code{ltcalc}
The C and Bison declarations for the location tracking calculator are the same The C and Bison declarations for the location tracking calculator are
as the declarations for the infix notation calculator. the same as the declarations for the infix notation calculator.
@example @example
/* Location tracking calculator. */ /* Location tracking calculator. */
@@ -1413,22 +1421,24 @@ as the declarations for the infix notation calculator.
%% /* Grammar follows */ %% /* Grammar follows */
@end example @end example
In the code above, there are no declarations specific to locations. Defining @noindent
a data type for storing locations is not needed: we will use the type provided Note there are no declarations specific to locations. Defining a data
by default (@pxref{Location Type, ,Data Types of Locations}), which is a four type for storing locations is not needed: we will use the type provided
member structure with the following integer fields: @code{first_line}, by default (@pxref{Location Type, ,Data Types of Locations}), which is a
@code{first_column}, @code{last_line} and @code{last_column}. four member structure with the following integer fields:
@code{first_line}, @code{first_column}, @code{last_line} and
@code{last_column}.
@node Ltcalc Rules @node Ltcalc Rules
@subsection Grammar Rules for @code{ltcalc} @subsection Grammar Rules for @code{ltcalc}
Whether you choose to handle locations or not has no effect on the syntax of Whether handling locations or not has no effect on the syntax of your
your language. Therefore, grammar rules for this example will be very close to language. Therefore, grammar rules for this example will be very close
those of the previous example: we will only modify them to benefit from the new to those of the previous example: we will only modify them to benefit
informations we will have. from the new information.
Here, we will use locations to report divisions by zero, and locate the wrong Here, we will use locations to report divisions by zero, and locate the
expressions or subexpressions. wrong expressions or subexpressions.
@example @example
@group @group
@@ -1449,17 +1459,17 @@ exp : NUM @{ $$ = $1; @}
| exp '-' exp @{ $$ = $1 - $3; @} | exp '-' exp @{ $$ = $1 - $3; @}
| exp '*' exp @{ $$ = $1 * $3; @} | exp '*' exp @{ $$ = $1 * $3; @}
@end group @end group
| exp '/' exp
@group @group
| exp '/' exp
@{ @{
if ($3) if ($3)
$$ = $1 / $3; $$ = $1 / $3;
else else
@{ @{
$$ = 1; $$ = 1;
printf("Division by zero, l%d,c%d-l%d,c%d", fprintf (stderr, "%d.%d-%d.%d: division by zero",
@@3.first_line, @@3.first_column, @@3.first_line, @@3.first_column,
@@3.last_line, @@3.last_column); @@3.last_line, @@3.last_column);
@} @}
@} @}
@end group @end group
@@ -1474,25 +1484,24 @@ This code shows how to reach locations inside of semantic actions, by
using the pseudo-variables @code{@@@var{n}} for rule components, and the using the pseudo-variables @code{@@@var{n}} for rule components, and the
pseudo-variable @code{@@$} for groupings. pseudo-variable @code{@@$} for groupings.
In this example, we never assign a value to @code{@@$}, because the We don't need to assign a value to @code{@@$}: the output parser does it
output parser can do this automatically. By default, before executing automatically. By default, before executing the C code of each action,
the C code of each action, @code{@@$} is set to range from the beginning @code{@@$} is set to range from the beginning of @code{@@1} to the end
of @code{@@1} to the end of @code{@@@var{n}}, for a rule with @var{n} of @code{@@@var{n}}, for a rule with @var{n} components. This behavior
components. can be redefined (@pxref{Location Default Action, , Default Action for
Locations}), and for very specific rules, @code{@@$} can be computed by
Of course, this behavior can be redefined (@pxref{Location Default hand.
Action, , Default Action for Locations}), and for very specific rules,
@code{@@$} can be computed by hand.
@node Ltcalc Lexer @node Ltcalc Lexer
@subsection The @code{ltcalc} Lexical Analyzer. @subsection The @code{ltcalc} Lexical Analyzer.
Until now, we relied on Bison's defaults to enable location tracking. The next Until now, we relied on Bison's defaults to enable location
step is to rewrite the lexical analyser, and make it able to feed the parser tracking. The next step is to rewrite the lexical analyser, and make it
with locations of tokens, as he already does for semantic values. able to feed the parser with the token locations, as it already does for
semantic values.
To do so, we must take into account every single character of the input text, To this end, we must take into account every single character of the
to avoid the computed locations of being fuzzy or wrong: input text, to avoid the computed locations of being fuzzy or wrong:
@example @example
@group @group
@@ -1542,17 +1551,18 @@ yylex (void)
@} @}
@end example @end example
Basically, the lexical analyzer does the same processing as before: it skips Basically, the lexical analyzer performs the same processing as before:
blanks and tabs, and reads numbers or single-character tokens. In addition it skips blanks and tabs, and reads numbers or single-character tokens.
to this, it updates the @code{yylloc} global variable (of type @code{YYLTYPE}), In addition, it updates @code{yylloc}, the global variable (of type
where the location of tokens is stored. @code{YYLTYPE}) containing the token's location.
Now, each time this function returns a token, the parser has it's number as Now, each time this function returns a token, the parser has its number
well as it's semantic value, and it's position in the text. The last needed as well as its semantic value, and its location in the text. The last
change is to initialize @code{yylloc}, for example in the controlling needed change is to initialize @code{yylloc}, for example in the
function: controlling function:
@example @example
@group
int int
main (void) main (void)
@{ @{
@@ -1560,11 +1570,12 @@ main (void)
yylloc.first_column = yylloc.last_column = 0; yylloc.first_column = yylloc.last_column = 0;
return yyparse (); return yyparse ();
@} @}
@end group
@end example @end example
Remember that computing locations is not a matter of syntax. Every character Remember that computing locations is not a matter of syntax. Every
must be associated to a location update, whether it is in valid input, in character must be associated to a location update, whether it is in
comments, in literal strings, and so on... valid input, in comments, in literal strings, and so on.
@node Multi-function Calc @node Multi-function Calc
@section Multi-Function Calculator: @code{mfcalc} @section Multi-Function Calculator: @code{mfcalc}
@@ -1594,20 +1605,20 @@ to create named variables, store values in them, and use them later.
Here is a sample session with the multi-function calculator: Here is a sample session with the multi-function calculator:
@example @example
% mfcalc $ @kbd{mfcalc}
pi = 3.141592653589 @kbd{pi = 3.141592653589}
3.1415926536 3.1415926536
sin(pi) @kbd{sin(pi)}
0.0000000000 0.0000000000
alpha = beta1 = 2.3 @kbd{alpha = beta1 = 2.3}
2.3000000000 2.3000000000
alpha @kbd{alpha}
2.3000000000 2.3000000000
ln(alpha) @kbd{ln(alpha)}
0.8329091229 0.8329091229
exp(ln(beta1)) @kbd{exp(ln(beta1))}
2.3000000000 2.3000000000
% $
@end example @end example
Note that multiple assignment and nested function calls are permitted. Note that multiple assignment and nested function calls are permitted.