]> git.saurik.com Git - bison.git/blobdiff - doc/bison.texinfo
doc: check the rpcalc.
[bison.git] / doc / bison.texinfo
index 836733d00ff4a796f5171d625558ab5c53f3e1b9..0f5dbbb3f9cd5f4ebe912e4402fd140733aaf0c9 100644 (file)
@@ -163,9 +163,9 @@ Reverse Polish Notation Calculator
 
 Grammar Rules for @code{rpcalc}
 
-* Rpcalc Input::
-* Rpcalc Line::
-* Rpcalc Expr::
+* Rpcalc Input::            Explanation of the @code{input} nonterminal
+* Rpcalc Line::             Explanation of the @code{line} nonterminal
+* Rpcalc Expr::             Explanation of the @code{expr} nonterminal
 
 Location Tracking Calculator: @code{ltcalc}
 
@@ -178,6 +178,8 @@ Multi-Function Calculator: @code{mfcalc}
 * Mfcalc Declarations::    Bison declarations for multi-function calculator.
 * Mfcalc Rules::           Grammar rules for the calculator.
 * Mfcalc Symbol Table::    Symbol table management subroutines.
+* Mfcalc Lexer::           The lexical analyzer.
+* Mfcalc Main::            The controlling function.
 
 Bison Grammar Files
 
@@ -1515,11 +1517,13 @@ The source code for this calculator is named @file{rpcalc.y}.  The
 Here are the C and Bison declarations for the reverse polish notation
 calculator.  As in C, comments are placed between @samp{/*@dots{}*/}.
 
+@comment file: rpcalc.y
 @example
 /* Reverse polish notation calculator.  */
 
 %@{
   #define YYSTYPE double
+  #include <stdio.h>
   #include <math.h>
   int yylex (void);
   void yyerror (char const *);
@@ -1564,13 +1568,14 @@ type for numeric constants.
 
 Here are the grammar rules for the reverse polish notation calculator.
 
+@comment file: rpcalc.y
 @example
 input:    /* empty */
         | input line
 ;
 
 line:     '\n'
-        | exp '\n'      @{ printf ("\t%.10g\n", $1); @}
+        | exp '\n'      @{ printf ("%.10g\n", $1); @}
 ;
 
 exp:      NUM           @{ $$ = $1;           @}
@@ -1605,9 +1610,9 @@ main job of most actions.  The semantic values of the components of the
 rule are referred to as @code{$1}, @code{$2}, and so on.
 
 @menu
-* Rpcalc Input::
-* Rpcalc Line::
-* Rpcalc Expr::
+* Rpcalc Input::            Explanation of the @code{input} nonterminal
+* Rpcalc Line::             Explanation of the @code{line} nonterminal
+* Rpcalc Expr::             Explanation of the @code{expr} nonterminal
 @end menu
 
 @node Rpcalc Input
@@ -1651,7 +1656,7 @@ Now consider the definition of @code{line}:
 
 @example
 line:     '\n'
-        | exp '\n'  @{ printf ("\t%.10g\n", $1); @}
+        | exp '\n'  @{ printf ("%.10g\n", $1); @}
 ;
 @end example
 
@@ -1767,6 +1772,7 @@ A token type code of zero is returned if the end-of-input is encountered.
 
 Here is the code for the lexical analyzer:
 
+@comment file: rpcalc.y
 @example
 @group
 /* The lexical analyzer returns a double floating point
@@ -1815,6 +1821,7 @@ In keeping with the spirit of this example, the controlling function is
 kept to the bare minimum.  The only requirement is that it call
 @code{yyparse} to start the process of parsing.
 
+@comment file: rpcalc.y
 @example
 @group
 int
@@ -1835,6 +1842,7 @@ always @code{"syntax error"}).  It is up to the programmer to supply
 @code{yyerror} (@pxref{Interface, ,Parser C-Language Interface}), so
 here is the definition we will use:
 
+@comment file: rpcalc.y
 @example
 @group
 #include <stdio.h>
@@ -1917,15 +1925,15 @@ example session using @code{rpcalc}.
 @example
 $ @kbd{rpcalc}
 @kbd{4 9 +}
-13
+@result{} 13
 @kbd{3 7 + 3 4 5 *+-}
--13
+@result{} -13
 @kbd{3 7 + 3 4 5 * + - n}              @r{Note the unary minus, @samp{n}}
-13
+@result{} 13
 @kbd{5 6 / 4 n +}
--3.166666667
+@result{} -3.166666667
 @kbd{3 4 ^}                            @r{Exponentiation}
-81
+@result{} 81
 @kbd{^D}                               @r{End-of-file indicator}
 $
 @end example
@@ -2300,17 +2308,17 @@ Here is a sample session with the multi-function calculator:
 @example
 $ @kbd{mfcalc}
 @kbd{pi = 3.141592653589}
-3.1415926536
+@result{} 3.1415926536
 @kbd{sin(pi)}
-0.0000000000
+@result{} 0.0000000000
 @kbd{alpha = beta1 = 2.3}
-2.3000000000
+@result{} 2.3000000000
 @kbd{alpha}
-2.3000000000
+@result{} 2.3000000000
 @kbd{ln(alpha)}
-0.8329091229
+@result{} 0.8329091229
 @kbd{exp(ln(beta1))}
-2.3000000000
+@result{} 2.3000000000
 $
 @end example
 
@@ -2320,6 +2328,8 @@ Note that multiple assignment and nested function calls are permitted.
 * Mfcalc Declarations::    Bison declarations for multi-function calculator.
 * Mfcalc Rules::           Grammar rules for the calculator.
 * Mfcalc Symbol Table::    Symbol table management subroutines.
+* Mfcalc Lexer::           The lexical analyzer.
+* Mfcalc Main::            The controlling function.
 @end menu
 
 @node Mfcalc Declarations
@@ -2327,11 +2337,13 @@ Note that multiple assignment and nested function calls are permitted.
 
 Here are the C and Bison declarations for the multi-function calculator.
 
+@comment file: mfcalc.y
 @smallexample
 @group
 %@{
-  #include <math.h>  /* For math functions, cos(), sin(), etc.  */
-  #include "calc.h"  /* Contains definition of `symrec'.  */
+  #include <stdio.h>  /* For printf, etc. */
+  #include <math.h>   /* For pow, used in the grammar.  */
+  #include "calc.h"   /* Contains definition of `symrec'.  */
   int yylex (void);
   void yyerror (char const *);
 %@}
