Encapsulate code properties and related functionality for the various

destructors, printers, and actions into a code_props structure and
interface.
* src/location.h (EMPTY_LOCATION_INIT): Define so that it's easier to
consistently initialize const structs that have an empty location field.
* src/location.c (empty_location): Initialize with EMPTY_LOCATION_INIT
to ensure consistency.
* src/output.c (symbol_destructors_output, symbol_printers_output):
Replace with...
(symbol_code_props_output): ... this to eliminate duplicate code.
(output_skeleton): Update to use symbol_code_props_output.
* src/parse-gram.y (prologue_declaration, braceless, epilogue.opt):
Update all uses of translate_* functions to use the new code_props
interface and to use gram_scanner_last_string_free and
code_scanner_last_string_free where possible.
(grammar_declaration): symbol_list_destructor_set and
symbol_list_printer_set now perform the translation, so don't do it
here.  Use gram_scanner_last_string_free where possible.
* src/reader.c: Update to use code_props interface for destructors and
rule actions.
* src/scan-code.h (code_props): New structure.
(code_props_none_init, CODE_PROPS_NONE_INIT, code_props_none): New
function, macro, and const global variable for initializing a
code_props with no code.
(code_props_plain_init, code_props_symbol_action_init,
code_props_rule_action_init, code_props_translate_code,
code_props_code_get, code_props_location_get,
code_props_is_value_used): The rest of the new code_props interface.
(translate_rule_action, translate_symbol_action, translate_code):
Remove as these are now just special cases within
code_props_translate_code, which is switched on the code_props kind.
(code_scanner_last_string_free): New function similar to
gram_scanner_last_string_free.
* src/scan-code.l: Implement the new interface.
(last_string): New static global similar to the one in scan-gram.l.
(SC_SYMBOL_ACTION): For $$, set the is_value_used member of the
code_props since Bison will one day use this information for
destructors and printers.
(<*><<EOF>>): Use STRING_FINISH so that last_string is set.
(handle_action_dollar): Update to use the code_props interface of rule
actions.  Use symbol_list_n_get and set is_value_used directly since
symbol_list_n_used_set is removed.
* src/symlist.h, src/symlist.c (symbol_list): Replace action,
action_location, and used members with a code_props member, and update
all uses.
(symbol_list_n_used_set): Remove since it would need to break the
encapsulation of code_props.
(symbol_list_destructor_set, symbol_list_printer_set): Perform code
translation here rather than depending on the caller to do so.
* src/symtab.h (symbol, semantic_type): Remove destructor_location and
printer_location members and change the type of the destructor and
printer members to code_props.
(symbol_destructor_location_get, symbol_printer_location_get): Remove
unneeded.
(symbol_destructor_set, symbol_destructor_get, symbol_printer_set,
symbol_printer_get, semantic_type_destructor_set,
semantic_type_printer_set, default_tagged_destructor_set,
default_tagless_destructor_set, default_tagged_printer_set,
default_tagless_printer_set): Use code_props in arguments and return
types in place of const char * and location.
* src/symtab.c: Update implementation for interface and struct changes.
(default_tagged_destructor_location,
default_tagless_destructor_location, default_tagged_printer_location,
default_tagless_printer_location): Remove since we...
(default_tagged_destructor, default_tagless_destructor,
default_tagged_printer, default_tagless_printer): ... change the type
of these to code_props.
(SYMBOL_CODE_PRINT): New similar to SYMBOL_ATTR_PRINT but for
code_props members.
(symbol_print): Use SYMBOL_CODE_PRINT.

* src/scan-gram.h (gram_last_string): Remove declaration.
* src/scan-gram.l (last_string): Declare it static.
This commit is contained in:
Joel E. Denny
2006-11-11 06:57:39 +00:00
parent 405d53b724
commit 76290368d4
15 changed files with 739 additions and 464 deletions

View File

