]> git.saurik.com Git - bison.git/commitdiff
* doc/bison.texinfo (Location Tracking Calc): New node.
authorAkim Demaille <akim@epita.fr>
Wed, 29 Aug 2001 12:16:04 +0000 (12:16 +0000)
committerAkim Demaille <akim@epita.fr>
Wed, 29 Aug 2001 12:16:04 +0000 (12:16 +0000)
ChangeLog
doc/bison.info
doc/bison.info-1
doc/bison.info-2
doc/bison.info-3
doc/bison.info-4
doc/bison.info-5
doc/bison.texinfo

index 7a6507ec49f755da2bc159257a937ec7799b3e02..3fe071ee0b1c8f986cf018019d14e612c165de22 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2001-08-29  Robert Anisko  <anisko_r@epita.fr>
+
+       * doc/bison.texinfo (Location Tracking Calc): New node.
+
 2001-08-29  Paul Eggert  <eggert@twinsun.com>
 
        * src/output.c (output): Do not define const, as this now
 2001-08-29  Paul Eggert  <eggert@twinsun.com>
 
        * src/output.c (output): Do not define const, as this now
index 905b3e6c7425e2121c386bea71c20f57041630b0..017768da9586bbee212e9466c2f959ce4b38f12e 100644 (file)
@@ -31,111 +31,115 @@ instead of in the original English.
 \1f
 Indirect:
 bison.info-1: 1313
 \1f
 Indirect:
 bison.info-1: 1313
-bison.info-2: 50345
-bison.info-3: 99970
-bison.info-4: 148168
-bison.info-5: 191130
+bison.info-2: 50688
+bison.info-3: 100578
+bison.info-4: 150128
+bison.info-5: 197515
 \1f
 Tag Table:
 (Indirect)
 Node: Top\7f1313
 \1f
 Tag Table:
 (Indirect)
 Node: Top\7f1313
