bison-patches
[Top][All Lists]
Advanced

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

FYI: Extract calc++ from the documentation


From: Akim Demaille
Subject: FYI: Extract calc++ from the documentation
Date: Tue, 05 Jul 2005 09:23:08 +0200
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

[Paul in CC because I'm not sure the message will appear on the list.]

There still remains to bind this to the package itself, currently you
have to go into examples/calc++ and run make extract before make.

Index: ChangeLog
from  Akim Demaille  <address@hidden>

        Extract calc++ from the documentation.
        * doc/bison.texinfo (Calc++): Add the extraction marks.
        * examples/extexi: New, from the aborted GNU Programming 2E.
        Separate the different paragraph of a file with empty lines.
        * examples/Makefile: Use it to extract the whole calc++ example.

Index: doc/bison.texinfo
===================================================================
RCS file: /cvsroot/bison/bison/doc/bison.texinfo,v
retrieving revision 1.146
diff -u -u -r1.146 bison.texinfo
--- doc/bison.texinfo 24 Jun 2005 14:56:11 -0000 1.146
+++ doc/bison.texinfo 5 Jul 2005 07:21:18 -0000
@@ -7031,6 +7031,7 @@
 follows.  The first part includes the CPP guard and imports the
 required standard library components.
 
address@hidden file: calc++-driver.hh
 @example
 #ifndef CALCXX_DRIVER_HH
 # define CALCXX_DRIVER_HH
@@ -7045,10 +7046,15 @@
 by the rest of the project, it is saner to forward declare the
 parser's information here.
 
address@hidden file: calc++-driver.hh
 @example
 // Forward declarations.
 union YYSTYPE;
-namespace yy @{ class calcxx_parser; @}
+namespace yy
address@hidden
+  class location;
+  class calcxx_parser;
address@hidden
 class calcxx_driver;
 @end example
 
@@ -7057,9 +7063,11 @@
 the signature of @code{yylex} to be defined in the macro
 @code{YY_DECL}, and the C++ parser expects it to be declared.  We can
 factor both as follows.
+
address@hidden file: calc++-driver.hh
 @example
 // Announce to Flex the prototype we want for lexing function, ...
-# define YY_DECL                                               \
+# define YY_DECL                                                \
   int yylex (YYSTYPE* yylval, yy::location* yylloc, calcxx_driver& driver)
 // ... and declare it for the parser's sake.
 YY_DECL;
@@ -7069,6 +7077,7 @@
 The @code{calcxx_driver} class is then declared with its most obvious
 members.
 
address@hidden file: calc++-driver.hh
 @example
 // Conducting the whole scanning and parsing of Calc++.
 class calcxx_driver
@@ -7087,6 +7096,7 @@
 have two members function to open and close the scanning phase.
 members.
 
address@hidden file: calc++-driver.hh
 @example
   // Handling the scanner.
   void scan_begin ();
@@ -7097,6 +7107,7 @@
 @noindent
 Similarly for the parser itself.
 
address@hidden file: calc++-driver.hh
 @example
   // Handling the parser.
   void parse (const std::string& f);
@@ -7110,6 +7121,7 @@
 compiler driver using the following two member functions.  Finally, we
 close the class declaration and CPP guard.
 
address@hidden file: calc++-driver.hh
 @example
   // Error handling.
   void error (const yy::location& l, const std::string& m);
@@ -7123,6 +7135,7 @@
 are simple stubs, they should actually register the located error
 messages and set error state.
 
address@hidden file: calc++-driver.cc
 @example
 #include "calc++-driver.hh"
 #include "calc++-parser.hh"
@@ -7169,6 +7182,8 @@
 for the C++ skeleton, the creation of the parser header file, and
 specifies the name of the parser class.  It then includes the required
 headers.
+
address@hidden file: calc++-parser.yy
 @example
 %skeleton "lalr1.cc"                          /*  -*- C++ -*- */
 %define "parser_class_name" "calcxx_parser"
@@ -7184,6 +7199,7 @@
 This provides a simple but effective pure interface, not relying on
 global variables.
 
address@hidden file: calc++-parser.yy
 @example
 // The parsing context.
 %parse-param @{ calcxx_driver& driver @}
@@ -7196,6 +7212,7 @@
 relatively to the previous locations: the file name will be
 automatically propagated.
 
address@hidden file: calc++-parser.yy
 @example
 %locations
 %initial-action
@@ -7209,6 +7226,7 @@
 Use the two following directives to enable parser tracing and verbose
 error messages.
 
address@hidden file: calc++-parser.yy
 @example
 %debug
 %error-verbose
@@ -7218,6 +7236,7 @@
 Semantic values cannot use ``real'' objects, but only pointers to
 them.
 
address@hidden file: calc++-parser.yy
 @example
 // Symbols.
 %union
@@ -7234,6 +7253,7 @@
 symbol.  Note that the tokens names are prefixed by @code{TOKEN_} to
 avoid name clashes.
 
address@hidden file: calc++-parser.yy
 @example
 %token        YYEOF          0 "end of file"
 %token        TOKEN_ASSIGN     ":="
@@ -7246,6 +7266,7 @@
 To enable memory deallocation during error recovery, use
 @code{%destructor}.
 
address@hidden file: calc++-parser.yy
 @example
 %printer    @{ debug_stream () << *$$; @} "identifier"
 %destructor @{ delete $$; @} "identifier"
@@ -7256,6 +7277,7 @@
 @noindent
 The grammar itself is straightforward.
 
address@hidden file: calc++-parser.yy
 @example
 %%
 %start unit;
@@ -7281,9 +7303,11 @@
 Finally the @code{error} member function registers the errors to the
 driver.
 
address@hidden file: calc++-parser.yy
 @example
 void
-yy::calcxx_parser::error (const location_type& l, const std::string& m)
+yy::calcxx_parser::error (const yy::calcxx_parser::location_type& l,
+                          const std::string& m)
 @{
   driver.error (l, m);
 @}
@@ -7295,6 +7319,7 @@
 The Flex scanner first includes the driver declaration, then the
 parser's to get the set of defined tokens.
 
address@hidden file: calc++-scanner.ll
 @example
 address@hidden                                            /* -*- C++ -*- */
 # include <string>
@@ -7309,6 +7334,7 @@
 actual file, this is not an interactive session with the user.
 Finally we enable the scanner tracing features.
 
address@hidden file: calc++-scanner.ll
 @example
 %option noyywrap nounput batch debug
 @end example
@@ -7316,6 +7342,7 @@
 @noindent
 Abbreviations allow for more readable rules.
 
address@hidden file: calc++-scanner.ll
 @example
 id    [a-zA-Z][a-zA-Z_0-9]*
 int   [0-9]+
@@ -7331,6 +7358,7 @@
 is moved onto the end cursor to effectively ignore the blanks
 preceding tokens.  Comments would be treated equally.
 
address@hidden file: calc++-scanner.ll
 @example
 %%
 address@hidden
@@ -7345,6 +7373,7 @@
 The rules are simple, just note the use of the driver to report
 errors.
 
address@hidden file: calc++-scanner.ll
 @example
 [-+*/]     return yytext[0];
 ":="       return TOKEN_ASSIGN;
@@ -7358,6 +7387,7 @@
 Finally, because the scanner related driver's member function depend
 on the scanner's data, it is simpler to implement them in this file.
 
address@hidden file: calc++-scanner.ll
 @example
 void
 calcxx_driver::scan_begin ()
@@ -7379,6 +7409,7 @@
 
 The top level file, @file{calc++.cc}, poses no problem.
 
address@hidden file: calc++.cc
 @example
 #include <iostream>
 #include "calc++-driver.hh"
Index: examples/extexi
===================================================================
RCS file: examples/extexi
diff -N examples/extexi
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ examples/extexi 5 Jul 2005 07:21:18 -0000
@@ -0,0 +1,133 @@
+# Extract all examples from the manual source.            -*- AWK -*-
+
+# This file is part of GNU M4
+# Copyright 1992, 2000, 2001 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307  USA
+
+# This script is for use with any New AWK.
+# Well, now it uses ARGV/ARGC, and I don't know if it's New AWK portable.
+#
+# Usage: extexi input-file.texi ... -- [FILES to extract]
+BEGIN {
+  if (!output_dir)
+    output_dir = ".";
+  for (argc = 1; argc < ARGC; ++argc)
+    if (ARGV[argc] == "--")
+      break;
+  for (i = argc + 1; i < ARGC; ++i)
+    file_wanted[ARGV[i]] = 1;
+  ARGC = argc;
+}
+
+/address@hidden / {
+  if (seq > 0)
+    print "AT_CLEANUP";
+
+  split ($0, tmp, ",");
+  node = substr(tmp[1], 7);
+  seq = 0;
+}
+
+/address@hidden file: / {
+  if (!file_wanted[$3])
+    message("ignoring " $3);
+  else
+    {
+      message("extracting " $3);
+      file = $3;
+    }
+}
+
+/address@hidden/, /address@hidden example$/ {
+  if (!file)
+    next;
+
+  if ($0 ~ /address@hidden/)
+    {
+      input = files_output[file] ? "\n" : "";
+
+      # FNR is starting at 0 instead of 1, and
+      # #line report the line number of the *next* line.
+      # => + 2.
+      # Note that recent Bison support it, but not Flex.
+      if (file ~ /\.[chy]*$/)
+       input = "#line " (FNR + 1) " \"" FILENAME "\"\n";
+      next;
+    }
+
+  if ($0 ~ /address@hidden example$/)
+    {
+      if (input == "")
+       fatal("no contents: " file);
+
+      input = normalize(input);
+      # No spurious end of line: use printf.
+      if (files_output[file])
+       printf ("%s", input) >> output_dir "/" file;
+      else
+       printf ("%s", input) > output_dir "/" file;
+      close (output_dir "/" file);
+      files_output[file] = 1;
+
+      file = input = "";
+      next;
+    }
+
+  input = input $0 "\n";
+}
+
+
+# We have to handle CONTENTS line per line, since anchors in AWK are
+# referring to the whole string, not the lines.
+function normalize(contents,    i, lines, n, line, res) {
+  # Remove the Texinfo tags.
+  n = split (contents, lines, "\n");
+  # We don't want the last field which empty: it's behind the last \n.
+  for (i = 1; i < n; ++i)
+    {
+      line = lines[i];
+
+      # Whole line commands.
+      if (line ~ /^@(c |comment|dots|end (ignore|group)|ignore|group)/)
+       # Gperf accepts empty lines as valid input!!!
+       if (file ~ /\.gperf$/)
+         continue;
+       else
+         line = "";
+
+      gsub (/address@hidden/, "", line);
+      gsub (/address@hidden/,  "", line);
+      gsub ("@[{]", "{", line);
+      gsub ("@}", "}", line);
+      gsub ("@@", "@", line);
+      gsub ("@comment.*", "", line);
+
+      res = res line "\n";
+    }
+  return res;
+}
+
+
+function message(msg) {
+  # FNR starts at 0 instead of 1 for line numbers.
+  print "extexi: " FILENAME ":" (FNR + 1) ": " msg > "/dev/stderr";
+}
+
+function fatal(msg) {
+  message(msg);
+  exit 1
+}
Index: examples/calc++/Makefile
===================================================================
RCS file: /cvsroot/bison/bison/examples/calc++/Makefile,v
retrieving revision 1.1
diff -u -u -r1.1 Makefile
--- examples/calc++/Makefile 22 Jun 2005 15:32:10 -0000 1.1
+++ examples/calc++/Makefile 5 Jul 2005 07:21:18 -0000
@@ -13,3 +13,23 @@
              calc++-parser.cc calc++-parser.hh \
              calc++-scanner.cc \
              calc++
+
+## ------------ ##
+## Extracting.  ##
+## ------------ ##
+
+EXTRACTED = \
+calc++-driver.hh calc++-driver.cc \
+calc++-parser.yy \
+calc++-scanner.ll \
+calc++.cc
+
+doc = ../../doc/bison.texinfo
+extexi = gawk -f ../extexi
+
+RECURSIVE_TARGETS += extract
+
+$(EXTRACTED): $(doc) ../extexi
+       $(extexi) $(doc) -- $(EXTRACTED)
+
+extract extract-am: $(EXTRACTED)
Index: examples/calc++/calc++-driver.cc
===================================================================
RCS file: /cvsroot/bison/bison/examples/calc++/calc++-driver.cc,v
retrieving revision 1.1
diff -u -u -r1.1 calc++-driver.cc
--- examples/calc++/calc++-driver.cc 22 Jun 2005 15:32:10 -0000 1.1
+++ examples/calc++/calc++-driver.cc 5 Jul 2005 07:21:18 -0000
@@ -1,9 +1,9 @@
+#line 7140 "../../doc/bison.texinfo"
 #include "calc++-driver.hh"
 #include "calc++-parser.hh"
 
 calcxx_driver::calcxx_driver ()
-  : trace_scanning (false),
-    trace_parsing (false)
+  : trace_scanning (false), trace_parsing (false)
 {
   variables["one"] = 1;
   variables["two"] = 2;
Index: examples/calc++/calc++-driver.hh
===================================================================
RCS file: /cvsroot/bison/bison/examples/calc++/calc++-driver.hh,v
retrieving revision 1.1
diff -u -u -r1.1 calc++-driver.hh
--- examples/calc++/calc++-driver.hh 22 Jun 2005 15:32:10 -0000 1.1
+++ examples/calc++/calc++-driver.hh 5 Jul 2005 07:21:18 -0000
@@ -1,64 +1,47 @@
+#line 7036 "../../doc/bison.texinfo"
 #ifndef CALCXX_DRIVER_HH
 # define CALCXX_DRIVER_HH
 # include <string>
 # include <map>
-
-/// Forward declarations.
+#line 7051 "../../doc/bison.texinfo"
+// Forward declarations.
 union YYSTYPE;
-
 namespace yy
 {
-  class calcxx_parser;
   class location;
+  class calcxx_parser;
 }
-
 class calcxx_driver;
-
+#line 7069 "../../doc/bison.texinfo"
 // Announce to Flex the prototype we want for lexing function, ...
-# define YY_DECL                                               \
+# define YY_DECL                                                \
   int yylex (YYSTYPE* yylval, yy::location* yylloc, calcxx_driver& driver)
 // ... and declare it for the parser's sake.
 YY_DECL;
-
-/// Conducting the whole scanning and parsing of Calc++.
+#line 7082 "../../doc/bison.texinfo"
+// Conducting the whole scanning and parsing of Calc++.
 class calcxx_driver
 {
 public:
   calcxx_driver ();
   virtual ~calcxx_driver ();
 
-  /// The variables.
   std::map<std::string, int> variables;
 
-  /// \name Handling the scanner.
-  /// \{
-  /// Open \a file for scanning.
+  int result;
+#line 7101 "../../doc/bison.texinfo"
+  // Handling the scanner.
   void scan_begin ();
-  /// End scanning, clean up memory.
   void scan_end ();
-  /// Whether to enable scanner traces.
   bool trace_scanning;
-  /// \}
-
-  /// \name Handling the parser.
-  /// \{
-  /// Parse the file \a f.
+#line 7112 "../../doc/bison.texinfo"
+  // Handling the parser.
   void parse (const std::string& f);
-  /// The file being parsed.
   std::string file;
-  /// Whether to enable parsing traces.
   bool trace_parsing;
-  /// \}
-
-  /// The result.
-  int result;
-
-  /// \name Error handling.
-  /// \{
-  /// Register a located error.
+#line 7126 "../../doc/bison.texinfo"
+  // Error handling.
   void error (const yy::location& l, const std::string& m);
-  /// Register an error.
   void error (const std::string& m);
-  /// \}
 };
-#endif
+#endif // ! CALCXX_DRIVER_HH
Index: examples/calc++/calc++-parser.yy
===================================================================
RCS file: /cvsroot/bison/bison/examples/calc++/calc++-parser.yy,v
retrieving revision 1.1
diff -u -u -r1.1 calc++-parser.yy
--- examples/calc++/calc++-parser.yy 22 Jun 2005 15:32:10 -0000 1.1
+++ examples/calc++/calc++-parser.yy 5 Jul 2005 07:21:18 -0000
@@ -1,48 +1,44 @@
-%skeleton "lalr1.cc"                                  /*  -*- C++ -*- */
+#line 7188 "../../doc/bison.texinfo"
+%skeleton "lalr1.cc"                          /*  -*- C++ -*- */
 %define "parser_class_name" "calcxx_parser"
 %defines
 %{
 # include <string>
 # include "calc++-driver.hh"
 %}
-
-%error-verbose
-
+#line 7204 "../../doc/bison.texinfo"
 // The parsing context.
 %parse-param { calcxx_driver& driver }
 %lex-param   { calcxx_driver& driver }
-
+#line 7217 "../../doc/bison.texinfo"
 %locations
 %initial-action
 {
   // Initialize the initial location.
   @$.begin.filename = @$.end.filename = &driver.file;
 };
-
-// Define yydebug.
+#line 7231 "../../doc/bison.texinfo"
 %debug
-
+%error-verbose
+#line 7241 "../../doc/bison.texinfo"
 // Symbols.
-
 %union
 {
-  /// Value of a numeric literal.
   int          ival;
-  /// Name of a variable.
   std::string *sval;
 };
-
+#line 7258 "../../doc/bison.texinfo"
 %token        YYEOF          0 "end of file"
 %token        TOKEN_ASSIGN     ":="
 %token <sval> TOKEN_IDENTIFIER "identifier"
 %token <ival> TOKEN_NUMBER     "number"
 %type  <ival> exp              "expression"
-
+#line 7271 "../../doc/bison.texinfo"
 %printer    { debug_stream () << *$$; } "identifier"
 %destructor { delete $$; } "identifier"
 
 %printer    { debug_stream () << $$; } "number" "expression"
-
+#line 7282 "../../doc/bison.texinfo"
 %%
 %start unit;
 unit: assignments exp  { driver.result = $2; };
@@ -61,8 +57,10 @@
    | TOKEN_IDENTIFIER  { $$ = driver.variables[*$1]; }
    | TOKEN_NUMBER      { $$ = $1; };
 %%
+#line 7308 "../../doc/bison.texinfo"
 void
-yy::calcxx_parser::error (const location& l, const std::string& m)
+yy::calcxx_parser::error (const yy::calcxx_parser::location_type& l,
+                          const std::string& m)
 {
   driver.error (l, m);
 }
Index: examples/calc++/calc++-scanner.ll
===================================================================
RCS file: /cvsroot/bison/bison/examples/calc++/calc++-scanner.ll,v
retrieving revision 1.1
diff -u -u -r1.1 calc++-scanner.ll
--- examples/calc++/calc++-scanner.ll 22 Jun 2005 15:32:10 -0000 1.1
+++ examples/calc++/calc++-scanner.ll 5 Jul 2005 07:21:18 -0000
@@ -1,33 +1,28 @@
-%{                                                            /* -*- C++ -*- */
-
+%{                                            /* -*- C++ -*- */
 # include <string>
-# include <cerrno>
 # include "calc++-driver.hh"
 # include "calc++-parser.hh"
 %}
 
-%option noyywrap nounput debug batch
+%option noyywrap nounput batch debug
 
 id    [a-zA-Z][a-zA-Z_0-9]*
 int   [0-9]+
 blank [ \t]
 
 %%
-
 %{
-# define YY_USER_ACTION  yylloc->columns (yyleng);
   yylloc->step ();
+# define YY_USER_ACTION  yylloc->columns (yyleng);
 %}
 {blank}+   yylloc->step ();
 [\n]+      yylloc->lines (yyleng); yylloc->step ();
 
-
 [-+*/]     return yytext[0];
 ":="       return TOKEN_ASSIGN;
 {int}      yylval->ival = atoi (yytext); return TOKEN_NUMBER;
 {id}       yylval->sval = new std::string (yytext); return TOKEN_IDENTIFIER;
 .          driver.error (*yylloc, "invalid character");
-
 %%
 
 void
Index: examples/calc++/calc++.cc
===================================================================
RCS file: /cvsroot/bison/bison/examples/calc++/calc++.cc,v
retrieving revision 1.1
diff -u -u -r1.1 calc++.cc
--- examples/calc++/calc++.cc 22 Jun 2005 15:32:10 -0000 1.1
+++ examples/calc++/calc++.cc 5 Jul 2005 07:21:18 -0000
@@ -1,3 +1,4 @@
+#line 7414 "../../doc/bison.texinfo"
 #include <iostream>
 #include "calc++-driver.hh"
 





reply via email to

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