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.
}
| "%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"
{
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;
}
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;
}
}
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_ */
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, [],