bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: master: examples: calc++: minor improvements


From: Akim Demaille
Subject: FYI: master: examples: calc++: minor improvements
Date: Fri, 24 Aug 2018 19:42:06 +0200

Installed in master.

commit b4e9eaefd55640d913deadfc0ba3a241f7e8a8ea
Author: Akim Demaille <address@hidden>
Date:   Fri Aug 24 19:12:07 2018 +0200

    examples: calc++: minor improvements
    
    * doc/bison.texi (A Complete C++ Example): Prefer throw exceptions
    from the scanner.
    Show the invalid characters.
    Since the scanner sends exceptions, it no longer needs to report
    errors, so we can get rid of the driver's routine to report error,
    do it in yyerror.
    Use @group/@end group to improve rendering.

diff --git a/doc/bison.texi b/doc/bison.texi
index 8896fb77..6cd52917 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -11156,66 +11156,56 @@ public:
 @end example
 
 @noindent
-To encapsulate the coordination with the Flex scanner, it is useful to have
-member functions to open and close the scanning phase.
+The main routine is of course calling the parser.
 
 @comment file: calc++/driver.hh
 @example
-  // Handling the scanner.
-  void scan_begin ();
-  void scan_end ();
-  // Whether to generate scanner debug traces.
-  bool trace_scanning;
-  // The token's location used by the scanner.
-  yy::location location;
address@hidden example
-
address@hidden
-Similarly for the parser itself.
-
address@hidden file: calc++/driver.hh
address@hidden
-  // Run the parser on file F.
-  // Return 0 on success.
+  // Run the parser on file F.  Return 0 on success.
   int parse (const std::string& f);
   // The name of the file being parsed.
   std::string file;
-  // Whether parser traces should be generated.
+  // Whether to generate parser debug traces.
   bool trace_parsing;
 @end example
 
 @noindent
-To demonstrate pure handling of parse errors, instead of simply
-dumping them on the standard error output, we will pass them to the
-compiler driver using the following two member functions.  Finally, we
-close the class declaration and CPP guard.
+To encapsulate the coordination with the Flex scanner, it is useful to have
+member functions to open and close the scanning phase.
 
 @comment file: calc++/driver.hh
 @example
-  // Error handling.
-  void error (const yy::location& l, const std::string& m);
-  void error (const std::string& m);
+  // Handling the scanner.
+  void scan_begin ();
+  void scan_end ();
+  // Whether to generate scanner debug traces.
+  bool trace_scanning;
+  // The token's location used by the scanner.
+  yy::location location;
 @};
 #endif // ! DRIVER_HH
 @end example
 
-The implementation of the driver is straightforward.  The @code{parse}
-member function deserves some attention.  The @code{error} functions
-are simple stubs, they should actually register the located error
-messages and set error state.
+The implementation of the driver (@file{driver.cc}) is straightforward.
 
 @comment file: calc++/driver.cc
 @example
 #include "driver.hh"
 #include "parser.hh"
 
address@hidden
 driver::driver ()
-  : trace_scanning (false), trace_parsing (false)
+  : trace_parsing (false), trace_scanning (false)
 @{
   variables["one"] = 1;
   variables["two"] = 2;
 @}
address@hidden group
address@hidden example
 
+The @code{parse} member function deserves some attention.
+
address@hidden file: calc++/driver.cc
address@hidden
 @group
 int
 driver::parse (const std::string &f)
@@ -11230,18 +11220,6 @@ driver::parse (const std::string &f)
   return res;
 @}
 @end group
-
-void
-driver::error (const yy::location& l, const std::string& m)
address@hidden
-  std::cerr << l << ": " << m << '\n';
address@hidden
-
-void
-driver::error (const std::string& m)
address@hidden
-  std::cerr << m << '\n';
address@hidden
 @end example
 
 @node Calc++ Parser
@@ -11286,11 +11264,12 @@ forward declaration of the driver.  @xref{%code 
Summary}.
 
 @comment file: calc++/parser.yy
 @example
-%code requires
address@hidden
-# include <string>
-class driver;
address@hidden
+%code requires @{
+  # include <string>
+  class driver;
 @}
address@hidden group
 @end example
 
 @noindent
@@ -11330,10 +11309,11 @@ file; it needs detailed knowledge about the driver.
 
 @comment file: calc++/parser.yy
 @example
-%code
address@hidden
address@hidden
+%code @{
 # include "driver.hh"
 @}
address@hidden group
 @end example
 
 
@@ -11413,14 +11393,14 @@ exp:
 @end example
 
 @noindent
-Finally the @code{error} member function registers the errors to the driver.
+Finally the @code{error} member function reports the errors.
 
 @comment file: calc++/parser.yy
 @example
 void
 yy::parser::error (const location_type& l, const std::string& m)
 @{
-  drv.error (l, m);
+  std::cerr << l << ": " << m << '\n';
 @}
 @end example
 
@@ -11524,12 +11504,18 @@ The rules are simple.  The driver is used to report 
errors.
   errno = 0;
   long n = strtol (yytext, NULL, 10);
   if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
-    drv.error (loc, "integer is out of range");
+    throw yy::parser::syntax_error (loc, "integer is out of range: "
+                                    + std::string(yytext));
   return yy::parser::make_NUMBER (n, loc);
 @}
 @end group
 @address@hidden       return yy::parser::make_IDENTIFIER (yytext, loc);
-.          drv.error (loc, "invalid character");
address@hidden
+.          @{
+             throw yy::parser::syntax_error
+               (loc, "invalid character: " + std::string(yytext));
address@hidden
address@hidden group
 <<EOF>>    return yy::parser::make_END (loc);
 %%
 @end example
@@ -11549,7 +11535,7 @@ driver::scan_begin ()
     yyin = stdin;
   else if (!(yyin = fopen (file.c_str (), "r")))
     @{
-      error ("cannot open " + file + ": " + strerror(errno));
+      std::cerr << "cannot open " << file << ": " << strerror(errno) << '\n';
       exit (EXIT_FAILURE);
     @}
 @}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]