-Node: Introduction\7f8686
-Node: Conditions\7f9961
-Node: Copying\7f11425
-Node: Concepts\7f30628
-Node: Language and Grammar\7f31707
-Node: Grammar in Bison\7f36723
-Node: Semantic Values\7f38647
-Node: Semantic Actions\7f40748
-Node: Locations Overview\7f41937
-Node: Bison Parser\7f43384
-Node: Stages\7f45696
-Node: Grammar Layout\7f46979
-Node: Examples\7f48236
-Node: RPN Calc\7f49371
-Node: Rpcalc Decls\7f50345
-Node: Rpcalc Rules\7f51932
-Node: Rpcalc Input\7f53732
-Node: Rpcalc Line\7f55193
-Node: Rpcalc Expr\7f56308
-Node: Rpcalc Lexer\7f58253
-Node: Rpcalc Main\7f60825
-Node: Rpcalc Error\7f61223
-Node: Rpcalc Gen\7f62231
-Node: Rpcalc Compile\7f63380
-Node: Infix Calc\7f64255
-Node: Simple Error Recovery\7f66962
-Node: Multi-function Calc\7f68848
-Node: Mfcalc Decl\7f70414
-Node: Mfcalc Rules\7f72437
-Node: Mfcalc Symtab\7f73817
-Node: Exercises\7f80190
-Node: Grammar File\7f80696
-Node: Grammar Outline\7f81544
-Node: C Declarations\7f82278
-Node: Bison Declarations\7f82858
-Node: Grammar Rules\7f83270
-Node: C Code\7f83730
-Node: Symbols\7f84660
-Node: Rules\7f89741
-Node: Recursion\7f91380
-Node: Semantics\7f93099
-Node: Value Type\7f94193
-Node: Multiple Types\7f94865
-Node: Actions\7f95882
-Node: Action Types\7f98667
-Node: Mid-Rule Actions\7f99970
-Node: Locations\7f105540
-Node: Location Type\7f106188
-Node: Actions and Locations\7f106746
-Node: Location Default Action\7f108902
-Node: Declarations\7f110365
-Node: Token Decl\7f111684
-Node: Precedence Decl\7f113697
-Node: Union Decl\7f115248
-Node: Type Decl\7f116092
-Node: Expect Decl\7f116998
-Node: Start Decl\7f118544
-Node: Pure Decl\7f118922
-Node: Decl Summary\7f120599
-Node: Multiple Parsers\7f125982
-Node: Interface\7f127476
-Node: Parser Function\7f128348
-Node: Lexical\7f129183
-Node: Calling Convention\7f130589
-Node: Token Values\7f133360
-Node: Token Positions\7f134509
-Node: Pure Calling\7f135394
-Node: Error Reporting\7f138326
-Node: Action Features\7f140448
-Node: Algorithm\7f143743
-Node: Look-Ahead\7f146036
-Node: Shift/Reduce\7f148168
-Node: Precedence\7f151080
-Node: Why Precedence\7f151731
-Node: Using Precedence\7f153596
-Node: Precedence Examples\7f154564
-Node: How Precedence\7f155265
-Node: Contextual Precedence\7f156414
-Node: Parser States\7f158205
-Node: Reduce/Reduce\7f159448
-Node: Mystery Conflicts\7f163009
-Node: Stack Overflow\7f166395
-Node: Error Recovery\7f167768
-Node: Context Dependency\7f172904
-Node: Semantic Tokens\7f173752
-Node: Lexical Tie-ins\7f176769
-Node: Tie-in Recovery\7f178317
-Node: Debugging\7f180489
-Node: Invocation\7f183790
-Node: Bison Options\7f185042
-Node: Environment Variables\7f188654
-Node: Option Cross Key\7f189502
-Node: VMS Invocation\7f190346
-Node: Table of Symbols\7f191130
-Node: Glossary\7f198769
-Node: Copying This Manual\7f205073
-Node: GNU Free Documentation License\7f205282
-Node: Index\7f225147
+Node: Introduction\7f8966
+Node: Conditions\7f10241
+Node: Copying\7f11705
+Node: Concepts\7f30908
+Node: Language and Grammar\7f31987
+Node: Grammar in Bison\7f37003
+Node: Semantic Values\7f38927
+Node: Semantic Actions\7f41028
+Node: Locations Overview\7f42217
+Node: Bison Parser\7f43664
+Node: Stages\7f45976
+Node: Grammar Layout\7f47259
+Node: Examples\7f48516
+Node: RPN Calc\7f49714
+Node: Rpcalc Decls\7f50688
+Node: Rpcalc Rules\7f52275
+Node: Rpcalc Input\7f54075
+Node: Rpcalc Line\7f55536
+Node: Rpcalc Expr\7f56651
+Node: Rpcalc Lexer\7f58596
+Node: Rpcalc Main\7f61168
+Node: Rpcalc Error\7f61566
+Node: Rpcalc Gen\7f62574
+Node: Rpcalc Compile\7f63723
+Node: Infix Calc\7f64598
+Node: Simple Error Recovery\7f67305
+Node: Location Tracking Calc\7f69194
+Node: Ltcalc Decls\7f69924
+Node: Ltcalc Rules\7f70833
+Node: Ltcalc Lexer\7f72894
+Node: Multi-function Calc\7f75232
+Node: Mfcalc Decl\7f76799
+Node: Mfcalc Rules\7f78822
+Node: Mfcalc Symtab\7f80202
+Node: Exercises\7f86575
+Node: Grammar File\7f87081
+Node: Grammar Outline\7f87929
+Node: C Declarations\7f88663
+Node: Bison Declarations\7f89243
+Node: Grammar Rules\7f89655
+Node: C Code\7f90115
+Node: Symbols\7f91045
+Node: Rules\7f96126
+Node: Recursion\7f97765
+Node: Semantics\7f99484
+Node: Value Type\7f100578
+Node: Multiple Types\7f101250
+Node: Actions\7f102267
+Node: Action Types\7f105052
+Node: Mid-Rule Actions\7f106355
+Node: Locations\7f111925
+Node: Location Type\7f112573
+Node: Actions and Locations\7f113131
+Node: Location Default Action\7f115287
+Node: Declarations\7f116750
+Node: Token Decl\7f118069
+Node: Precedence Decl\7f120082
+Node: Union Decl\7f121633
+Node: Type Decl\7f122477
+Node: Expect Decl\7f123383
+Node: Start Decl\7f124929
+Node: Pure Decl\7f125307
+Node: Decl Summary\7f126984
+Node: Multiple Parsers\7f132367
+Node: Interface\7f133861
+Node: Parser Function\7f134733
+Node: Lexical\7f135568
+Node: Calling Convention\7f136974
+Node: Token Values\7f139745
+Node: Token Positions\7f140894
+Node: Pure Calling\7f141779
+Node: Error Reporting\7f144711
+Node: Action Features\7f146833
+Node: Algorithm\7f150128
+Node: Look-Ahead\7f152421
+Node: Shift/Reduce\7f154553
+Node: Precedence\7f157465
+Node: Why Precedence\7f158116
+Node: Using Precedence\7f159981
+Node: Precedence Examples\7f160949
+Node: How Precedence\7f161650
+Node: Contextual Precedence\7f162799
+Node: Parser States\7f164590
+Node: Reduce/Reduce\7f165833
+Node: Mystery Conflicts\7f169394
+Node: Stack Overflow\7f172780
+Node: Error Recovery\7f174153
+Node: Context Dependency\7f179289
+Node: Semantic Tokens\7f180137
+Node: Lexical Tie-ins\7f183154
+Node: Tie-in Recovery\7f184702
+Node: Debugging\7f186874
+Node: Invocation\7f190175
+Node: Bison Options\7f191427
+Node: Environment Variables\7f195039
+Node: Option Cross Key\7f195887
+Node: VMS Invocation\7f196731
+Node: Table of Symbols\7f197515
+Node: Glossary\7f205154
+Node: Copying This Manual\7f211458
+Node: GNU Free Documentation License\7f211667
+Node: Index\7f231532
 \1f
 End Tag Table
 \1f
 End Tag Table
index 3961f74244831b4423f53b38dfb452ad53dbd5b0..4867aa6fd93e13564de43328e4a1252d7b8f6e51 100644 (file)
@@ -83,6 +83,7 @@ Examples
 * Infix Calc::        Infix (algebraic) notation calculator.
                         Operator precedence is introduced.
 * Simple Error Recovery::  Continuing after syntax errors.
 * Infix Calc::        Infix (algebraic) notation calculator.
                         Operator precedence is introduced.
 * Simple Error Recovery::  Continuing after syntax errors.
+* Location Tracking Calc:: Demonstrating the use of @N and @$.
 * Multi-function Calc::    Calculator with memory and trig functions.
                         It uses multiple data-types for semantic values.
 * Exercises::         Ideas for improving the multi-function calculator.
 * Multi-function Calc::    Calculator with memory and trig functions.
                         It uses multiple data-types for semantic values.
 * Exercises::         Ideas for improving the multi-function calculator.
@@ -103,6 +104,12 @@ Grammar Rules for `rpcalc'
 * Rpcalc Line::
 * Rpcalc Expr::
 
 * Rpcalc Line::
 * Rpcalc Expr::
 
+Location Tracking Calculator: `ltcalc'
+
+* Decls: Ltcalc Decls.  Bison and C declarations for ltcalc.
+* Rules: Ltcalc Rules.  Grammar rules for ltcalc, with explanations.
+* Lexer: Ltcalc Lexer.  The lexical analyzer.
+
 Multi-Function Calculator: `mfcalc'
 
 * Decl: Mfcalc Decl.      Bison declarations for multi-function calculator.
 Multi-Function Calculator: `mfcalc'
 
 * Decl: Mfcalc Decl.      Bison declarations for multi-function calculator.
