mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-10 12:53:03 +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>
|
||||
|
||||
%expext was not functioning at all.
|
||||
|
||||
202
doc/bison.info
202
doc/bison.info
@@ -31,10 +31,10 @@ instead of in the original English.
|
||||
|
||||
Indirect:
|
||||
bison.info-1: 1313
|
||||
bison.info-2: 50690
|
||||
bison.info-3: 100580
|
||||
bison.info-4: 147602
|
||||
bison.info-5: 197472
|
||||
bison.info-2: 50632
|
||||
bison.info-3: 100395
|
||||
bison.info-4: 147417
|
||||
bison.info-5: 197287
|
||||
|
||||
Tag Table:
|
||||
(Indirect)
|
||||
@@ -44,102 +44,102 @@ Node: Conditions10243
|
||||
Node: Copying11707
|
||||
Node: Concepts30910
|
||||
Node: Language and Grammar31989
|
||||
Node: Grammar in Bison37005
|
||||
Node: Semantic Values38929
|
||||
Node: Semantic Actions41030
|
||||
Node: Locations Overview42219
|
||||
Node: Bison Parser43666
|
||||
Node: Stages45978
|
||||
Node: Grammar Layout47261
|
||||
Node: Examples48518
|
||||
Node: RPN Calc49716
|
||||
Node: Rpcalc Decls50690
|
||||
Node: Rpcalc Rules52277
|
||||
Node: Rpcalc Input54077
|
||||
Node: Rpcalc Line55538
|
||||
Node: Rpcalc Expr56653
|
||||
Node: Rpcalc Lexer58598
|
||||
Node: Rpcalc Main61170
|
||||
Node: Rpcalc Error61568
|
||||
Node: Rpcalc Gen62576
|
||||
Node: Rpcalc Compile63725
|
||||
Node: Infix Calc64600
|
||||
Node: Simple Error Recovery67307
|
||||
Node: Location Tracking Calc69196
|
||||
Node: Ltcalc Decls69926
|
||||
Node: Ltcalc Rules70835
|
||||
Node: Ltcalc Lexer72896
|
||||
Node: Multi-function Calc75234
|
||||
Node: Mfcalc Decl76801
|
||||
Node: Mfcalc Rules78824
|
||||
Node: Mfcalc Symtab80204
|
||||
Node: Exercises86577
|
||||
Node: Grammar File87083
|
||||
Node: Grammar Outline87931
|
||||
Node: C Declarations88665
|
||||
Node: Bison Declarations89245
|
||||
Node: Grammar Rules89657
|
||||
Node: C Code90117
|
||||
Node: Symbols91047
|
||||
Node: Rules96128
|
||||
Node: Recursion97767
|
||||
Node: Semantics99486
|
||||
Node: Value Type100580
|
||||
Node: Multiple Types101252
|
||||
Node: Actions102269
|
||||
Node: Action Types105054
|
||||
Node: Mid-Rule Actions106357
|
||||
Node: Locations111927
|
||||
Node: Location Type112575
|
||||
Node: Actions and Locations113133
|
||||
Node: Location Default Action115289
|
||||
Node: Declarations116752
|
||||
Node: Token Decl118071
|
||||
Node: Precedence Decl120084
|
||||
Node: Union Decl121635
|
||||
Node: Type Decl122479
|
||||
Node: Expect Decl123385
|
||||
Node: Start Decl124953
|
||||
Node: Pure Decl125331
|
||||
Node: Decl Summary127008
|
||||
Node: Multiple Parsers133136
|
||||
Node: Interface134630
|
||||
Node: Parser Function135502
|
||||
Node: Lexical136337
|
||||
Node: Calling Convention137743
|
||||
Node: Token Values140514
|
||||
Node: Token Positions141663
|
||||
Node: Pure Calling142548
|
||||
Node: Error Reporting145480
|
||||
Node: Action Features147602
|
||||
Node: Algorithm150897
|
||||
Node: Look-Ahead153190
|
||||
Node: Shift/Reduce155322
|
||||
Node: Precedence158234
|
||||
Node: Why Precedence158885
|
||||
Node: Using Precedence160750
|
||||
Node: Precedence Examples161718
|
||||
Node: How Precedence162419
|
||||
Node: Contextual Precedence163568
|
||||
Node: Parser States165359
|
||||
Node: Reduce/Reduce166602
|
||||
Node: Mystery Conflicts170163
|
||||
Node: Stack Overflow173549
|
||||
Node: Error Recovery174922
|
||||
Node: Context Dependency180058
|
||||
Node: Semantic Tokens180906
|
||||
Node: Lexical Tie-ins183923
|
||||
Node: Tie-in Recovery185471
|
||||
Node: Debugging187643
|
||||
Node: Invocation190944
|
||||
Node: Bison Options192196
|
||||
Node: Environment Variables195746
|
||||
Node: Option Cross Key196594
|
||||
Node: VMS Invocation197472
|
||||
Node: Table of Symbols198256
|
||||
Node: Glossary206224
|
||||
Node: Copying This Manual212528
|
||||
Node: GNU Free Documentation License212737
|
||||
Node: Index232602
|
||||
Node: Grammar in Bison36947
|
||||
Node: Semantic Values38871
|
||||
Node: Semantic Actions40972
|
||||
Node: Locations Overview42161
|
||||
Node: Bison Parser43608
|
||||
Node: Stages45920
|
||||
Node: Grammar Layout47203
|
||||
Node: Examples48460
|
||||
Node: RPN Calc49658
|
||||
Node: Rpcalc Decls50632
|
||||
Node: Rpcalc Rules52219
|
||||
Node: Rpcalc Input54019
|
||||
Node: Rpcalc Line55480
|
||||
Node: Rpcalc Expr56595
|
||||
Node: Rpcalc Lexer58540
|
||||
Node: Rpcalc Main61112
|
||||
Node: Rpcalc Error61510
|
||||
Node: Rpcalc Gen62518
|
||||
Node: Rpcalc Compile63667
|
||||
Node: Infix Calc64542
|
||||
Node: Simple Error Recovery67249
|
||||
Node: Location Tracking Calc69138
|
||||
Node: Ltcalc Decls69820
|
||||
Node: Ltcalc Rules70713
|
||||
Node: Ltcalc Lexer72723
|
||||
Node: Multi-function Calc75049
|
||||
Node: Mfcalc Decl76616
|
||||
Node: Mfcalc Rules78639
|
||||
Node: Mfcalc Symtab80019
|
||||
Node: Exercises86392
|
||||
Node: Grammar File86898
|
||||
Node: Grammar Outline87746
|
||||
Node: C Declarations88480
|
||||
Node: Bison Declarations89060
|
||||
Node: Grammar Rules89472
|
||||
Node: C Code89932
|
||||
Node: Symbols90862
|
||||
Node: Rules95943
|
||||
Node: Recursion97582
|
||||
Node: Semantics99301
|
||||
Node: Value Type100395
|
||||
Node: Multiple Types101067
|
||||
Node: Actions102084
|
||||
Node: Action Types104869
|
||||
Node: Mid-Rule Actions106172
|
||||
Node: Locations111742
|
||||
Node: Location Type112390
|
||||
Node: Actions and Locations112948
|
||||
Node: Location Default Action115104
|
||||
Node: Declarations116567
|
||||
Node: Token Decl117886
|
||||
Node: Precedence Decl119899
|
||||
Node: Union Decl121450
|
||||
Node: Type Decl122294
|
||||
Node: Expect Decl123200
|
||||
Node: Start Decl124768
|
||||
Node: Pure Decl125146
|
||||
Node: Decl Summary126823
|
||||
Node: Multiple Parsers132951
|
||||
Node: Interface134445
|
||||
Node: Parser Function135317
|
||||
Node: Lexical136152
|
||||
Node: Calling Convention137558
|
||||
Node: Token Values140329
|
||||
Node: Token Positions141478
|
||||
Node: Pure Calling142363
|
||||
Node: Error Reporting145295
|
||||
Node: Action Features147417
|
||||
Node: Algorithm150712
|
||||
Node: Look-Ahead153005
|
||||
Node: Shift/Reduce155137
|
||||
Node: Precedence158049
|
||||
Node: Why Precedence158700
|
||||
Node: Using Precedence160565
|
||||
Node: Precedence Examples161533
|
||||
Node: How Precedence162234
|
||||
Node: Contextual Precedence163383
|
||||
Node: Parser States165174
|
||||
Node: Reduce/Reduce166417
|
||||
Node: Mystery Conflicts169978
|
||||
Node: Stack Overflow173364
|
||||
Node: Error Recovery174737
|
||||
Node: Context Dependency179873
|
||||
Node: Semantic Tokens180721
|
||||
Node: Lexical Tie-ins183738
|
||||
Node: Tie-in Recovery185286
|
||||
Node: Debugging187458
|
||||
Node: Invocation190759
|
||||
Node: Bison Options192011
|
||||
Node: Environment Variables195561
|
||||
Node: Option Cross Key196409
|
||||
Node: VMS Invocation197287
|
||||
Node: Table of Symbols198071
|
||||
Node: Glossary206039
|
||||
Node: Copying This Manual212343
|
||||
Node: GNU Free Documentation License212552
|
||||
Node: Index232417
|
||||
|
||||
End Tag Table
|
||||
|
||||
@@ -709,12 +709,11 @@ matter of lexicography, not grammar.)
|
||||
Here is a simple C function subdivided into tokens:
|
||||
|
||||
int /* keyword `int' */
|
||||
square (x) /* identifier, open-paren, */
|
||||
/* identifier, close-paren */
|
||||
int x; /* keyword `int', identifier, semicolon */
|
||||
square (int x) /* identifier, open-paren, identifier,
|
||||
identifier, close-paren */
|
||||
{ /* open-brace */
|
||||
return x * x; /* keyword `return', identifier, */
|
||||
/* asterisk, identifier, semicolon */
|
||||
return x * x; /* keyword `return', identifier, asterisk,
|
||||
identifier, semicolon */
|
||||
} /* close-brace */
|
||||
|
||||
The syntactic groupings of C include the expression, the statement,
|
||||
|
||||
@@ -385,21 +385,21 @@ Compiling the Parser File
|
||||
Here is how to compile and run the parser file:
|
||||
|
||||
# List files in current directory.
|
||||
% ls
|
||||
$ ls
|
||||
rpcalc.tab.c rpcalc.y
|
||||
|
||||
# Compile the Bison parser.
|
||||
# `-lm' tells compiler to search math library for `pow'.
|
||||
% cc rpcalc.tab.c -lm -o rpcalc
|
||||
$ cc rpcalc.tab.c -lm -o rpcalc
|
||||
|
||||
# List files again.
|
||||
% ls
|
||||
$ ls
|
||||
rpcalc rpcalc.tab.c rpcalc.y
|
||||
|
||||
The file `rpcalc' now contains the executable code. Here is an
|
||||
example session using `rpcalc'.
|
||||
|
||||
% rpcalc
|
||||
$ rpcalc
|
||||
4 9 +
|
||||
13
|
||||
3 7 + 3 4 5 *+-
|
||||
@@ -411,7 +411,7 @@ example session using `rpcalc'.
|
||||
3 4 ^ Exponentiation
|
||||
81
|
||||
^D End-of-file indicator
|
||||
%
|
||||
$
|
||||
|
||||
|
||||
File: bison.info, Node: Infix Calc, Next: Simple Error Recovery, Prev: RPN Calc, Up: Examples
|
||||
@@ -485,7 +485,7 @@ Precedence.
|
||||
|
||||
Here is a sample run of `calc.y':
|
||||
|
||||
% calc
|
||||
$ calc
|
||||
4 + 4.5 - (34/(8*3+-3))
|
||||
6.880952381
|
||||
-56 + 2
|
||||
@@ -539,12 +539,10 @@ Location Tracking Calculator: `ltcalc'
|
||||
======================================
|
||||
|
||||
This example extends the infix notation calculator with location
|
||||
tracking. This feature will be used to improve error reporting, and
|
||||
provide better error messages.
|
||||
|
||||
For the sake of clarity, we will switch for this example to an
|
||||
integer calculator, since most of the work needed to use locations will
|
||||
be done in the lexical analyser.
|
||||
tracking. This feature will be used to improve the error messages. For
|
||||
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
|
||||
analyser.
|
||||
|
||||
* Menu:
|
||||
|
||||
@@ -558,8 +556,8 @@ File: bison.info, Node: Ltcalc Decls, Next: Ltcalc Rules, Up: Location Tracki
|
||||
Declarations for `ltcalc'
|
||||
-------------------------
|
||||
|
||||
The C and Bison declarations for the location tracking calculator
|
||||
are the same as the declarations for the infix notation calculator.
|
||||
The C and Bison declarations for the location tracking calculator are
|
||||
the same as the declarations for the infix notation calculator.
|
||||
|
||||
/* Location tracking calculator. */
|
||||
|
||||
@@ -578,11 +576,11 @@ are the same as the declarations for the infix notation calculator.
|
||||
|
||||
%% /* Grammar follows */
|
||||
|
||||
In the code above, there are no declarations specific to locations.
|
||||
Defining a data type for storing locations is not needed: we will use
|
||||
the type provided by default (*note Data Types of Locations: Location
|
||||
Type.), which is a four member structure with the following integer
|
||||
fields: `first_line', `first_column', `last_line' and `last_column'.
|
||||
Note there are no declarations specific to locations. Defining a data
|
||||
type for storing locations is not needed: we will use the type provided
|
||||
by default (*note Data Types of Locations: Location Type.), which is a
|
||||
four member structure with the following integer fields: `first_line',
|
||||
`first_column', `last_line' and `last_column'.
|
||||
|
||||
|
||||
File: bison.info, Node: Ltcalc Rules, Next: Ltcalc Lexer, Prev: Ltcalc Decls, Up: Location Tracking Calc
|
||||
@@ -590,10 +588,10 @@ File: bison.info, Node: Ltcalc Rules, Next: Ltcalc Lexer, Prev: Ltcalc Decls,
|
||||
Grammar Rules for `ltcalc'
|
||||
--------------------------
|
||||
|
||||
Whether you choose to handle locations or not has no effect on the
|
||||
syntax of your language. Therefore, grammar rules for this example
|
||||
will be very close to those of the previous example: we will only
|
||||
modify them to benefit from the new informations we will have.
|
||||
Whether handling locations or not has no effect on the syntax of your
|
||||
language. Therefore, grammar rules for this example will be very close
|
||||
to those of the previous example: we will only modify them to benefit
|
||||
from the new information.
|
||||
|
||||
Here, we will use locations to report divisions by zero, and locate
|
||||
the wrong expressions or subexpressions.
|
||||
@@ -617,9 +615,9 @@ the wrong expressions or subexpressions.
|
||||
else
|
||||
{
|
||||
$$ = 1;
|
||||
printf("Division by zero, l%d,c%d-l%d,c%d",
|
||||
@3.first_line, @3.first_column,
|
||||
@3.last_line, @3.last_column);
|
||||
fprintf (stderr, "%d.%d-%d.%d: division by zero",
|
||||
@3.first_line, @3.first_column,
|
||||
@3.last_line, @3.last_column);
|
||||
}
|
||||
}
|
||||
| '-' exp %preg NEG { $$ = -$2; }
|
||||
@@ -630,14 +628,12 @@ the wrong expressions or subexpressions.
|
||||
using the pseudo-variables `@N' for rule components, and the
|
||||
pseudo-variable `@$' for groupings.
|
||||
|
||||
In this example, we never assign a value to `@$', because the output
|
||||
parser can do this automatically. By default, before executing the C
|
||||
code of each action, `@$' is set to range from the beginning of `@1' to
|
||||
the end of `@N', for a rule with N components.
|
||||
|
||||
Of course, this behavior can be redefined (*note Default Action for
|
||||
Locations: Location Default Action.), and for very specific rules, `@$'
|
||||
can be computed by hand.
|
||||
We don't need to assign a value to `@$': the output parser does it
|
||||
automatically. By default, before executing the C code of each action,
|
||||
`@$' is set to range from the beginning of `@1' to the end of `@N', for
|
||||
a rule with N components. This behavior can be redefined (*note
|
||||
Default Action for Locations: Location Default Action.), and for very
|
||||
specific rules, `@$' can be computed by hand.
|
||||
|
||||
|
||||
File: bison.info, Node: Ltcalc Lexer, Prev: Ltcalc Rules, Up: Location Tracking Calc
|
||||
@@ -647,10 +643,10 @@ The `ltcalc' Lexical Analyzer.
|
||||
|
||||
Until now, we relied on Bison's defaults to enable location
|
||||
tracking. The next step is to rewrite the lexical analyser, and make it
|
||||
able to feed the parser 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
|
||||
To this end, we must take into account every single character of the
|
||||
input text, to avoid the computed locations of being fuzzy or wrong:
|
||||
|
||||
int
|
||||
@@ -695,14 +691,14 @@ input text, to avoid the computed locations of being fuzzy or wrong:
|
||||
return c;
|
||||
}
|
||||
|
||||
Basically, the lexical analyzer does the same processing as before:
|
||||
it skips blanks and tabs, and reads numbers or single-character tokens.
|
||||
In addition to this, it updates the `yylloc' global variable (of type
|
||||
`YYLTYPE'), where the location of tokens is stored.
|
||||
Basically, the lexical analyzer performs the same processing as
|
||||
before: it skips blanks and tabs, and reads numbers or single-character
|
||||
tokens. In addition, it updates `yylloc', the global variable (of type
|
||||
`YYLTYPE') containing the token's location.
|
||||
|
||||
Now, each time this function returns a token, the parser has it's
|
||||
number as well as it's semantic value, and it's position in the text.
|
||||
The last needed change is to initialize `yylloc', for example in the
|
||||
Now, each time this function returns a token, the parser has its
|
||||
number as well as its semantic value, and its location in the text. The
|
||||
last needed change is to initialize `yylloc', for example in the
|
||||
controlling function:
|
||||
|
||||
int
|
||||
@@ -715,7 +711,7 @@ controlling function:
|
||||
|
||||
Remember that computing locations is not a matter of syntax. Every
|
||||
character must be associated to a location update, whether it is in
|
||||
valid input, in comments, in literal strings, and so on...
|
||||
valid input, in comments, in literal strings, and so on.
|
||||
|
||||
|
||||
File: bison.info, Node: Multi-function Calc, Next: Exercises, Prev: Location Tracking Calc, Up: Examples
|
||||
@@ -741,7 +737,7 @@ At the same time, we will add memory to the calculator, by allowing you
|
||||
to create named variables, store values in them, and use them later.
|
||||
Here is a sample session with the multi-function calculator:
|
||||
|
||||
% mfcalc
|
||||
$ mfcalc
|
||||
pi = 3.141592653589
|
||||
3.1415926536
|
||||
sin(pi)
|
||||
@@ -754,7 +750,7 @@ Here is a sample session with the multi-function calculator:
|
||||
0.8329091229
|
||||
exp(ln(beta1))
|
||||
2.3000000000
|
||||
%
|
||||
$
|
||||
|
||||
Note that multiple assignment and nested function calls are
|
||||
permitted.
|
||||
|
||||
@@ -447,16 +447,26 @@ lexicography, not grammar.)
|
||||
|
||||
Here is a simple C function subdivided into tokens:
|
||||
|
||||
@ifinfo
|
||||
@example
|
||||
int /* @r{keyword `int'} */
|
||||
square (x) /* @r{identifier, open-paren,} */
|
||||
/* @r{identifier, close-paren} */
|
||||
int x; /* @r{keyword `int', identifier, semicolon} */
|
||||
square (int x) /* @r{identifier, open-paren, identifier,}
|
||||
@r{identifier, close-paren} */
|
||||
@{ /* @r{open-brace} */
|
||||
return x * x; /* @r{keyword `return', identifier,} */
|
||||
/* @r{asterisk, identifier, semicolon} */
|
||||
return x * x; /* @r{keyword `return', identifier, asterisk,
|
||||
identifier, semicolon} */
|
||||
@} /* @r{close-brace} */
|
||||
@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
|
||||
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
|
||||
@group
|
||||
# @r{List files in current directory.}
|
||||
% ls
|
||||
$ @kbd{ls}
|
||||
rpcalc.tab.c rpcalc.y
|
||||
@end group
|
||||
|
||||
@group
|
||||
# @r{Compile the Bison parser.}
|
||||
# @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
|
||||
|
||||
@group
|
||||
# @r{List files again.}
|
||||
% ls
|
||||
$ @kbd{ls}
|
||||
rpcalc rpcalc.tab.c rpcalc.y
|
||||
@end group
|
||||
@end example
|
||||
@@ -1225,19 +1235,19 @@ The file @file{rpcalc} now contains the executable code. Here is an
|
||||
example session using @code{rpcalc}.
|
||||
|
||||
@example
|
||||
% rpcalc
|
||||
4 9 +
|
||||
$ @kbd{rpcalc}
|
||||
@kbd{4 9 +}
|
||||
13
|
||||
3 7 + 3 4 5 *+-
|
||||
@kbd{3 7 + 3 4 5 *+-}
|
||||
-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
|
||||
5 6 / 4 n +
|
||||
@kbd{5 6 / 4 n +}
|
||||
-3.166666667
|
||||
3 4 ^ @r{Exponentiation}
|
||||
@kbd{3 4 ^} @r{Exponentiation}
|
||||
81
|
||||
^D @r{End-of-file indicator}
|
||||
%
|
||||
@kbd{^D} @r{End-of-file indicator}
|
||||
$
|
||||
@end example
|
||||
|
||||
@node Infix Calc
|
||||
@@ -1317,12 +1327,12 @@ Here is a sample run of @file{calc.y}:
|
||||
|
||||
@need 500
|
||||
@example
|
||||
% calc
|
||||
4 + 4.5 - (34/(8*3+-3))
|
||||
$ @kbd{calc}
|
||||
@kbd{4 + 4.5 - (34/(8*3+-3))}
|
||||
6.880952381
|
||||
-56 + 2
|
||||
@kbd{-56 + 2}
|
||||
-54
|
||||
3 ^ 2
|
||||
@kbd{3 ^ 2}
|
||||
9
|
||||
@end example
|
||||
|
||||
@@ -1374,13 +1384,11 @@ Bison programs.
|
||||
@cindex @code{ltcalc}
|
||||
@cindex calculator, location tracking
|
||||
|
||||
This example extends the infix notation calculator with location tracking.
|
||||
This feature will be used to improve error reporting, and provide better
|
||||
error messages.
|
||||
|
||||
For the sake of clarity, we will switch for this example to an integer
|
||||
calculator, since most of the work needed to use locations will be done
|
||||
in the lexical analyser.
|
||||
This example extends the infix notation calculator with location
|
||||
tracking. This feature will be used to improve the error messages. For
|
||||
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
|
||||
analyser.
|
||||
|
||||
@menu
|
||||
* Decls: Ltcalc Decls. Bison and C declarations for ltcalc.
|
||||
@@ -1391,8 +1399,8 @@ in the lexical analyser.
|
||||
@node Ltcalc Decls
|
||||
@subsection Declarations for @code{ltcalc}
|
||||
|
||||
The C and Bison declarations for the location tracking calculator are the same
|
||||
as the declarations for the infix notation calculator.
|
||||
The C and Bison declarations for the location tracking calculator are
|
||||
the same as the declarations for the infix notation calculator.
|
||||
|
||||
@example
|
||||
/* Location tracking calculator. */
|
||||
@@ -1413,22 +1421,24 @@ as the declarations for the infix notation calculator.
|
||||
%% /* Grammar follows */
|
||||
@end example
|
||||
|
||||
In the code above, there are no declarations specific to locations. Defining
|
||||
a data type for storing locations is not needed: we will use the type provided
|
||||
by default (@pxref{Location Type, ,Data Types of Locations}), which is a four
|
||||
member structure with the following integer fields: @code{first_line},
|
||||
@code{first_column}, @code{last_line} and @code{last_column}.
|
||||
@noindent
|
||||
Note there are no declarations specific to locations. Defining a data
|
||||
type for storing locations is not needed: we will use the type provided
|
||||
by default (@pxref{Location Type, ,Data Types of Locations}), which is a
|
||||
four member structure with the following integer fields:
|
||||
@code{first_line}, @code{first_column}, @code{last_line} and
|
||||
@code{last_column}.
|
||||
|
||||
@node Ltcalc Rules
|
||||
@subsection Grammar Rules for @code{ltcalc}
|
||||
|
||||
Whether you choose to handle locations or not has no effect on the syntax of
|
||||
your language. Therefore, grammar rules for this example will be very close to
|
||||
those of the previous example: we will only modify them to benefit from the new
|
||||
informations we will have.
|
||||
Whether handling locations or not has no effect on the syntax of your
|
||||
language. Therefore, grammar rules for this example will be very close
|
||||
to those of the previous example: we will only modify them to benefit
|
||||
from the new information.
|
||||
|
||||
Here, we will use locations to report divisions by zero, and locate the wrong
|
||||
expressions or subexpressions.
|
||||
Here, we will use locations to report divisions by zero, and locate the
|
||||
wrong expressions or subexpressions.
|
||||
|
||||
@example
|
||||
@group
|
||||
@@ -1449,17 +1459,17 @@ exp : NUM @{ $$ = $1; @}
|
||||
| exp '-' exp @{ $$ = $1 - $3; @}
|
||||
| exp '*' exp @{ $$ = $1 * $3; @}
|
||||
@end group
|
||||
| exp '/' exp
|
||||
@group
|
||||
| exp '/' exp
|
||||
@{
|
||||
if ($3)
|
||||
$$ = $1 / $3;
|
||||
else
|
||||
@{
|
||||
$$ = 1;
|
||||
printf("Division by zero, l%d,c%d-l%d,c%d",
|
||||
@@3.first_line, @@3.first_column,
|
||||
@@3.last_line, @@3.last_column);
|
||||
fprintf (stderr, "%d.%d-%d.%d: division by zero",
|
||||
@@3.first_line, @@3.first_column,
|
||||
@@3.last_line, @@3.last_column);
|
||||
@}
|
||||
@}
|
||||
@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
|
||||
pseudo-variable @code{@@$} for groupings.
|
||||
|
||||
In this example, we never assign a value to @code{@@$}, because the
|
||||
output parser can do this automatically. By default, before executing
|
||||
the C code of each action, @code{@@$} is set to range from the beginning
|
||||
of @code{@@1} to the end of @code{@@@var{n}}, for a rule with @var{n}
|
||||
components.
|
||||
|
||||
Of course, this behavior can be redefined (@pxref{Location Default
|
||||
Action, , Default Action for Locations}), and for very specific rules,
|
||||
@code{@@$} can be computed by hand.
|
||||
We don't need to assign a value to @code{@@$}: the output parser does it
|
||||
automatically. By default, before executing the C code of each action,
|
||||
@code{@@$} is set to range from the beginning of @code{@@1} to the end
|
||||
of @code{@@@var{n}}, for a rule with @var{n} components. This behavior
|
||||
can be redefined (@pxref{Location Default Action, , Default Action for
|
||||
Locations}), and for very specific rules, @code{@@$} can be computed by
|
||||
hand.
|
||||
|
||||
@node Ltcalc Lexer
|
||||
@subsection The @code{ltcalc} Lexical Analyzer.
|
||||
|
||||
Until now, we relied on Bison's defaults to enable location tracking. The next
|
||||
step is to rewrite the lexical analyser, and make it able to feed the parser
|
||||
with locations of tokens, as he already does for semantic values.
|
||||
Until now, we relied on Bison's defaults to enable location
|
||||
tracking. The next step is to rewrite the lexical analyser, and make it
|
||||
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 avoid the computed locations of being fuzzy or wrong:
|
||||
To this end, we must take into account every single character of the
|
||||
input text, to avoid the computed locations of being fuzzy or wrong:
|
||||
|
||||
@example
|
||||
@group
|
||||
@@ -1542,17 +1551,18 @@ yylex (void)
|
||||
@}
|
||||
@end example
|
||||
|
||||
Basically, the lexical analyzer does the same processing as before: it skips
|
||||
blanks and tabs, and reads numbers or single-character tokens. In addition
|
||||
to this, it updates the @code{yylloc} global variable (of type @code{YYLTYPE}),
|
||||
where the location of tokens is stored.
|
||||
Basically, the lexical analyzer performs the same processing as before:
|
||||
it skips blanks and tabs, and reads numbers or single-character tokens.
|
||||
In addition, it updates @code{yylloc}, the global variable (of type
|
||||
@code{YYLTYPE}) containing the token's location.
|
||||
|
||||
Now, each time this function returns a token, the parser has it's number as
|
||||
well as it's semantic value, and it's position in the text. The last needed
|
||||
change is to initialize @code{yylloc}, for example in the controlling
|
||||
function:
|
||||
Now, each time this function returns a token, the parser has its number
|
||||
as well as its semantic value, and its location in the text. The last
|
||||
needed change is to initialize @code{yylloc}, for example in the
|
||||
controlling function:
|
||||
|
||||
@example
|
||||
@group
|
||||
int
|
||||
main (void)
|
||||
@{
|
||||
@@ -1560,11 +1570,12 @@ main (void)
|
||||
yylloc.first_column = yylloc.last_column = 0;
|
||||
return yyparse ();
|
||||
@}
|
||||
@end group
|
||||
@end example
|
||||
|
||||
Remember that computing locations is not a matter of syntax. Every character
|
||||
must be associated to a location update, whether it is in valid input, in
|
||||
comments, in literal strings, and so on...
|
||||
Remember that computing locations is not a matter of syntax. Every
|
||||
character must be associated to a location update, whether it is in
|
||||
valid input, in comments, in literal strings, and so on.
|
||||
|
||||
@node Multi-function Calc
|
||||
@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:
|
||||
|
||||
@example
|
||||
% mfcalc
|
||||
pi = 3.141592653589
|
||||
$ @kbd{mfcalc}
|
||||
@kbd{pi = 3.141592653589}
|
||||
3.1415926536
|
||||
sin(pi)
|
||||
@kbd{sin(pi)}
|
||||
0.0000000000
|
||||
alpha = beta1 = 2.3
|
||||
@kbd{alpha = beta1 = 2.3}
|
||||
2.3000000000
|
||||
alpha
|
||||
@kbd{alpha}
|
||||
2.3000000000
|
||||
ln(alpha)
|
||||
@kbd{ln(alpha)}
|
||||
0.8329091229
|
||||
exp(ln(beta1))
|
||||
@kbd{exp(ln(beta1))}
|
||||
2.3000000000
|
||||
%
|
||||
$
|
||||
@end example
|
||||
|
||||
Note that multiple assignment and nested function calls are permitted.
|
||||
|
||||
Reference in New Issue
Block a user