From 1c292035e12d4c2c782f1dba6f78e690ad5635b3 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 27 Jul 2012 12:47:02 +0200 Subject: [PATCH] printer/destructor: translate only once 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 eb034b08..e6a27c50 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 0a5bb996..c8d554d5 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 bf47da1e..69ac8a1b 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 43936b29..63577f79 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 6b90b21e..ff1d3924 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, [], -- 2.47.2