@@ -1036,6 +1043,7 @@ the Info file and into a source file to try them.
 * Infix Calc::        Infix (algebraic) notation calculator.
                         Operator precedence is introduced.
 * Simple Error Recovery::  Continuing after syntax errors.
 * Infix Calc::        Infix (algebraic) notation calculator.
                         Operator precedence is introduced.
 * Simple Error Recovery::  Continuing after syntax errors.
+* Location Tracking Calc:: Demonstrating the use of @N and @$.
 * Multi-function Calc::  Calculator with memory and trig functions.
                            It uses multiple data-types for semantic values.
 * Exercises::         Ideas for improving the multi-function calculator.
 * Multi-function Calc::  Calculator with memory and trig functions.
                            It uses multiple data-types for semantic values.
 * Exercises::         Ideas for improving the multi-function calculator.
index 21b3e2df903a727fd379be0364b359a25050ed02..db638a464becdad39cc368cfef1669812085b046 100644 (file)
@@ -494,7 +494,7 @@ Precedence.
      9
 
 \1f
      9
 
 \1f
-File: bison.info,  Node: Simple Error Recovery,  Next: Multi-function Calc,  Prev: Infix Calc,  Up: Examples
+File: bison.info,  Node: Simple Error Recovery,  Next: Location Tracking Calc,  Prev: Infix Calc,  Up: Examples
 
 Simple Error Recovery
 =====================
 
 Simple Error Recovery
 =====================
@@ -533,7 +533,192 @@ the current line of input.  We won't discuss this issue further because
 it is not specific to Bison programs.
 
 \1f
 it is not specific to Bison programs.
 
 \1f
