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