bison-patches
[Top][All Lists]
Advanced

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

Preparing %printer


From: Akim Demaille
Subject: Preparing %printer
Date: 20 Jun 2002 11:07:43 +0200
User-agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Honest Recruiter)

Up to now, I have not tested %printer per se, but this is for a
forthcoming patch.  Still, I meant to first ensure YYPRINT backward
compatibility, and this does work.

Index: ChangeLog
from  Akim Demaille  <address@hidden>

        * src/symtab.h, src/symtab.c (symbol_t): printer and
        printer_location are new members.
        (symbol_printer_set): New.
        * src/parse-gram.y (PERCENT_PRINTER): New token.
        Handle its associated rule.
        * src/scan-gram.l: Adjust.
        (handle_destructor_at, handle_destructor_dollar): Rename as...
        (handle_symbol_code_at, handle_symbol_code_dollar): these.
        * src/output.c (symbol_printers_output): New.
        (output_skeleton): Call it.
        * data/bison.simple (yysymprint): New.  Cannot be named yyprint
        since there are already many grammar files with a user `yyprint'.
        Replace the calls to YYPRINT to calls to yysymprint.
        * tests/calc.at: Adjust.
        * tests/torture.at (AT_DATA_STACK_TORTURE): Remove YYPRINT: it was
        taking advantage of parser very internal details (stack size!).

Index: data/bison.simple
===================================================================
RCS file: /cvsroot/bison/bison/data/bison.simple,v
retrieving revision 1.41
diff -u -u -r1.41 bison.simple
--- data/bison.simple 19 Jun 2002 12:03:22 -0000 1.41
+++ data/bison.simple 20 Jun 2002 09:05:16 -0000
@@ -671,6 +671,10 @@
 #if defined (__STDC__) || defined (__cplusplus)
 static void yydestructor (int yytype,
                          YYSTYPE yyvalue[]b4_location_if([, YYLTYPE 
yylocation]));
+# if YYDEBUG
+static void yysymprint (FILE* out, int yytype,
+                       YYSTYPE yyvalue[]b4_location_if([, YYLTYPE 
yylocation]));
+# endif
 #endif
 
 m4_divert_push([KILL])# ======================== M4 code.
@@ -887,14 +891,9 @@
        which are defined only if `YYDEBUG' is set.  */
       if (yydebug)
        {
-         YYFPRINTF (stderr, "Next token is %d (%s",
-                    yychar, yytname[yychar1]);
-         /* Give the individual parser a way to print the precise
-            meaning of a token, for further debugging info.  */
-# ifdef YYPRINT
-         YYPRINT (stderr, yychar, yylval);
-# endif
-         YYFPRINTF (stderr, ")\n");
+         YYFPRINTF (stderr, "Next token is ");
+         yysymprint (stderr, yychar1, yylval]b4_location_if([, yyloc])[);
+         YYFPRINTF (stderr, "\n");
        }
 #endif
     }
@@ -1113,21 +1112,11 @@
 #if YYDEBUG
              if (yydebug)
                {
-                 if (yystos[*yyssp] < YYNTOKENS)
-                   {
-                     YYFPRINTF (stderr, "Error: popping token %d (%s",
-                                yytoknum[yystos[*yyssp]],
-                                yytname[yystos[*yyssp]]);
-# ifdef YYPRINT
-                     YYPRINT (stderr, yytoknum[yystos[*yyssp]], *yyvsp);
-# endif
-                     YYFPRINTF (stderr, ")\n");
-                   }
-                 else
-                   {
-                     YYFPRINTF (stderr, "Error: popping nonterminal (%s)\n",
-                                yytname[yystos[*yyssp]]);
-                   }
+                 YYFPRINTF (stderr, "Error: popping ");
+                 yysymprint (stderr,
+                             yystos[*yyssp],
+                             *yyvsp]b4_location_if([, *yylsp])[);
+                 YYFPRINTF (stderr, "\n");
                }
 #endif
              yydestructor (yystos[*yyssp], *yyvsp]b4_location_if([, *yylsp])[);
@@ -1168,20 +1157,11 @@
 #if YYDEBUG
       if (yydebug)
        {
-         if (yystos[yystate] < YYNTOKENS)
-           {
-             YYFPRINTF (stderr, "Error: popping token %d (%s",
-                        yytoknum[yystos[yystate]], yytname[yystos[yystate]]);
-# ifdef YYPRINT
-             YYPRINT (stderr, yytoknum[yystos[yystate]], *yyvsp);
-# endif
-             YYFPRINTF (stderr, ")\n");
-           }
-         else
-           {
-             YYFPRINTF (stderr, "Error: popping nonterminal (%s)\n",
-                        yytname[yystos[yystate]]);
-           }
+         YYFPRINTF (stderr, "Error: popping ");
+         yysymprint (stderr,
+                     yystos[*yyssp],
+                     *yyvsp]b4_location_if([, *yylsp])[);
+         YYFPRINTF (stderr, "\n");
        }
 #endif
 