@@ -39,10 +39,11 @@
#include <quote.h>
#include "scan-code.h"
#include "symlist.h"
/* The current calling start condition: SC_RULE_ACTION or
SC_SYMBOL_ACTION. */
# define YY_DECL char *code_lex (int sc_context, symbol_list *rule)
# define YY_DECL static char *code_lex (code_props *self, int sc_context)
YY_DECL;
#define YY_USER_ACTION location_compute (loc, &loc->end, yytext, yyleng);
@@ -53,6 +54,9 @@ static void handle_action_at (symbol_list *rule, char *cp, location at_loc);
static location the_location;
static location *loc = &the_location;
/* A string representing the most recent translation. */
static char *last_string;
/* True if an untyped $$ or $n was seen. */
static bool untyped_var_seen;
%}
@@ -151,8 +155,12 @@ splice (\\[ \f\t\v]*\n)*
<SC_RULE_ACTION>
{
"$"("<"{tag}">")?(-?[0-9]+|"$") handle_action_dollar (rule, yytext, *loc);
"@"(-?[0-9]+|"$") handle_action_at (rule, yytext, *loc);
"$"("<"{tag}">")?(-?[0-9]+|"$") {
handle_action_dollar (self->rule, yytext, *loc);
}
"@"(-?[0-9]+|"$") {
handle_action_at (self->rule, yytext, *loc);
}
"$" {
warn_at (*loc, _("stray `$'"));
@@ -190,7 +198,10 @@ splice (\\[ \f\t\v]*\n)*
<SC_SYMBOL_ACTION>
{
"$$" obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
"$$" {
obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
self->is_value_used = true;
}
"@$" obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
}
@@ -215,8 +226,8 @@ splice (\\[ \f\t\v]*\n)*
/* End of processing. */
<*><<EOF>> {
obstack_1grow (&obstack_for_string, '\0');
return obstack_finish (&obstack_for_string);
STRING_FINISH;
return last_string;
}
%%
@@ -238,7 +249,7 @@ int max_left_semantic_context = 0;
static void
handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
{
const char *type_name = NULL;
char const *type_name = NULL;
char *cp = text + 1;
symbol_list *effective_rule;
int effective_rule_length;
@@ -293,7 +304,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
obstack_fgrow1 (&obstack_for_string,
"]b4_lhs_value([%s])[", type_name);
rule->used = true;
rule->action_props.is_value_used = true;
}
else
{
@@ -321,7 +332,9 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
obstack_fgrow3 (&obstack_for_string,
"]b4_rhs_value(%d, %d, [%s])[",
effective_rule_length, n, type_name);
symbol_list_n_used_set (effective_rule, n, true);
if (n > 0)
symbol_list_n_get (effective_rule, n)->action_props.is_value_used =
true;
}
else
complain_at (dollar_loc, _("integer out of range: %s"), quote (text));
@@ -368,12 +381,11 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
| Initialize the scanner. |
`-------------------------*/
/* Translate the dollars and ats in \a a, whose location is \a l. The
translation is for \a rule, in the context \a sc_context
/* Translate the dollars and ats in \a self, in the context \a sc_context
(SC_RULE_ACTION, SC_SYMBOL_ACTION, INITIAL). */
static char const *
translate_action (int sc_context, symbol_list *rule, char const *a, location l)
translate_action (code_props *self, int sc_context)
{
char *res;
static bool initialized = false;
@@ -384,36 +396,102 @@ translate_action (int sc_context, symbol_list *rule, char const *a, location l)
initialized = true;
}
loc->start = loc->end = l.start;
yy_switch_to_buffer (yy_scan_string (a));
res = code_lex (sc_context, rule);
loc->start = loc->end = self->location.start;
yy_switch_to_buffer (yy_scan_string (self->code));
res = code_lex (self, sc_context);
yy_delete_buffer (YY_CURRENT_BUFFER);
return res;
}
char const *
translate_rule_action (symbol_list *rule)
/*------------------------------------------------------------------------.
| Implementation of the public interface as documented in "scan-code.h". |
`------------------------------------------------------------------------*/
void
code_props_none_init (code_props *self)
{
return translate_action (SC_RULE_ACTION, rule, rule->action,
rule->action_location);
*self = code_props_none;
}
code_props const code_props_none = CODE_PROPS_NONE_INIT;
void
code_props_plain_init (code_props *self, char const *code, location code_loc)
{
self->kind = CODE_PROPS_PLAIN;
self->code = code;
self->location = code_loc;
self->is_value_used = false;
self->rule = NULL;
}
void
code_props_symbol_action_init (code_props *self, char const *code,
location code_loc)
{
self->kind = CODE_PROPS_SYMBOL_ACTION;
self->code = code;
self->location = code_loc;
self->is_value_used = false;
self->rule = NULL;
}
void
code_props_rule_action_init (code_props *self, char const *code,
location code_loc, symbol_list *rule)
{
self->kind = CODE_PROPS_RULE_ACTION;
self->code = code;
self->location = code_loc;
self->is_value_used = false;
self->rule = rule;
}
void
code_props_translate_code (code_props *self)
{
switch (self->kind)
{
case CODE_PROPS_NONE:
break;
case CODE_PROPS_PLAIN:
self->code = translate_action (self, INITIAL);
break;
case CODE_PROPS_SYMBOL_ACTION:
self->code = translate_action (self, SC_SYMBOL_ACTION);
break;
case CODE_PROPS_RULE_ACTION:
self->code = translate_action (self, SC_RULE_ACTION);
break;
}
}
char const *
translate_symbol_action (char const *a, location l)
code_props_code_get (code_props const self)
{
return translate_action (SC_SYMBOL_ACTION, NULL, a, l);
return self.code;
}
char const *
translate_code (char const *a, location l)
location
code_props_location_get (code_props const self)
{
return translate_action (INITIAL, NULL, a, l);
aver (self.code != NULL);
return self.location;
}
/*-----------------------------------------------.
| Free all the memory allocated to the scanner. |
`-----------------------------------------------*/
bool
code_props_is_value_used (code_props const self)
{
aver (self.kind != CODE_PROPS_PLAIN);
return self.is_value_used;
}
void
code_scanner_last_string_free (void)
{
STRING_FREE;
}
void
code_scanner_free (void)