@@ -2385,6 +2397,7 @@ Here are the grammar rules for the multi-function calculator.
 Most of them are copied directly from @code{calc}; three rules,
 those which mention @code{VAR} or @code{FNCT}, are new.
 
+@comment file: mfcalc.y
 @smallexample
 @group
 input:   /* empty */
@@ -2395,8 +2408,8 @@ input:   /* empty */
 @group
 line:
           '\n'
-        | exp '\n'   @{ printf ("\t%.10g\n", $1); @}
-        | error '\n' @{ yyerrok;                  @}
+        | exp '\n'   @{ printf ("%.10g\n", $1); @}
+        | error '\n' @{ yyerrok;                @}
 ;
 @end group
 
@@ -2431,6 +2444,7 @@ The symbol table itself consists of a linked list of records.  Its
 definition, which is kept in the header @file{calc.h}, is as follows.  It
 provides for either functions or variables to be placed in the table.
 
+@comment file: calc.h
 @smallexample
 @group
 /* Function type.  */
@@ -2463,22 +2477,11 @@ symrec *getsym (char const *);
 @end group
 @end smallexample
 
-The new version of @code{main} includes a call to @code{init_table}, a
-function that initializes the symbol table.  Here it is, and
-@code{init_table} as well:
+The new version of @code{main} will call @code{init_table} to initialize
+the symbol table:
 
+@comment file: mfcalc.y
 @smallexample
-#include <stdio.h>
-
-@group
-/* Called by yyparse on error.  */
-void
-yyerror (char const *s)
-@{
-  printf ("%s\n", s);
-@}
-@end group
-
 @group
 struct init
 @{
@@ -2490,13 +2493,13 @@ struct init
 @group
 struct init const arith_fncts[] =
 @{
-  "sin",  sin,
-  "cos",  cos,
-  "atan", atan,
-  "ln",   log,
-  "exp",  exp,
-  "sqrt", sqrt,
-  0, 0
+  @{ "atan", atan @},
+  @{ "cos",  cos  @},
+  @{ "exp",  exp  @},
+  @{ "ln",   log  @},
+  @{ "sin",  sin  @},
+  @{ "sqrt", sqrt @},
+  @{ 0, 0 @},
 @};
 @end group
 
@@ -2507,6 +2510,7 @@ symrec *sym_table;
 
 @group
 /* Put arithmetic functions in table.  */
+static
 void
 init_table (void)
 @{
@@ -2519,15 +2523,6 @@ init_table (void)
     @}
 @}
 @end group