@@ -1247,9 +1227,9 @@
 ]}
 
 
-/*-------------------------------------------------.
-| Release the memory associated to SYMBOL-NUMBER.  |
-`-------------------------------------------------*/
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
 
 m4_divert_push([KILL])# M4 code.
 # b4_symbol_destructor(SYMBOL-NUMBER, DESTRUCTOR, TYPE-NAME)
@@ -1274,11 +1254,52 @@
     {
 m4_map([b4_symbol_destructor], m4_defn([b4_symbol_destructors]))dnl
       default:
-        YYDPRINTF ((stderr, "yydestructor: unknown symbol type: %d (%s)\n",
-                   yytype, yytname[[yytype]]));
         break;
     }
 }
+
+
+#if YYDEBUG
+/*---------------------------.
+| Print this symbol on OUT.  |
+`---------------------------*/
+
+m4_divert_push([KILL])# M4 code.
+# b4_symbol_printer(SYMBOL-NUMBER, PRINTER, TYPE-NAME)
+# ----------------------------------------------------------
+m4_define([b4_symbol_printer],
+[m4_pushdef([b4_dollar_dollar], [yyvalue.$6])dnl
+m4_pushdef([b4_at_dollar], [yylocation])dnl
+      case $4: /* $3 */
+#line $2 "$1"
+        $5;
+#line __oline__ "__ofile__"
+        break;
+m4_popdef([b4_at_dollar])dnl
+m4_popdef([b4_dollar_dollar])])
+
+m4_divert_pop([KILL])dnl# End of M4 code.
+static void
+yysymprint (FILE* out, int yytype,
+           YYSTYPE yyvalue[]b4_location_if([, YYLTYPE yylocation]))
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (out, "token %d (%s ", yytoknum[[yytype]], yytname[[yytype]]);
+  else
+    YYFPRINTF (out, "nterm %s (", yytname[[yytype]]);
+# ifdef YYPRINT
+  YYPRINT (out, yytype, yyvalue);
+# else
+  switch (yytype)
+    {
+m4_map([b4_symbol_printer], m4_defn([b4_symbol_printers]))dnl
+      default:
+        break;
+    }
+# endif /* !defined YYPRINT. */
+  YYFPRINTF (out, ")");
+}
+#endif /* YYDEBUG. */
 
 b4_epilogue
 m4_if(b4_defines_flag, 0, [],
Index: src/output.c
===================================================================
RCS file: /cvsroot/bison/bison/src/output.c,v
retrieving revision 1.166
diff -u -u -r1.166 output.c
--- src/output.c 18 Jun 2002 09:55:35 -0000 1.166
+++ src/output.c 20 Jun 2002 09:05:16 -0000
@@ -639,6 +639,39 @@
 }
 
 
+/*-------------------------------------.
+| Output the symbol printers to OOUT.  |
+`-------------------------------------*/
+
+static void
+symbol_printers_output (FILE *out)
+{
+  int i;
+  int first = 1;
+
+  fputs ("m4_define([b4_symbol_printers], \n[", out);
+  for (i = 0; i < nsyms; ++i)
+    if (symbols[i]->destructor)
+      {
+       symbol_t *symbol = symbols[i];
+
+       /* Filename, lineno,
+          Symbol-name, Symbol-number,
+          destructor, typename. */
+       fprintf (out, "%s[[[%s]], [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
+                first ? "" : ",\n",
+                infile, symbol->printer_location.first_line,
+                symbol_tag_get (symbol),
+                symbol->number,
+                symbol->printer,
+                symbol->type_name);
+
+       first = 0;
+      }
+  fputs ("])\n\n", out);
+}
+
+
 static void
 save_column (int symbol, int default_state)
 {
@@ -1053,6 +1086,7 @@
   actions_output (out);
   token_definitions_output (out);
   symbol_destructors_output (out);
+  symbol_printers_output (out);
 
   muscles_m4_output (out);
 
Index: src/parse-gram.y
===================================================================
RCS file: /cvsroot/bison/bison/src/parse-gram.y,v
retrieving revision 1.12
diff -u -u -r1.12 parse-gram.y
--- src/parse-gram.y 17 Jun 2002 08:43:11 -0000 1.12
+++ src/parse-gram.y 20 Jun 2002 09:05:16 -0000
@@ -103,9 +103,13 @@
 
 %token PERCENT_TOKEN       "%token"
 %token PERCENT_NTERM       "%nterm"
+
 %token PERCENT_TYPE        "%type"
 %token PERCENT_DESTRUCTOR  "%destructor"
+%token PERCENT_PRINTER     "%printer"
+
 %token PERCENT_UNION       "%union"
+
 %token PERCENT_LEFT        "%left"
 %token PERCENT_RIGHT       "%right"
 %token PERCENT_NONASSOC    "%nonassoc"
@@ -209,6 +213,16 @@
       symbol_list_t *list;
       for (list = $4; list; list = list->next)
        symbol_destructor_set (list->sym, list->location, $3);
+      symbol_list_free ($4);
+      current_braced_code = action_braced_code;
+    }
+| "%printer"
+    { current_braced_code = printer_braced_code; }
+  BRACED_CODE symbols.1
+    {
+      symbol_list_t *list;
+      for (list = $4; list; list = list->next)
+       symbol_printer_set (list->sym, $3, list->location);
       symbol_list_free ($4);
       current_braced_code = action_braced_code;
     }