-File: bison.info,  Node: Multi-function Calc,  Next: Exercises,  Prev: Simple Error Recovery,  Up: Examples
+File: bison.info,  Node: Location Tracking Calc,  Next: Multi-function Calc,  Prev: Simple Error Recovery,  Up: Examples
+
+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.
+
+* Menu:
+
+* Decls: Ltcalc Decls.  Bison and C declarations for ltcalc.
+* Rules: Ltcalc Rules.  Grammar rules for ltcalc, with explanations.
+* Lexer: Ltcalc Lexer.  The lexical analyzer.
+
+\1f
+File: bison.info,  Node: Ltcalc Decls,  Next: Ltcalc Rules,  Up: Location Tracking Calc
+
+Declarations for `ltcalc'
+-------------------------
+
+   The C and Bison declarations for the location tracking calculator
+are the same as the declarations for the infix notation calculator.
+
+     /* Location tracking calculator.  */
+     
+     %{
+     #define YYSTYPE int
+     #include <math.h>
+     %}
+     
+     /* Bison declarations.  */
+     %token NUM
+     
+     %left '-' '+'
+     %left '*' '/'
+     %left NEG
+     %right '^'
+     
+     %% /* 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'.
+
+\1f
+File: bison.info,  Node: Ltcalc Rules,  Next: Ltcalc Lexer,  Prev: Ltcalc Decls,  Up: Location Tracking Calc
+
+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.
+
+   Here, we will use locations to report divisions by zero, and locate
+the wrong expressions or subexpressions.
+
+     input   : /* empty */
+             | input line
+     ;
+     
+     line    : '\n'
+             | exp '\n' { printf ("%d\n", $1); }
+     ;
+     
+     exp     : NUM           { $$ = $1; }
+             | exp '+' exp   { $$ = $1 + $3; }
+             | exp '-' exp   { $$ = $1 - $3; }
+             | exp '*' exp   { $$ = $1 * $3; }
+             | 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);
+                     }
+                 }
+             | '-' exp %preg NEG     { $$ = -$2; }
+             | exp '^' exp           { $$ = pow ($1, $3); }
+             | '(' exp ')'           { $$ = $2; }
+
+   This code shows how to reach locations inside of semantic actions, by
+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.
+
+\1f
+File: bison.info,  Node: Ltcalc Lexer,  Prev: Ltcalc Rules,  Up: Location Tracking Calc
+
+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.
+
+   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:
+
+     int
+     yylex (void)
+     {
+       int c;
+     
+       /* skip white space */
+       while ((c = getchar ()) == ' ' || c == '\t')
+         ++yylloc.last_column;
+     
+       /* step */
+       yylloc.first_line = yylloc.last_line;
+       yylloc.first_column = yylloc.last_column;
+     
+       /* process numbers */
+       if (isdigit (c))
+         {
+           yylval = c - '0';
+           ++yylloc.last_column;
+           while (isdigit (c = getchar ()))
+             {
+               ++yylloc.last_column;
+               yylval = yylval * 10 + c - '0';
+             }
+           ungetc (c, stdin);
+           return NUM;
+         }
+     
+       /* return end-of-file */
+       if (c == EOF)
+         return 0;
+     
+       /* return single chars and update location */
+       if (c == '\n')
+         {
+           ++yylloc.last_line;
+           yylloc.last_column = 0;
+         }
+       else
+         ++yylloc.last_column;
+       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.
+
+   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
+controlling function:
+
+     int
+     main (void)
+     {
+       yylloc.first_line = yylloc.last_line = 1;
+       yylloc.first_column = yylloc.last_column = 0;
+       return yyparse ();
+     }
+
+   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...
+
+\1f
+File: bison.info,  Node: Multi-function Calc,  Next: Exercises,  Prev: Location Tracking Calc,  Up: Examples
 
 Multi-Function Calculator: `mfcalc'
 ===================================
 
 Multi-Function Calculator: `mfcalc'
 ===================================
@@ -1240,147 +1425,3 @@ associated with X and Y.
                       This says when, why and how to use the exceptional
                         action in the middle of a rule.
 
                       This says when, why and how to use the exceptional
                         action in the middle of a rule.
 
-\1f
-File: bison.info,  Node: Value Type,  Next: Multiple Types,  Up: Semantics
-
-Data Types of Semantic Values
------------------------------
-
-   In a simple program it may be sufficient to use the same data type
-for the semantic values of all language constructs.  This was true in
-the RPN and infix calculator examples (*note Reverse Polish Notation
-Calculator: RPN Calc.).
-
-   Bison's default is to use type `int' for all semantic values.  To
-specify some other type, define `YYSTYPE' as a macro, like this:
-
-     #define YYSTYPE double
-
-This macro definition must go in the C declarations section of the
-grammar file (*note Outline of a Bison Grammar: Grammar Outline.).
-
-\1f
-File: bison.info,  Node: Multiple Types,  Next: Actions,  Prev: Value Type,  Up: Semantics
-
-More Than One Value Type
-------------------------
-
-   In most programs, you will need different data types for different
-kinds of tokens and groupings.  For example, a numeric constant may
-need type `int' or `long', while a string constant needs type `char *',
-and an identifier might need a pointer to an entry in the symbol table.
-
-   To use more than one data type for semantic values in one parser,
-Bison requires you to do two things:
-
-   * Specify the entire collection of possible data types, with the
-     `%union' Bison declaration (*note The Collection of Value Types:
-     Union Decl.).
-
-   * Choose one of those types for each symbol (terminal or
-     nonterminal) for which semantic values are used.  This is done for
-     tokens with the `%token' Bison declaration (*note Token Type
-     Names: Token Decl.)  and for groupings with the `%type' Bison
-     declaration (*note Nonterminal Symbols: Type Decl.).
-
-\1f
-File: bison.info,  Node: Actions,  Next: Action Types,  Prev: Multiple Types,  Up: Semantics
-
-Actions
--------
-
-   An action accompanies a syntactic rule and contains C code to be
-executed each time an instance of that rule is recognized.  The task of
-most actions is to compute a semantic value for the grouping built by
-the rule from the semantic values associated with tokens or smaller
-groupings.
-
-   An action consists of C statements surrounded by braces, much like a
-compound statement in C.  It can be placed at any position in the rule;
-it is executed at that position.  Most rules have just one action at
-the end of the rule, following all the components.  Actions in the
-middle of a rule are tricky and used only for special purposes (*note
-Actions in Mid-Rule: Mid-Rule Actions.).
-
-   The C code in an action can refer to the semantic values of the
-components matched by the rule with the construct `$N', which stands for
-the value of the Nth component.  The semantic value for the grouping
-being constructed is `$$'.  (Bison translates both of these constructs
-into array element references when it copies the actions into the parser
-file.)
-
-   Here is a typical example:
-
-     exp:    ...
-             | exp '+' exp
-                 { $$ = $1 + $3; }
-
-This rule constructs an `exp' from two smaller `exp' groupings
-connected by a plus-sign token.  In the action, `$1' and `$3' refer to
-the semantic values of the two component `exp' groupings, which are the
-first and third symbols on the right hand side of the rule.  The sum is
-stored into `$$' so that it becomes the semantic value of the
-addition-expression just recognized by the rule.  If there were a
-useful semantic value associated with the `+' token, it could be
-referred to as `$2'.
-
-   If you don't specify an action for a rule, Bison supplies a default:
-`$$ = $1'.  Thus, the value of the first symbol in the rule becomes the
-value of the whole rule.  Of course, the default rule is valid only if
-the two data types match.  There is no meaningful default action for an
-empty rule; every empty rule must have an explicit action unless the
-rule's value does not matter.
-
-   `$N' with N zero or negative is allowed for reference to tokens and
-groupings on the stack _before_ those that match the current rule.
-This is a very risky practice, and to use it reliably you must be
-certain of the context in which the rule is applied.  Here is a case in
-which you can use this reliably:
-
-     foo:      expr bar '+' expr  { ... }
-             | expr bar '-' expr  { ... }
-             ;
-     
-     bar:      /* empty */
-             { previous_expr = $0; }
-             ;
-
-   As long as `bar' is used only in the fashion shown here, `$0' always
-refers to the `expr' which precedes `bar' in the definition of `foo'.
-
-\1f
-File: bison.info,  Node: Action Types,  Next: Mid-Rule Actions,  Prev: Actions,  Up: Semantics
-
-Data Types of Values in Actions
--------------------------------
-
-   If you have chosen a single data type for semantic values, the `$$'
-and `$N' constructs always have that data type.
-
-   If you have used `%union' to specify a variety of data types, then
-you must declare a choice among these types for each terminal or
-nonterminal symbol that can have a semantic value.  Then each time you
-use `$$' or `$N', its data type is determined by which symbol it refers
-to in the rule.  In this example,
-
-     exp:    ...
-             | exp '+' exp
-                 { $$ = $1 + $3; }
-
-`$1' and `$3' refer to instances of `exp', so they all have the data
-type declared for the nonterminal symbol `exp'.  If `$2' were used, it
-would have the data type declared for the terminal symbol `'+'',
-whatever that might be.
-
-   Alternatively, you can specify the data type when you refer to the
-value, by inserting `<TYPE>' after the `$' at the beginning of the
-reference.  For example, if you have defined types as shown here:
-
-     %union {
-       int itype;
-       double dtype;
-     }
-
-then you can write `$<itype>1' to refer to the first subunit of the
-rule as an integer, or `$<dtype>1' to refer to it as a double.
-
index 7640c5c0669388aa67e0ad88f579d2fb156f2410..c80fae4822c782de58848f6c2674e02dd0a594c0 100644 (file)
@@ -28,6 +28,150 @@ License", "Conditions for Using Bison" and this permission notice may be
 included in translations approved by the Free Software Foundation
 instead of in the original English.
 
 included in translations approved by the Free Software Foundation
 instead of in the original English.
 
