mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-17 08:13:02 +00:00
* 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:
11
ChangeLog
11
ChangeLog
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user