Index: src/reader.h
===================================================================
RCS file: /cvsroot/bison/bison/src/reader.h,v
retrieving revision 1.22
diff -u -u -r1.22 reader.h
--- src/reader.h 17 Jun 2002 08:43:11 -0000 1.22
+++ src/reader.h 20 Jun 2002 09:05:16 -0000
@@ -52,7 +52,8 @@
 typedef enum braced_code_e
   {
     action_braced_code,
-    destructor_braced_code
+    destructor_braced_code,
+    printer_braced_code
   } braced_code_t;
 /* FIXME: This is really a dirty hack which demonstrates that we
    should probably not try to parse the actions now.  */
Index: src/scan-gram.l
===================================================================
RCS file: /cvsroot/bison/bison/src/scan-gram.l,v
retrieving revision 1.13
diff -u -u -r1.13 scan-gram.l
--- src/scan-gram.l 20 Jun 2002 07:19:13 -0000 1.13
+++ src/scan-gram.l 20 Jun 2002 09:05:16 -0000
@@ -136,6 +136,7 @@
   "%nterm"                return PERCENT_NTERM;
   "%output"               return PERCENT_OUTPUT;
   "%prec"                 return PERCENT_PREC;
+  "%printer"              return PERCENT_PRINTER;
   "%pure"[-_]"parser"     return PERCENT_PURE_PARSER;
   "%right"                return PERCENT_RIGHT;
   "%skeleton"             return PERCENT_SKELETON;
@@ -524,7 +525,7 @@
 %%
 
 /*------------------------------------------------------------------.
-| CP is pointing to a wannabee semantic value (i.e., a `$').        |
+| TEXT is pointing to a wannabee semantic value (i.e., a `$').      |
 |                                                                   |
 | Possible inputs: $[<TYPENAME>]($|integer)                         |
 |                                                                   |
@@ -532,11 +533,10 @@
 `------------------------------------------------------------------*/
 
 static inline void
-handle_action_dollar (char *cp, location_t location)
+handle_action_dollar (char *text, location_t location)
 {
   const char *type_name = NULL;
-
-  ++cp;
+  char *cp = text + 1;
 
   /* Get the type name if explicit. */
   if (*cp == '<')
@@ -588,31 +588,24 @@
     }
   else
     {
-      char buf[] = "$c";
-      buf[1] = *cp;
-      complain_at (location, _("%s is invalid"), quote (buf));
+      complain_at (location, _("%s is invalid"), quote (text));
     }
 }
 
 
-/*---------------------------------------.
-| CP is pointing to $$ in a destructor.  |
-`---------------------------------------*/
+/*---------------------------------------------------------------.
+| TEXT is expexted tp be $$ in some code associated to a symbol: |
+| destructor or printer.                                         |
+`---------------------------------------------------------------*/
 
 static inline void
-handle_destructor_dollar (char *cp, location_t location)
+handle_symbol_code_dollar (char *text, location_t location)
 {
-  ++cp;
+  char *cp = text + 1;
   if (*cp == '$')
-    {
-      obstack_sgrow (&string_obstack, "]b4_dollar_dollar[");
-    }
+    obstack_sgrow (&string_obstack, "]b4_dollar_dollar[");
   else
-    {
-      char buf[] = "$c";
-      buf[1] = *cp;
-      complain_at (location, _("%s is invalid"), quote (buf));
-    }
+    complain_at (location, _("%s is invalid"), quote (text));
 }
 
 