+\1f
+File: bison.info,  Node: Value Type,  Next: Multiple Types,  Up: Semantics
+
+Data Types of Semantic Values
+-----------------------------
+
+   In a simple program it may be sufficient to use the same data type
+for the semantic values of all language constructs.  This was true in
+the RPN and infix calculator examples (*note Reverse Polish Notation
+Calculator: RPN Calc.).
+
+   Bison's default is to use type `int' for all semantic values.  To
+specify some other type, define `YYSTYPE' as a macro, like this:
+
+     #define YYSTYPE double
+
+This macro definition must go in the C declarations section of the
+grammar file (*note Outline of a Bison Grammar: Grammar Outline.).
+
+\1f
+File: bison.info,  Node: Multiple Types,  Next: Actions,  Prev: Value Type,  Up: Semantics
+
+More Than One Value Type
+------------------------
+
+   In most programs, you will need different data types for different
+kinds of tokens and groupings.  For example, a numeric constant may
+need type `int' or `long', while a string constant needs type `char *',
+and an identifier might need a pointer to an entry in the symbol table.
+
+   To use more than one data type for semantic values in one parser,
+Bison requires you to do two things:
+
+   * Specify the entire collection of possible data types, with the
+     `%union' Bison declaration (*note The Collection of Value Types:
+     Union Decl.).
+
+   * Choose one of those types for each symbol (terminal or
+     nonterminal) for which semantic values are used.  This is done for
+     tokens with the `%token' Bison declaration (*note Token Type
+     Names: Token Decl.)  and for groupings with the `%type' Bison
+     declaration (*note Nonterminal Symbols: Type Decl.).
+
+\1f
+File: bison.info,  Node: Actions,  Next: Action Types,  Prev: Multiple Types,  Up: Semantics
+
+Actions
+-------
+
+   An action accompanies a syntactic rule and contains C code to be
+executed each time an instance of that rule is recognized.  The task of
+most actions is to compute a semantic value for the grouping built by
+the rule from the semantic values associated with tokens or smaller
+groupings.
+
+   An action consists of C statements surrounded by braces, much like a
+compound statement in C.  It can be placed at any position in the rule;
+it is executed at that position.  Most rules have just one action at
+the end of the rule, following all the components.  Actions in the
+middle of a rule are tricky and used only for special purposes (*note
+Actions in Mid-Rule: Mid-Rule Actions.).
+
+   The C code in an action can refer to the semantic values of the
+components matched by the rule with the construct `$N', which stands for
+the value of the Nth component.  The semantic value for the grouping
+being constructed is `$$'.  (Bison translates both of these constructs
+into array element references when it copies the actions into the parser
+file.)
+
+   Here is a typical example:
+
+     exp:    ...
+             | exp '+' exp
+                 { $$ = $1 + $3; }
+
+This rule constructs an `exp' from two smaller `exp' groupings
+connected by a plus-sign token.  In the action, `$1' and `$3' refer to
+the semantic values of the two component `exp' groupings, which are the
+first and third symbols on the right hand side of the rule.  The sum is
+stored into `$$' so that it becomes the semantic value of the
+addition-expression just recognized by the rule.  If there were a
+useful semantic value associated with the `+' token, it could be
+referred to as `$2'.
+
+   If you don't specify an action for a rule, Bison supplies a default:
+`$$ = $1'.  Thus, the value of the first symbol in the rule becomes the
+value of the whole rule.  Of course, the default rule is valid only if
+the two data types match.  There is no meaningful default action for an
+empty rule; every empty rule must have an explicit action unless the
+rule's value does not matter.
+
+   `$N' with N zero or negative is allowed for reference to tokens and
+groupings on the stack _before_ those that match the current rule.
+This is a very risky practice, and to use it reliably you must be
+certain of the context in which the rule is applied.  Here is a case in
+which you can use this reliably:
+
+     foo:      expr bar '+' expr  { ... }
+             | expr bar '-' expr  { ... }
+             ;
+     
+     bar:      /* empty */
+             { previous_expr = $0; }
+             ;
+
+   As long as `bar' is used only in the fashion shown here, `$0' always
+refers to the `expr' which precedes `bar' in the definition of `foo'.
+
+\1f
+File: bison.info,  Node: Action Types,  Next: Mid-Rule Actions,  Prev: Actions,  Up: Semantics
+
+Data Types of Values in Actions
+-------------------------------
+
+   If you have chosen a single data type for semantic values, the `$$'
+and `$N' constructs always have that data type.
+
+   If you have used `%union' to specify a variety of data types, then
+you must declare a choice among these types for each terminal or
+nonterminal symbol that can have a semantic value.  Then each time you
+use `$$' or `$N', its data type is determined by which symbol it refers
+to in the rule.  In this example,
+
+     exp:    ...
+             | exp '+' exp
+                 { $$ = $1 + $3; }
+
+`$1' and `$3' refer to instances of `exp', so they all have the data
+type declared for the nonterminal symbol `exp'.  If `$2' were used, it
+would have the data type declared for the terminal symbol `'+'',
+whatever that might be.
+
+   Alternatively, you can specify the data type when you refer to the
+value, by inserting `<TYPE>' after the `$' at the beginning of the
+reference.  For example, if you have defined types as shown here:
+
+     %union {
+       int itype;
+       double dtype;
+     }
+
+then you can write `$<itype>1' to refer to the first subunit of the
+rule as an integer, or `$<dtype>1' to refer to it as a double.
+
 \1f
 File: bison.info,  Node: Mid-Rule Actions,  Prev: Action Types,  Up: Semantics
 
 \1f
 File: bison.info,  Node: Mid-Rule Actions,  Prev: Action Types,  Up: Semantics
 