-
-@group
-int
-main (void)
-@{
-  init_table ();
-  return yyparse ();
-@}
-@end group
 @end smallexample
 
 By simply editing the initialization list and adding the necessary include
@@ -2540,7 +2535,11 @@ linked to the front of the list, and a pointer to the object is returned.
 The function @code{getsym} is passed the name of the symbol to look up.  If
 found, a pointer to that symbol is returned; otherwise zero is returned.
 
+@comment file: mfcalc.y
 @smallexample
+#include <stdlib.h> /* malloc. */
+#include <string.h> /* strlen. */
+
 symrec *
 putsym (char const *sym_name, int sym_type)
 @{
@@ -2567,6 +2566,9 @@ getsym (char const *sym_name)
 @}
 @end smallexample
 
+@node Mfcalc Lexer
+@subsection The @code{mfcalc} Lexer
+
 The function @code{yylex} must now recognize variables, numeric values, and
 the single-character arithmetic operators.  Strings of alphanumeric
 characters with a leading letter are recognized as either variables or
@@ -2582,6 +2584,7 @@ returned to @code{yyparse}.
 No change is needed in the handling of numeric values and arithmetic
 operators in @code{yylex}.
 
+@comment file: mfcalc.y
 @smallexample
 @group
 #include <ctype.h>
@@ -2624,7 +2627,10 @@ yylex (void)
       /* Initially make the buffer long enough
          for a 40-character symbol name.  */
       if (length == 0)
-        length = 40, symbuf = (char *)malloc (length + 1);
+        @{
+          length = 40;
+          symbuf = (char *) malloc (length + 1);
+        @}
 
       i = 0;
       do
@@ -2664,6 +2670,34 @@ yylex (void)
 @end group
 @end smallexample
 
+@node Mfcalc Main
+@subsection The @code{mfcalc} Main
+
+The error reporting function is unchanged, and the new version of
+@code{main} includes a call to @code{init_table}:
+
+@comment file: mfcalc.y
+@smallexample
+
+@group
+@group
+/* Called by yyparse on error.  */
+void
+yyerror (char const *s)
+@{
+  fprintf (stderr, "%s\n", s);
+@}
+@end group
+
+int
+main (int argc, char const* argv[])
+@{
+  init_table ();
+  return yyparse ();
+@}
+@end group
+@end smallexample
+
 This program is both powerful and flexible.  You may easily add new
 functions, and it is a simple job to modify this code to install
 predefined variables such as @code{pi} or @code{e} as well.
@@ -4166,7 +4200,7 @@ In references, in order to specify names containing dots and dashes, an explicit
 bracketed syntax @code{$[name]} and @code{@@[name]} must be used:
 @example
 @group
-if-stmt: IF '(' expr ')' THEN then.stmt ';'
+if-stmt: "if" '(' expr ')' "then" then.stmt ';'
   @{ $[if-stmt] = new_if_stmt ($expr, $[then.stmt]); @}
 @end group
 @end example
@@ -9941,7 +9975,7 @@ calcxx_driver::scan_begin ()
   else if (!(yyin = fopen (file.c_str (), "r")))
     @{
       error (std::string ("cannot open ") + file + ": " + strerror(errno));
-      exit (1);
+      exit (EXIT_FAILURE);
     @}
 @}
 
@@ -10675,11 +10709,17 @@ yyparse (char const *file)
 {
   yyin = fopen (file, "r");
   if (!yyin)
-    exit (2);
+  {
+    perror ("fopen");
+    exit (EXIT_FAILURE);
+  }
   /* One token only.  */
   yylex ();
   if (fclose (yyin) != 0)
-    exit (3);
+  {
+    perror ("fclose");
+    exit (EXIT_FAILURE);
+  }
   return 0;
 }