X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/411614fac478a60cf942dc5e2011a08178156d30..24ec08374334f3c4cfb4080384793aa423e29679:/doc/bison.texinfo diff --git a/doc/bison.texinfo b/doc/bison.texinfo index b6604f61..0f5dbbb3 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -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 #include 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 @@ -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 /* For math functions, cos(), sin(), etc. */ - #include "calc.h" /* Contains definition of `symrec'. */ + #include /* For printf, etc. */ + #include /* 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 - -@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 /* malloc. */ +#include /* 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 @@ -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 @@ -9270,7 +9304,8 @@ scanner should use @code{yy::parser::token::FOO}. The scanner can use @defcv {Type} {parser} {syntax_error} This class derives from @code{std::runtime_error}. Throw instances of it -from user actions to raise parse errors. This is equivalent with first +from the scanner or from the user actions to raise parse errors. This is +equivalent with first invoking @code{error} to report the location and message of the syntax error, and then to invoke @code{YYERROR} to enter the error-recovery mode. But contrary to @code{YYERROR} which can only be invoked from user actions @@ -9940,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); @} @} @@ -10674,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; }