@@ -632,7 +625,8 @@
       break;
 
     case destructor_braced_code:
-      handle_destructor_dollar (text, location);
+    case printer_braced_code:
+      handle_symbol_code_dollar (text, location);
       break;
     }
 }
@@ -646,21 +640,21 @@
 static inline void
 handle_action_at (char *text, location_t location)
 {
+  char *cp = text + 1;
   locations_flag = 1;
-  ++text;
 
-  if (*text == '$')
+  if (*cp == '$')
     {
       obstack_sgrow (&string_obstack, "]b4_lhs_location[");
     }
-  else if (isdigit (*text) || *text == '-')
+  else if (isdigit (*cp) || *cp == '-')
     {
       /* RULE_LENGTH is the number of values in the current rule so
         far, which says where to find `$0' with respect to the top of
         the stack.  It is not the same as the rule->length in the
         case of mid rule actions.  */
       int rule_length = symbol_list_length (current_rule->next);
-      int n = strtol (text, &text, 10);
+      int n = strtol (cp, &cp, 10);
 
       if (n > rule_length)
        complain_at (location, _("invalid value: %s%d"), "@", n);
@@ -670,31 +664,24 @@
     }
   else
     {
-      char buf[] = "@c";
-      buf[1] = *text;
-      complain_at (location, _("%s is invalid"), quote (buf));
+      complain_at (location, _("%s is invalid"), quote (text));
     }
 }
 
 
-/*--------------------------------------------.
-| TEXT is expexted tp be @$ in a destructor.  |
-`--------------------------------------------*/
+/*---------------------------------------------------------------.
+| TEXT is expexted tp be @$ in some code associated to a symbol: |
+| destructor or printer.                                         |
+`---------------------------------------------------------------*/
 
 static inline void
-handle_destructor_at (char *text, location_t location)
+handle_symbol_code_at (char *text, location_t location)
 {
-  ++text;
-  if (*text == '$')
-    {
-      obstack_sgrow (&string_obstack, "]b4_at_dollar[");
-    }
+  char *cp = text + 1;
+  if (*cp == '$')
+    obstack_sgrow (&string_obstack, "]b4_at_dollar[");
   else
-    {
-      char buf[] = "$c";
-      buf[1] = *text;
-      complain_at (location, _("%s is invalid"), quote (buf));
-    }
+    complain_at (location, _("%s is invalid"), quote (text));
 }
 
 
@@ -714,7 +701,8 @@
       break;
 
     case destructor_braced_code:
-      handle_destructor_at (text, location);
+    case printer_braced_code:
+      handle_symbol_code_at (text, location);
       break;
     }
 }
Index: src/symtab.c
===================================================================
RCS file: /cvsroot/bison/bison/src/symtab.c,v
retrieving revision 1.36
diff -u -u -r1.36 symtab.c
--- src/symtab.c 18 Jun 2002 09:55:35 -0000 1.36
+++ src/symtab.c 20 Jun 2002 09:05:16 -0000
@@ -118,8 +118,7 @@
 
 
 /*-------------------------------------------------------------------.
-| Set the DESTRUCTOR associated to SYMBOL.  Does nothing if passed 0 |
-| as DESTRUCTOR.                                                      |
+| Set the DESTRUCTOR associated to SYMBOL.  Do nothing if passed 0.  |
 `-------------------------------------------------------------------*/
 
 void
@@ -129,10 +128,29 @@
     {
       if (symbol->destructor)
        complain_at (location,
-                    _("destructor redeclaration for %s"),
-                    symbol_tag_get (symbol));
+                    _("%s redeclaration for %s"),
+                    "%destructor", symbol_tag_get (symbol));
       symbol->destructor = destructor;
       symbol->destructor_location = location;
+    }
+}
+
+
+/*----------------------------------------------------------------.
+| Set the PRITNER associated to SYMBOL.  Do nothing if passed 0.  |
+`----------------------------------------------------------------*/
+
+void
+symbol_printer_set (symbol_t *symbol, char *printer, location_t location)
+{
+  if (printer)
+    {
+      if (symbol->printer)
+       complain_at (location,
+                    _("%s redeclaration for %s"),
+                    "%printer", symbol_tag_get (symbol));
+      symbol->printer = printer;
+      symbol->printer_location = location;
     }
 }
 