@@ -1171,110 +1315,3 @@ useful in actions.
      textual position of the Nth component of the current rule.  *Note
      Tracking Locations: Locations.
 
      textual position of the Nth component of the current rule.  *Note
      Tracking Locations: Locations.
 
-\1f
-File: bison.info,  Node: Algorithm,  Next: Error Recovery,  Prev: Interface,  Up: Top
-
-The Bison Parser Algorithm
-**************************
-
-   As Bison reads tokens, it pushes them onto a stack along with their
-semantic values.  The stack is called the "parser stack".  Pushing a
-token is traditionally called "shifting".
-
-   For example, suppose the infix calculator has read `1 + 5 *', with a
-`3' to come.  The stack will have four elements, one for each token
-that was shifted.
-
-   But the stack does not always have an element for each token read.
-When the last N tokens and groupings shifted match the components of a
-grammar rule, they can be combined according to that rule.  This is
-called "reduction".  Those tokens and groupings are replaced on the
-stack by a single grouping whose symbol is the result (left hand side)
-of that rule.  Running the rule's action is part of the process of
-reduction, because this is what computes the semantic value of the
-resulting grouping.
-
-   For example, if the infix calculator's parser stack contains this:
-
-     1 + 5 * 3
-
-and the next input token is a newline character, then the last three
-elements can be reduced to 15 via the rule:
-
-     expr: expr '*' expr;
-
-Then the stack contains just these three elements:
-
-     1 + 15
-
-At this point, another reduction can be made, resulting in the single
-value 16.  Then the newline token can be shifted.
-
-   The parser tries, by shifts and reductions, to reduce the entire
-input down to a single grouping whose symbol is the grammar's
-start-symbol (*note Languages and Context-Free Grammars: Language and
-Grammar.).
-
-   This kind of parser is known in the literature as a bottom-up parser.
-
-* Menu:
-
-* Look-Ahead::        Parser looks one token ahead when deciding what to do.
-* Shift/Reduce::      Conflicts: when either shifting or reduction is valid.
-* Precedence::        Operator precedence works by resolving conflicts.
-* Contextual Precedence::  When an operator's precedence depends on context.
-* Parser States::     The parser is a finite-state-machine with stack.
-* Reduce/Reduce::     When two rules are applicable in the same situation.
-* Mystery Conflicts::  Reduce/reduce conflicts that look unjustified.
-* Stack Overflow::    What happens when stack gets full.  How to avoid it.
-
-\1f
-File: bison.info,  Node: Look-Ahead,  Next: Shift/Reduce,  Up: Algorithm
-
-Look-Ahead Tokens
-=================
-
-   The Bison parser does _not_ always reduce immediately as soon as the
-last N tokens and groupings match a rule.  This is because such a
-simple strategy is inadequate to handle most languages.  Instead, when a
-reduction is possible, the parser sometimes "looks ahead" at the next
-token in order to decide what to do.
-
-   When a token is read, it is not immediately shifted; first it
-becomes the "look-ahead token", which is not on the stack.  Now the
-parser can perform one or more reductions of tokens and groupings on
-the stack, while the look-ahead token remains off to the side.  When no
-more reductions should take place, the look-ahead token is shifted onto
-the stack.  This does not mean that all possible reductions have been
-done; depending on the token type of the look-ahead token, some rules
-may choose to delay their application.
-
-   Here is a simple case where look-ahead is needed.  These three rules
-define expressions which contain binary addition operators and postfix
-unary factorial operators (`!'), and allow parentheses for grouping.
-
-     expr:     term '+' expr
-             | term
-             ;
-     
-     term:     '(' expr ')'
-             | term '!'
-             | NUMBER
-             ;
-
-   Suppose that the tokens `1 + 2' have been read and shifted; what
-should be done?  If the following token is `)', then the first three
-tokens must be reduced to form an `expr'.  This is the only valid
-course, because shifting the `)' would produce a sequence of symbols
-`term ')'', and no rule allows this.
-
-   If the following token is `!', then it must be shifted immediately so
-that `2 !' can be reduced to make a `term'.  If instead the parser were
-to reduce before shifting, `1 + 2' would become an `expr'.  It would
-then be impossible to shift the `!' because doing so would produce on
-the stack the sequence of symbols `expr '!''.  No rule allows that
-sequence.
-
-   The current look-ahead token is stored in the variable `yychar'.
-*Note Special Features for Use in Actions: Action Features.
-
index a385c81c308aa376351ed9d8436ea6b74964d2ab..6bd65ae9bf17c2a4c62d400359c2a1ef9912a525 100644 (file)
@@ -28,6 +28,113 @@ License", "Conditions for Using Bison" and this permission notice may be
 included in translations approved by the Free Software Foundation
 instead of in the original English.
 
 included in translations approved by the Free Software Foundation
 instead of in the original English.
 
+\1f
+File: bison.info,  Node: Algorithm,  Next: Error Recovery,  Prev: Interface,  Up: Top
+
+The Bison Parser Algorithm
+**************************
+
+   As Bison reads tokens, it pushes them onto a stack along with their
+semantic values.  The stack is called the "parser stack".  Pushing a
+token is traditionally called "shifting".
+
+   For example, suppose the infix calculator has read `1 + 5 *', with a
+`3' to come.  The stack will have four elements, one for each token
+that was shifted.
+
+   But the stack does not always have an element for each token read.
+When the last N tokens and groupings shifted match the components of a
+grammar rule, they can be combined according to that rule.  This is
+called "reduction".  Those tokens and groupings are replaced on the
+stack by a single grouping whose symbol is the result (left hand side)
+of that rule.  Running the rule's action is part of the process of
+reduction, because this is what computes the semantic value of the
+resulting grouping.
+
+   For example, if the infix calculator's parser stack contains this:
+
+     1 + 5 * 3
+
+and the next input token is a newline character, then the last three
+elements can be reduced to 15 via the rule:
+
+     expr: expr '*' expr;
+
+Then the stack contains just these three elements:
+
+     1 + 15
+
+At this point, another reduction can be made, resulting in the single
+value 16.  Then the newline token can be shifted.
+
+   The parser tries, by shifts and reductions, to reduce the entire
+input down to a single grouping whose symbol is the grammar's
+start-symbol (*note Languages and Context-Free Grammars: Language and
+Grammar.).
+
+   This kind of parser is known in the literature as a bottom-up parser.
+
+* Menu:
+
+* Look-Ahead::        Parser looks one token ahead when deciding what to do.
+* Shift/Reduce::      Conflicts: when either shifting or reduction is valid.
+* Precedence::        Operator precedence works by resolving conflicts.
+* Contextual Precedence::  When an operator's precedence depends on context.
+* Parser States::     The parser is a finite-state-machine with stack.
+* Reduce/Reduce::     When two rules are applicable in the same situation.
+* Mystery Conflicts::  Reduce/reduce conflicts that look unjustified.
+* Stack Overflow::    What happens when stack gets full.  How to avoid it.
+
+\1f
+File: bison.info,  Node: Look-Ahead,  Next: Shift/Reduce,  Up: Algorithm
+
+Look-Ahead Tokens
+=================
+
+   The Bison parser does _not_ always reduce immediately as soon as the
+last N tokens and groupings match a rule.  This is because such a
+simple strategy is inadequate to handle most languages.  Instead, when a
+reduction is possible, the parser sometimes "looks ahead" at the next
+token in order to decide what to do.
+
+   When a token is read, it is not immediately shifted; first it
+becomes the "look-ahead token", which is not on the stack.  Now the
+parser can perform one or more reductions of tokens and groupings on
+the stack, while the look-ahead token remains off to the side.  When no
+more reductions should take place, the look-ahead token is shifted onto
+the stack.  This does not mean that all possible reductions have been
+done; depending on the token type of the look-ahead token, some rules
+may choose to delay their application.
+
+   Here is a simple case where look-ahead is needed.  These three rules
+define expressions which contain binary addition operators and postfix
+unary factorial operators (`!'), and allow parentheses for grouping.
+
+     expr:     term '+' expr
+             | term
+             ;
+     
+     term:     '(' expr ')'
+             | term '!'
+             | NUMBER
+             ;
+
+   Suppose that the tokens `1 + 2' have been read and shifted; what
+should be done?  If the following token is `)', then the first three
+tokens must be reduced to form an `expr'.  This is the only valid
+course, because shifting the `)' would produce a sequence of symbols
+`term ')'', and no rule allows this.
+
+   If the following token is `!', then it must be shifted immediately so
+that `2 !' can be reduced to make a `term'.  If instead the parser were
+to reduce before shifting, `1 + 2' would become an `expr'.  It would
+then be impossible to shift the `!' because doing so would produce on
+the stack the sequence of symbols `expr '!''.  No rule allows that
+sequence.
+
+   The current look-ahead token is stored in the variable `yychar'.
+*Note Special Features for Use in Actions: Action Features.
+
 \1f
 File: bison.info,  Node: Shift/Reduce,  Next: Precedence,  Prev: Look-Ahead,  Up: Algorithm
 
 \1f
 File: bison.info,  Node: Shift/Reduce,  Next: Precedence,  Prev: Look-Ahead,  Up: Algorithm
 
index 965c6fac63166a793b2a4ecc5693f51b3e7fc697..927438b2d7814d8f37e12197b5bb66e542668006 100644 (file)
@@ -855,6 +855,7 @@ Index
 * C-language interface:                  Interface.
 * calc:                                  Infix Calc.
 * calculator, infix notation:            Infix Calc.
 * C-language interface:                  Interface.
 * calc:                                  Infix Calc.
 * calculator, infix notation:            Infix Calc.
+* calculator, location tracking:         Location Tracking Calc.
 * calculator, multi-function:            Multi-function Calc.
 * calculator, simple:                    RPN Calc.
 * character token:                       Symbols.
 * calculator, multi-function:            Multi-function Calc.
 * calculator, simple:                    RPN Calc.
 * character token:                       Symbols.
@@ -925,8 +926,10 @@ Index
 * location <1>:                          Locations.
 * location:                              Locations Overview.
 * location actions:                      Actions and Locations.
 * location <1>:                          Locations.
 * location:                              Locations Overview.
 * location actions:                      Actions and Locations.
+* location tracking calculator:          Location Tracking Calc.
 * look-ahead token:                      Look-Ahead.
 * LR(1):                                 Mystery Conflicts.
 * look-ahead token:                      Look-Ahead.
 * LR(1):                                 Mystery Conflicts.
+* ltcalc:                                Location Tracking Calc.
 * main function in simple example:       Rpcalc Main.
 * mfcalc:                                Multi-function Calc.
 * mid-rule actions:                      Mid-Rule Actions.
 * main function in simple example:       Rpcalc Main.
 * mfcalc:                                Multi-function Calc.
 * mid-rule actions:                      Mid-Rule Actions.
index 517fcfdc350adf97147a7aa56309be6e40aaef89..db9f2cf096368a75f6ace1162e9c16016520973f 100644 (file)
@@ -184,6 +184,7 @@ Examples
 * Infix Calc::        Infix (algebraic) notation calculator.
                         Operator precedence is introduced.
 * Simple Error Recovery::  Continuing after syntax errors.
 * Infix Calc::        Infix (algebraic) notation calculator.
                         Operator precedence is introduced.
 * Simple Error Recovery::  Continuing after syntax errors.
+* Location Tracking Calc:: Demonstrating the use of @@@var{n} and @@$.
 * Multi-function Calc::    Calculator with memory and trig functions.
                         It uses multiple data-types for semantic values.
 * Exercises::         Ideas for improving the multi-function calculator.
 * Multi-function Calc::    Calculator with memory and trig functions.
                         It uses multiple data-types for semantic values.
 * Exercises::         Ideas for improving the multi-function calculator.
@@ -204,6 +205,12 @@ Grammar Rules for @code{rpcalc}
 * Rpcalc Line::
 * Rpcalc Expr::
 
 * Rpcalc Line::
 * Rpcalc Expr::
 
+Location Tracking Calculator: @code{ltcalc}
+
+* Decls: Ltcalc Decls.  Bison and C declarations for ltcalc.
+* Rules: Ltcalc Rules.  Grammar rules for ltcalc, with explanations.
+* Lexer: Ltcalc Lexer.  The lexical analyzer.
+
 Multi-Function Calculator: @code{mfcalc}
 
 * Decl: Mfcalc Decl.      Bison declarations for multi-function calculator.
 Multi-Function Calculator: @code{mfcalc}
 
 * Decl: Mfcalc Decl.      Bison declarations for multi-function calculator.
@@ -794,6 +801,7 @@ to try them.
 * Infix Calc::        Infix (algebraic) notation calculator.
                         Operator precedence is introduced.
 * Simple Error Recovery::  Continuing after syntax errors.
 * Infix Calc::        Infix (algebraic) notation calculator.
                         Operator precedence is introduced.
 * Simple Error Recovery::  Continuing after syntax errors.
+* Location Tracking Calc:: Demonstrating the use of @@@var{n} and @@$.
 * Multi-function Calc::  Calculator with memory and trig functions.
                            It uses multiple data-types for semantic values.
 * Exercises::         Ideas for improving the multi-function calculator.
 * Multi-function Calc::  Calculator with memory and trig functions.
                            It uses multiple data-types for semantic values.
 * Exercises::         Ideas for improving the multi-function calculator.
@@ -1358,6 +1366,204 @@ input lines; it would also have to discard the rest of the current line of
 input.  We won't discuss this issue further because it is not specific to
 Bison programs.
 
 input.  We won't discuss this issue further because it is not specific to
 Bison programs.
 
+@node Location Tracking Calc
+@section Location Tracking Calculator: @code{ltcalc}
+@cindex location tracking calculator
+@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.
+
+@menu
+* Decls: Ltcalc Decls.  Bison and C declarations for ltcalc.
+* Rules: Ltcalc Rules.  Grammar rules for ltcalc, with explanations.
+* Lexer: Ltcalc Lexer.  The lexical analyzer.
+@end menu
+
+@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.
+
+@example
+/* Location tracking calculator.  */
+
+%@{
+#define YYSTYPE int
+#include <math.h>
+%@}
+
+/* Bison declarations.  */
+%token NUM
+
+%left '-' '+'
+%left '*' '/'
+%left NEG
+%right '^'
+
+%% /* 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}.
+
+@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.
+
+Here, we will use locations to report divisions by zero, and locate the wrong
+expressions or subexpressions.
+
+@example
+@group
+input   : /* empty */
+        | input line
+;
+@end group
+
+@group
+line    : '\n'
+        | exp '\n' @{ printf ("%d\n", $1); @}
+;
+@end group
+
+@group
+exp     : NUM           @{ $$ = $1; @}
+        | exp '+' exp   @{ $$ = $1 + $3; @}
+        | exp '-' exp   @{ $$ = $1 - $3; @}
+        | exp '*' exp   @{ $$ = $1 * $3; @}
+@end group
+        | exp '/' exp
+@group
+            @{
+              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);
+                @}
+            @}
+@end group
+@group
+        | '-' exp %preg NEG     @{ $$ = -$2; @}
+        | exp '^' exp           @{ $$ = pow ($1, $3); @}
+        | '(' exp ')'           @{ $$ = $2; @}
+@end group
+@end example
+
+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.
+
+@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.
+
+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:
+
+@example
+@group
+int
+yylex (void)
+@{
+  int c;
+
+  /* skip white space */
+  while ((c = getchar ()) == ' ' || c == '\t')
+    ++yylloc.last_column;
+
+  /* step */
+  yylloc.first_line = yylloc.last_line;
+  yylloc.first_column = yylloc.last_column;
+@end group
+
+@group
+  /* process numbers */
+  if (isdigit (c))
+    @{
+      yylval = c - '0';
+      ++yylloc.last_column;
+      while (isdigit (c = getchar ()))
+        @{
+          ++yylloc.last_column;
+          yylval = yylval * 10 + c - '0';
+        @}
+      ungetc (c, stdin);
+      return NUM;
+    @}
+@end group
+
+  /* return end-of-file */
+  if (c == EOF)
+    return 0;
+
+  /* return single chars and update location */
+  if (c == '\n')
+    @{
+      ++yylloc.last_line;
+      yylloc.last_column = 0;
+    @}
+  else
+    ++yylloc.last_column;
+  return c;
+@}
+@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.
+
+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:
+
+@example
+int
+main (void)
+@{
+  yylloc.first_line = yylloc.last_line = 1;
+  yylloc.first_column = yylloc.last_column = 0;
+  return yyparse ();
+@}
+@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...
+
 @node Multi-function Calc
 @section Multi-Function Calculator: @code{mfcalc}
 @cindex multi-function calculator
 @node Multi-function Calc
 @section Multi-Function Calculator: @code{mfcalc}
 @cindex multi-function calculator