bison-patches
[Top][All Lists]
Advanced

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

[PATCH 4/5] printer/destructor: translate only once


From: Akim Demaille
Subject: [PATCH 4/5] printer/destructor: translate only once
Date: Fri, 27 Jul 2012 17:13:34 +0200

Currently "%printer {...} a b c d e f" translates the {...} six times.
Not only is this bad for time and space, it also issues six times the
same warnings.

* src/symlist.h, src/symlist.c (symbol_list_destructor_set)
(symbol_list_printer_set): Take the action as code_props instead of
const char *.
* src/parse-gram.y: Translate these actions here.
* src/scan-code.h: Comment change.
* tests/input.at: Check that warnings are issued only once.
---
 src/parse-gram.y | 26 ++++++++++++++++++--------
 src/scan-code.h  |  5 ++++-
 src/symlist.c    | 26 ++++++++++----------------
 src/symlist.h    |  8 ++++----
 tests/input.at   |  9 ++++++---
 5 files changed, 42 insertions(+), 32 deletions(-)

diff --git a/src/parse-gram.y b/src/parse-gram.y
index eb034b0..e6a27c5 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -347,17 +347,27 @@ grammar_declaration:
     }
 | "%destructor" "{...}" generic_symlist
     {
-      symbol_list *list;
-      for (list = $3; list; list = list->next)
-       symbol_list_destructor_set (list, $2, @2);
-      symbol_list_free ($3);
+      code_props code;
+      code_props_symbol_action_init (&code, $2, @2);
+      code_props_translate_code (&code);
+      {
+        symbol_list *list;
+        for (list = $3; list; list = list->next)
+          symbol_list_destructor_set (list, &code);
+        symbol_list_free ($3);
+      }
     }
 | "%printer" "{...}" generic_symlist
     {
-      symbol_list *list;
-      for (list = $3; list; list = list->next)
-       symbol_list_printer_set (list, $2, @2);
-      symbol_list_free ($3);
+      code_props code;
+      code_props_symbol_action_init (&code, $2, @2);
+      code_props_translate_code (&code);
+      {
+        symbol_list *list;
+        for (list = $3; list; list = list->next)
+          symbol_list_printer_set (list, &code);
+        symbol_list_free ($3);
+      }
     }
 | "%default-prec"
     {
diff --git a/src/scan-code.h b/src/scan-code.h
index 0a5bb99..c8d554d 100644
--- a/src/scan-code.h
+++ b/src/scan-code.h
@@ -45,7 +45,10 @@ typedef struct code_props {
     CODE_PROPS_SYMBOL_ACTION, CODE_PROPS_RULE_ACTION
   } kind;
 
-  /** \c NULL iff \c code_props::kind is \c CODE_PROPS_NONE.  */
+  /**
+   * \c NULL iff \c code_props::kind is \c CODE_PROPS_NONE.
+   * Memory is allocated in an obstack freed elsewhere.
+   */
   char const *code;
   /** Undefined iff \c code_props::code is \c NULL.  */
   location location;
diff --git a/src/symlist.c b/src/symlist.c
index bf47da1..69ac8a1 100644
--- a/src/symlist.c
+++ b/src/symlist.c
@@ -223,49 +223,43 @@ symbol_list_null (symbol_list *node)
 }
 
 void
-symbol_list_destructor_set (symbol_list *node, char const *code, location loc)
+symbol_list_destructor_set (symbol_list *node, code_props const *destructor)
 {
-  code_props destructor;
-  code_props_symbol_action_init (&destructor, code, loc);
-  code_props_translate_code (&destructor);
   switch (node->content_type)
     {
       case SYMLIST_SYMBOL:
-        symbol_destructor_set (node->content.sym, &destructor);
+        symbol_destructor_set (node->content.sym, destructor);
         break;
       case SYMLIST_TYPE:
         semantic_type_destructor_set (
-          semantic_type_get (node->content.type_name), &destructor);
+          semantic_type_get (node->content.type_name), destructor);
         break;
       case SYMLIST_DEFAULT_TAGGED:
-        default_tagged_destructor_set (&destructor);
+        default_tagged_destructor_set (destructor);
         break;
       case SYMLIST_DEFAULT_TAGLESS:
-        default_tagless_destructor_set (&destructor);
+        default_tagless_destructor_set (destructor);
         break;
     }
 }
 
 void
-symbol_list_printer_set (symbol_list *node, char const *code, location loc)
+symbol_list_printer_set (symbol_list *node, code_props const *printer)
 {
-  code_props printer;
-  code_props_symbol_action_init (&printer, code, loc);
-  code_props_translate_code (&printer);
   switch (node->content_type)
     {
       case SYMLIST_SYMBOL:
-        symbol_printer_set (node->content.sym, &printer);
+        symbol_printer_set (node->content.sym, printer);
         break;
       case SYMLIST_TYPE:
         semantic_type_printer_set (
-          semantic_type_get (node->content.type_name), &printer);
+          semantic_type_get (node->content.type_name), printer);
         break;
       case SYMLIST_DEFAULT_TAGGED:
-        default_tagged_printer_set (&printer);
+        default_tagged_printer_set (printer);
         break;
       case SYMLIST_DEFAULT_TAGLESS:
-        default_tagless_printer_set (&printer);
+        default_tagless_printer_set (printer);
         break;
     }
 }
diff --git a/src/symlist.h b/src/symlist.h
index 43936b2..63577f7 100644
--- a/src/symlist.h
+++ b/src/symlist.h
@@ -119,11 +119,11 @@ uniqstr symbol_list_n_type_name_get (symbol_list *l, 
location loc, int n);
 bool symbol_list_null (symbol_list *node);
 
 /** Set the \c \%destructor for \c node as \c code at \c loc.  */
-void symbol_list_destructor_set (symbol_list *node, char const *code,
-                                 location loc);
+void symbol_list_destructor_set (symbol_list *node,
+                                 code_props const *destructor);
 
 /** Set the \c \%printer for \c node as \c code at \c loc.  */
-void symbol_list_printer_set (symbol_list *node, char const *code,
-                              location loc);
+void symbol_list_printer_set (symbol_list *node,
+                              code_props const *printer);
 
 #endif /* !SYMLIST_H_ */
diff --git a/tests/input.at b/tests/input.at
index 6b90b21..ff1d392 100644
--- a/tests/input.at
+++ b/tests/input.at
@@ -1377,13 +1377,16 @@ AT_CLEANUP
 
 AT_SETUP([[Stray $ or @]])
 
+# Give %printer and %destructor "<*> exp TOK" instead of "<*>" to
+# check that the warnings are reported once, not three times.
+
 AT_DATA_GRAMMAR([[input.y]],
 [[%token TOK
-%destructor     { $%; @%; } <*>;
+%destructor     { $%; @%; } <*> exp TOK;
 %initial-action { $%; @%; };
-%printer        { $%; @%; } <*>;
+%printer        { $%; @%; } <*> exp TOK;
 %%
-exp: TOK        { $%; @%; };
+exp: TOK        { $%; @%; $$ = $1; };
 ]])
 
 AT_BISON_CHECK([[input.y]], 0, [],
-- 
1.7.11.3




reply via email to

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