Index: src/symtab.h
===================================================================
RCS file: /cvsroot/bison/bison/src/symtab.h,v
retrieving revision 1.36
diff -u -u -r1.36 symtab.h
--- src/symtab.h 18 Jun 2002 09:55:35 -0000 1.36
+++ src/symtab.h 20 Jun 2002 09:05:16 -0000
@@ -59,11 +59,12 @@
   /* The location of its first occurence.  */
   location_t location;
 
-  /* Its %type and associated destructor.  */
+  /* Its %type and associated printer and destructor.  */
   char *type_name;
   char *destructor;
   location_t destructor_location;
-
+  char *printer;
+  location_t printer_location;
 
   symbol_number_t number;
   short prec;
@@ -115,6 +116,10 @@
 /* Set the DESTRUCTOR associated to SYMBOL.  */
 void symbol_destructor_set PARAMS ((symbol_t *symbol, location_t location,
                                    char *destructor));
+
+/* Set the PRINTER associated to SYMBOL.  */
+void symbol_printer_set PARAMS ((symbol_t *symbol,
+                                char *printer, location_t location));
 
 /* Set the PRECEDENCE associated to SYMBOL.  Ensures that SYMBOL is a
    terminal.  Does nothing if invoked with UNDEF_ASSOC as ASSOC.  */
Index: tests/calc.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/calc.at,v
retrieving revision 1.24
diff -u -u -r1.24 calc.at
--- tests/calc.at 17 Jun 2002 08:43:12 -0000 1.24
+++ tests/calc.at 20 Jun 2002 09:05:16 -0000
@@ -415,40 +415,34 @@
 (2^2)^3 = 64], [486])
 
 # Some parse errors.
-_AT_CHECK_CALC_ERROR([$1], [0 0], [12],
+_AT_CHECK_CALC_ERROR([$1], [0 0], [11],
                      [1.3-1.4: parse error, unexpected "number"])
-_AT_CHECK_CALC_ERROR([$1], [1//2], [17],
+_AT_CHECK_CALC_ERROR([$1], [1//2], [15],
                      [1.3-1.4: parse error, unexpected '/', expecting "number" 
or '-' or '('])
 _AT_CHECK_CALC_ERROR([$1], [error], [4],
                      [1.1-1.2: parse error, unexpected $undefined., expecting 
"number" or '-' or '\n' or '('])
-_AT_CHECK_CALC_ERROR([$1], [1 = 2 = 3], [25],
+_AT_CHECK_CALC_ERROR([$1], [1 = 2 = 3], [22],
                      [1.7-1.8: parse error, unexpected '='])
 _AT_CHECK_CALC_ERROR([$1],
                      [
 +1],
-                     [15],
+                     [14],
                      [2.1-2.2: parse error, unexpected '+'])
 # Exercise error messages with EOF: work on an empty file.
-_AT_CHECK_CALC_ERROR([$1],
-                     [/dev/null],
-                     [4],
+_AT_CHECK_CALC_ERROR([$1], [/dev/null], [4],
                      [1.1-1.2: parse error, unexpected "end of file", 
expecting "number" or '-' or '\n' or '('])
 
 # Exercise the error token: without it, we die at the first error,
 # hence be sure i. to have several errors, ii. to test the action
 # associated to `error'.
-_AT_CHECK_CALC_ERROR([$1],
-                     [(1 ++ 2) + (0 0) = 1],
-                     [91],
+_AT_CHECK_CALC_ERROR([$1], [(1 ++ 2) + (0 0) = 1], [82],
 [1.5-1.6: parse error, unexpected '+', expecting "number" or '-' or '('
 1.15-1.16: parse error, unexpected "number"
 calc: error: 0 != 1])
 
 # Add a studid example demonstrating that Bison can further improve the
 # error message.  FIXME: Fix this ridiculous message.
-_AT_CHECK_CALC_ERROR([$1],
-                     [()],
-                     [21],
+_AT_CHECK_CALC_ERROR([$1], [()], [21],
 [1.2-1.3: parse error, unexpected ')', expecting error or "number" or '-' or 
'('])
 
 AT_CLEANUP
Index: tests/torture.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/torture.at,v
retrieving revision 1.16
diff -u -u -r1.16 torture.at
--- tests/torture.at 11 Jun 2002 20:16:05 -0000 1.16
+++ tests/torture.at 20 Jun 2002 09:05:17 -0000
@@ -371,9 +371,6 @@
 ]$1[
   static int yylex (void);
   static void yyerror (const char *msg);
-#define YYPRINT(File, Type, Value)                   \
-  fprintf (File, " (%d, stack size = %d, max = %d)", \
-           Value, yyssp - yyss + 1, yystacksize);
 %}
 %error-verbose
 %debug



reply via email to

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