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

@@ -1,3 +1,79 @@
2006-11-10 Joel E. Denny <jdenny@ces.clemson.edu>
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.
2006-11-10 Joel E. Denny <jdenny@ces.clemson.edu>
* tests/testsuite.at (AT_CHECK): Don't miss an exit value of 0 because

View File

@@ -27,7 +27,7 @@
#include "complain.h"
#include "location.h"
location const empty_location;
location const empty_location = EMPTY_LOCATION_INIT;
/* If BUF is null, add BUFSIZE (which in this case must be less than
INT_MAX) to COLUMN; otherwise, add mbsnwidth (BUF, BUFSIZE, 0) to

View File

@@ -71,6 +71,7 @@ typedef struct
#define YYLTYPE location
#define EMPTY_LOCATION_INIT {{NULL, 0, 0}, {NULL, 0, 0}}
extern location const empty_location;
/* Set *LOC and adjust scanner cursor to account for token TOKEN of

View File

@@ -373,70 +373,41 @@ token_definitions_output (FILE *out)
}
/*---------------------------------------.
| Output the symbol destructors to OUT. |
`---------------------------------------*/
/*----------------------------------------------------.
| Output the symbol destructors and printers to OUT. |
`----------------------------------------------------*/
static void
symbol_destructors_output (FILE *out)
symbol_code_props_output (FILE *out, char const *what,
code_props (*get)(symbol *))
{
int i;
char const *sep = "";
fputs ("m4_define([b4_symbol_destructors], \n[", out);
fputs ("m4_define([b4_symbol_", out);
fputs (what, out);
fputs ("], \n[", out);
for (i = 0; i < nsyms; ++i)
if (symbol_destructor_get (symbols[i]))
{
symbol *sym = symbols[i];
/* Filename, lineno,
Symbol-name, Symbol-number,
destructor, optional typename. */
fprintf (out, "%s[", sep);
sep = ",\n";
escaped_output (out, symbol_destructor_location_get (sym).start.file);
fprintf (out, ", %d, ",
symbol_destructor_location_get (sym).start.line);
escaped_output (out, sym->tag);
fprintf (out, ", %d, [[%s]]", sym->number,
symbol_destructor_get (sym));
if (sym->type_name)
fprintf (out, ", [[%s]]", sym->type_name);
fputc (']', out);
}
fputs ("])\n\n", out);
}
/*------------------------------------.
| Output the symbol printers to OUT. |
`------------------------------------*/
static void
symbol_printers_output (FILE *out)
{
int i;
char const *sep = "";
fputs ("m4_define([b4_symbol_printers], \n[", out);
for (i = 0; i < nsyms; ++i)
if (symbol_printer_get (symbols[i]))
{
symbol *sym = symbols[i];
/* Filename, lineno,
Symbol-name, Symbol-number,
printer, optional typename. */
fprintf (out, "%s[", sep);
sep = ",\n";
escaped_output (out, symbol_printer_location_get (sym).start.file);
fprintf (out, ", %d, ", symbol_printer_location_get (sym).start.line);
escaped_output (out, sym->tag);
fprintf (out, ", %d, [[%s]]", sym->number, symbol_printer_get (sym));
if (sym->type_name)
fprintf (out, ", [[%s]]", sym->type_name);
fputc (']', out);
}
{
symbol *sym = symbols[i];
char const *code = code_props_code_get ((*get) (sym));
if (code)
{
location loc = code_props_location_get ((*get) (sym));
/* Filename, lineno,
Symbol-name, Symbol-number,
code, optional typename. */
fprintf (out, "%s[", sep);
sep = ",\n";
escaped_output (out, loc.start.file);
fprintf (out, ", %d, ", loc.start.line);
escaped_output (out, sym->tag);
fprintf (out, ", %d, [[%s]]", sym->number, code);
if (sym->type_name)
fprintf (out, ", [[%s]]", sym->type_name);
fputc (']', out);
}
}
fputs ("])\n\n", out);
}
@@ -561,8 +532,8 @@ output_skeleton (void)
user_actions_output (out);
merger_output (out);
token_definitions_output (out);
symbol_destructors_output (out);
symbol_printers_output (out);
symbol_code_props_output (out, "destructors", &symbol_destructor_get);
symbol_code_props_output (out, "printers", &symbol_printer_get);
muscles_m4_output (out);

View File

@@ -668,16 +668,16 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
0, 210, 210, 218, 220, 224, 225, 226, 227, 228,
229, 230, 231, 232, 233, 238, 242, 243, 244, 245,
246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
256, 260, 261, 262, 266, 274, 282, 286, 290, 291,
292, 293, 304, 305, 309, 337, 337, 342, 342, 347,
358, 373, 374, 375, 379, 380, 385, 387, 392, 393,
397, 398, 399, 400, 405, 410, 415, 421, 427, 438,
439, 448, 449, 455, 456, 457, 464, 464, 468, 469,
470, 475, 476, 478, 480, 482, 484, 494, 495, 501,
505, 510, 526, 528, 537, 542, 543, 548, 555, 557
0, 210, 210, 218, 220, 224, 225, 233, 234, 235,
236, 237, 238, 239, 240, 245, 254, 255, 256, 257,
258, 259, 260, 261, 262, 263, 264, 265, 266, 267,
268, 272, 273, 274, 278, 285, 292, 296, 300, 301,
302, 303, 314, 315, 319, 348, 348, 353, 353, 358,
369, 384, 385, 386, 390, 391, 396, 398, 403, 404,
408, 409, 410, 411, 416, 421, 426, 432, 438, 449,
450, 459, 460, 466, 467, 468, 475, 475, 479, 480,
481, 486, 487, 489, 491, 493, 495, 505, 506, 512,
516, 521, 541, 543, 552, 557, 558, 563, 570, 572
};
#endif
@@ -1887,62 +1887,69 @@ yyreduce:
/* Line 1269 of yacc.c */
#line 225 "parse-gram.y"
{ prologue_augment (translate_code ((yyvsp[(1) - (1)].chars), (yylsp[(1) - (1)])), (yylsp[(1) - (1)]), union_seen); }
{
code_props plain_code;
code_props_plain_init (&plain_code, (yyvsp[(1) - (1)].chars), (yylsp[(1) - (1)]));
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
prologue_augment (code_props_code_get (plain_code), (yylsp[(1) - (1)]), union_seen);
code_scanner_last_string_free ();
}
break;
case 7:
/* Line 1269 of yacc.c */
#line 226 "parse-gram.y"
#line 233 "parse-gram.y"
{ debug_flag = true; }
break;
case 8:
/* Line 1269 of yacc.c */
#line 227 "parse-gram.y"
#line 234 "parse-gram.y"
{ muscle_insert ((yyvsp[(2) - (3)].chars), (yyvsp[(3) - (3)].chars)); }
break;
case 9:
/* Line 1269 of yacc.c */
#line 228 "parse-gram.y"
#line 235 "parse-gram.y"
{ defines_flag = true; }
break;
case 10:
/* Line 1269 of yacc.c */
#line 229 "parse-gram.y"
#line 236 "parse-gram.y"
{ error_verbose = true; }
break;
case 11:
/* Line 1269 of yacc.c */
#line 230 "parse-gram.y"
#line 237 "parse-gram.y"
{ expected_sr_conflicts = (yyvsp[(2) - (2)].integer); }
break;
case 12:
/* Line 1269 of yacc.c */
#line 231 "parse-gram.y"
#line 238 "parse-gram.y"
{ expected_rr_conflicts = (yyvsp[(2) - (2)].integer); }
break;
case 13:
/* Line 1269 of yacc.c */
#line 232 "parse-gram.y"
#line 239 "parse-gram.y"
{ spec_file_prefix = (yyvsp[(3) - (3)].chars); }
break;
case 14:
/* Line 1269 of yacc.c */
#line 234 "parse-gram.y"
#line 241 "parse-gram.y"
{
nondeterministic_parser = true;
glr_parser = true;
@@ -1952,114 +1959,119 @@ yyreduce:
case 15:
/* Line 1269 of yacc.c */
#line 239 "parse-gram.y"
#line 246 "parse-gram.y"
{
muscle_code_grow ("initial_action", translate_symbol_action ((yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])), (yylsp[(2) - (2)]));
code_props action;
code_props_symbol_action_init (&action, (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)]));
code_props_translate_code (&action);
gram_scanner_last_string_free ();
muscle_code_grow ("initial_action", code_props_code_get (action), (yylsp[(2) - (2)]));
code_scanner_last_string_free ();
}
break;
case 16:
/* Line 1269 of yacc.c */
#line 242 "parse-gram.y"
#line 254 "parse-gram.y"
{ add_param ("lex_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); }
break;
case 17:
/* Line 1269 of yacc.c */
#line 243 "parse-gram.y"
#line 255 "parse-gram.y"
{ locations_flag = true; }
break;
case 18:
/* Line 1269 of yacc.c */
#line 244 "parse-gram.y"
#line 256 "parse-gram.y"
{ spec_name_prefix = (yyvsp[(3) - (3)].chars); }
break;
case 19:
/* Line 1269 of yacc.c */
#line 245 "parse-gram.y"
#line 257 "parse-gram.y"
{ no_lines_flag = true; }
break;
case 20:
/* Line 1269 of yacc.c */
#line 246 "parse-gram.y"
#line 258 "parse-gram.y"
{ nondeterministic_parser = true; }
break;
case 21:
/* Line 1269 of yacc.c */
#line 247 "parse-gram.y"
#line 259 "parse-gram.y"
{ spec_outfile = (yyvsp[(3) - (3)].chars); }
break;
case 22:
/* Line 1269 of yacc.c */
#line 248 "parse-gram.y"
#line 260 "parse-gram.y"
{ add_param ("parse_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); }
break;
case 23:
/* Line 1269 of yacc.c */
#line 249 "parse-gram.y"
#line 261 "parse-gram.y"
{ pure_parser = true; }
break;
case 24:
/* Line 1269 of yacc.c */
#line 250 "parse-gram.y"
#line 262 "parse-gram.y"
{ push_parser = true; }
break;
case 25:
/* Line 1269 of yacc.c */
#line 251 "parse-gram.y"
#line 263 "parse-gram.y"
{ version_check (&(yylsp[(2) - (2)]), (yyvsp[(2) - (2)].chars)); }
break;
case 26:
/* Line 1269 of yacc.c */
#line 252 "parse-gram.y"
#line 264 "parse-gram.y"
{ skeleton = (yyvsp[(2) - (2)].chars); }
break;
case 27:
/* Line 1269 of yacc.c */
#line 253 "parse-gram.y"
#line 265 "parse-gram.y"
{ token_table_flag = true; }
break;
case 28:
/* Line 1269 of yacc.c */
#line 254 "parse-gram.y"
#line 266 "parse-gram.y"
{ report_flag = report_states; }
break;
case 29:
/* Line 1269 of yacc.c */
#line 255 "parse-gram.y"
#line 267 "parse-gram.y"
{ yacc_flag = true; }
break;
case 33:
/* Line 1269 of yacc.c */
#line 263 "parse-gram.y"
#line 275 "parse-gram.y"
{
grammar_start_symbol_set ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]));
}
@@ -2068,12 +2080,11 @@ yyreduce:
case 34:
/* Line 1269 of yacc.c */
#line 267 "parse-gram.y"
#line 279 "parse-gram.y"
{
symbol_list *list;
const char *action = translate_symbol_action ((yyvsp[(2) - (3)].code), (yylsp[(2) - (3)]));
for (list = (yyvsp[(3) - (3)].list); list; list = list->next)
symbol_list_destructor_set (list, action, (yylsp[(2) - (3)]));
symbol_list_destructor_set (list, (yyvsp[(2) - (3)].code), (yylsp[(2) - (3)]));
symbol_list_free ((yyvsp[(3) - (3)].list));
}
break;
@@ -2081,12 +2092,11 @@ yyreduce:
case 35:
/* Line 1269 of yacc.c */
#line 275 "parse-gram.y"
#line 286 "parse-gram.y"
{
symbol_list *list;
const char *action = translate_symbol_action ((yyvsp[(2) - (3)].code), (yylsp[(2) - (3)]));
for (list = (yyvsp[(3) - (3)].list); list; list = list->next)
symbol_list_printer_set (list, action, (yylsp[(2) - (3)]));
symbol_list_printer_set (list, (yyvsp[(2) - (3)].code), (yylsp[(2) - (3)]));
symbol_list_free ((yyvsp[(3) - (3)].list));
}
break;
@@ -2094,7 +2104,7 @@ yyreduce:
case 36:
/* Line 1269 of yacc.c */
#line 283 "parse-gram.y"
#line 293 "parse-gram.y"
{
default_prec = true;
}
@@ -2103,7 +2113,7 @@ yyreduce:
case 37:
/* Line 1269 of yacc.c */
#line 287 "parse-gram.y"
#line 297 "parse-gram.y"
{
default_prec = false;
}
@@ -2112,49 +2122,49 @@ yyreduce:
case 38:
/* Line 1269 of yacc.c */
#line 290 "parse-gram.y"
#line 300 "parse-gram.y"
{ prologue_augment ((yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)]), true); }
break;
case 39:
/* Line 1269 of yacc.c */
#line 291 "parse-gram.y"
#line 301 "parse-gram.y"
{ prologue_augment ((yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)]), false); }
break;
case 40:
/* Line 1269 of yacc.c */
#line 292 "parse-gram.y"
#line 302 "parse-gram.y"
{ muscle_code_grow ("provides", (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])); }
break;
case 41:
/* Line 1269 of yacc.c */
#line 293 "parse-gram.y"
#line 303 "parse-gram.y"
{ muscle_code_grow ("requires", (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])); }
break;
case 42:
/* Line 1269 of yacc.c */
#line 304 "parse-gram.y"
#line 314 "parse-gram.y"
{}
break;
case 43:
/* Line 1269 of yacc.c */
#line 305 "parse-gram.y"
#line 315 "parse-gram.y"
{ muscle_code_grow ("union_name", (yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
break;
case 44:
/* Line 1269 of yacc.c */
#line 310 "parse-gram.y"
#line 320 "parse-gram.y"
{
char const *body = (yyvsp[(3) - (3)].code);
@@ -2175,20 +2185,21 @@ yyreduce:
union_seen = true;
muscle_code_grow ("stype", body, (yylsp[(3) - (3)]));
gram_scanner_last_string_free ();
}
break;
case 45:
/* Line 1269 of yacc.c */
#line 337 "parse-gram.y"
#line 348 "parse-gram.y"
{ current_class = nterm_sym; }
break;
case 46:
/* Line 1269 of yacc.c */
#line 338 "parse-gram.y"
#line 349 "parse-gram.y"
{
current_class = unknown_sym;
current_type = NULL;
@@ -2198,14 +2209,14 @@ yyreduce:
case 47:
/* Line 1269 of yacc.c */
#line 342 "parse-gram.y"
#line 353 "parse-gram.y"
{ current_class = token_sym; }
break;
case 48:
/* Line 1269 of yacc.c */
#line 343 "parse-gram.y"
#line 354 "parse-gram.y"
{
current_class = unknown_sym;
current_type = NULL;
@@ -2215,7 +2226,7 @@ yyreduce:
case 49:
/* Line 1269 of yacc.c */
#line 348 "parse-gram.y"
#line 359 "parse-gram.y"
{
symbol_list *list;
tag_seen = true;
@@ -2228,7 +2239,7 @@ yyreduce:
case 50:
/* Line 1269 of yacc.c */
#line 359 "parse-gram.y"
#line 370 "parse-gram.y"
{
symbol_list *list;
++current_prec;
@@ -2245,98 +2256,98 @@ yyreduce:
case 51:
/* Line 1269 of yacc.c */
#line 373 "parse-gram.y"
#line 384 "parse-gram.y"
{ (yyval.assoc) = left_assoc; }
break;
case 52:
/* Line 1269 of yacc.c */
#line 374 "parse-gram.y"
#line 385 "parse-gram.y"
{ (yyval.assoc) = right_assoc; }
break;
case 53:
/* Line 1269 of yacc.c */
#line 375 "parse-gram.y"
#line 386 "parse-gram.y"
{ (yyval.assoc) = non_assoc; }
break;
case 54:
/* Line 1269 of yacc.c */
#line 379 "parse-gram.y"
#line 390 "parse-gram.y"
{ current_type = NULL; }
break;
case 55:
/* Line 1269 of yacc.c */
#line 380 "parse-gram.y"
#line 391 "parse-gram.y"
{ current_type = (yyvsp[(1) - (1)].uniqstr); tag_seen = true; }
break;
case 56:
/* Line 1269 of yacc.c */
#line 386 "parse-gram.y"
#line 397 "parse-gram.y"
{ (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); }
break;
case 57:
/* Line 1269 of yacc.c */
#line 388 "parse-gram.y"
#line 399 "parse-gram.y"
{ (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); }
break;
case 58:
/* Line 1269 of yacc.c */
#line 392 "parse-gram.y"
#line 403 "parse-gram.y"
{ (yyval.list) = (yyvsp[(1) - (1)].list); }
break;
case 59:
/* Line 1269 of yacc.c */
#line 393 "parse-gram.y"
#line 404 "parse-gram.y"
{ (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list)); }
break;
case 60:
/* Line 1269 of yacc.c */
#line 397 "parse-gram.y"
#line 408 "parse-gram.y"
{ (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); }
break;
case 61:
/* Line 1269 of yacc.c */
#line 398 "parse-gram.y"
#line 409 "parse-gram.y"
{ (yyval.list) = symbol_list_type_new ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
break;
case 62:
/* Line 1269 of yacc.c */
#line 399 "parse-gram.y"
#line 410 "parse-gram.y"
{ (yyval.list) = symbol_list_default_tagged_new ((yylsp[(1) - (1)])); }
break;
case 63:
/* Line 1269 of yacc.c */
#line 400 "parse-gram.y"
#line 411 "parse-gram.y"
{ (yyval.list) = symbol_list_default_tagless_new ((yylsp[(1) - (1)])); }
break;
case 64:
/* Line 1269 of yacc.c */
#line 406 "parse-gram.y"
#line 417 "parse-gram.y"
{
current_type = (yyvsp[(1) - (1)].uniqstr);
tag_seen = true;
@@ -2346,7 +2357,7 @@ yyreduce:
case 65:
/* Line 1269 of yacc.c */
#line 411 "parse-gram.y"
#line 422 "parse-gram.y"
{
symbol_class_set ((yyvsp[(1) - (1)].symbol), current_class, (yylsp[(1) - (1)]), true);
symbol_type_set ((yyvsp[(1) - (1)].symbol), current_type, (yylsp[(1) - (1)]));
@@ -2356,7 +2367,7 @@ yyreduce:
case 66:
/* Line 1269 of yacc.c */
#line 416 "parse-gram.y"
#line 427 "parse-gram.y"
{
symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true);
symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)]));
@@ -2367,7 +2378,7 @@ yyreduce:
case 67:
/* Line 1269 of yacc.c */
#line 422 "parse-gram.y"
#line 433 "parse-gram.y"
{
symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true);
symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)]));
@@ -2378,7 +2389,7 @@ yyreduce:
case 68:
/* Line 1269 of yacc.c */
#line 428 "parse-gram.y"
#line 439 "parse-gram.y"
{
symbol_class_set ((yyvsp[(1) - (3)].symbol), current_class, (yylsp[(1) - (3)]), true);
symbol_type_set ((yyvsp[(1) - (3)].symbol), current_type, (yylsp[(1) - (3)]));
@@ -2390,7 +2401,7 @@ yyreduce:
case 75:
/* Line 1269 of yacc.c */
#line 458 "parse-gram.y"
#line 469 "parse-gram.y"
{
yyerrok;
}
@@ -2399,70 +2410,70 @@ yyreduce:
case 76:
/* Line 1269 of yacc.c */
#line 464 "parse-gram.y"
#line 475 "parse-gram.y"
{ current_lhs = (yyvsp[(1) - (1)].symbol); current_lhs_location = (yylsp[(1) - (1)]); }
break;
case 78:
/* Line 1269 of yacc.c */
#line 468 "parse-gram.y"
#line 479 "parse-gram.y"
{ grammar_current_rule_end ((yylsp[(1) - (1)])); }
break;
case 79:
/* Line 1269 of yacc.c */
#line 469 "parse-gram.y"
#line 480 "parse-gram.y"
{ grammar_current_rule_end ((yylsp[(3) - (3)])); }
break;
case 81:
/* Line 1269 of yacc.c */
#line 475 "parse-gram.y"
#line 486 "parse-gram.y"
{ grammar_current_rule_begin (current_lhs, current_lhs_location); }
break;
case 82:
/* Line 1269 of yacc.c */
#line 477 "parse-gram.y"
#line 488 "parse-gram.y"
{ grammar_current_rule_symbol_append ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); }
break;
case 83:
/* Line 1269 of yacc.c */
#line 479 "parse-gram.y"
#line 490 "parse-gram.y"
{ grammar_current_rule_action_append ((yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); }
break;
case 84:
/* Line 1269 of yacc.c */
#line 481 "parse-gram.y"
#line 492 "parse-gram.y"
{ grammar_current_rule_prec_set ((yyvsp[(3) - (3)].symbol), (yylsp[(3) - (3)])); }
break;
case 85:
/* Line 1269 of yacc.c */
#line 483 "parse-gram.y"
#line 494 "parse-gram.y"
{ grammar_current_rule_dprec_set ((yyvsp[(3) - (3)].integer), (yylsp[(3) - (3)])); }
break;
case 86:
/* Line 1269 of yacc.c */
#line 485 "parse-gram.y"
#line 496 "parse-gram.y"
{ grammar_current_rule_merge_set ((yyvsp[(3) - (3)].uniqstr), (yylsp[(3) - (3)])); }
break;
case 89:
/* Line 1269 of yacc.c */
#line 501 "parse-gram.y"
#line 512 "parse-gram.y"
{
static char one[] = "1";
(yyval.chars) = one;
@@ -2472,24 +2483,28 @@ yyreduce:
case 91:
/* Line 1269 of yacc.c */
#line 511 "parse-gram.y"
#line 522 "parse-gram.y"
{
code_props plain_code;
(yyvsp[(1) - (1)].code)[strlen ((yyvsp[(1) - (1)].code)) - 1] = '\n';
(yyval.chars) = translate_code ((yyvsp[(1) - (1)].code) + 1, (yylsp[(1) - (1)]));
code_props_plain_init (&plain_code, (yyvsp[(1) - (1)].code)+1, (yylsp[(1) - (1)]));
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
(yyval.chars) = code_props_code_get (plain_code);
}
break;
case 92:
/* Line 1269 of yacc.c */
#line 527 "parse-gram.y"
#line 542 "parse-gram.y"
{ (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
break;
case 93:
/* Line 1269 of yacc.c */
#line 529 "parse-gram.y"
#line 544 "parse-gram.y"
{
(yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)]));
symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false);
@@ -2500,14 +2515,14 @@ yyreduce:
case 94:
/* Line 1269 of yacc.c */
#line 537 "parse-gram.y"
#line 552 "parse-gram.y"
{ (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); }
break;
case 97:
/* Line 1269 of yacc.c */
#line 549 "parse-gram.y"
#line 564 "parse-gram.y"
{
(yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)]));
symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false);
@@ -2517,17 +2532,21 @@ yyreduce:
case 99:
/* Line 1269 of yacc.c */
#line 558 "parse-gram.y"
#line 573 "parse-gram.y"
{
muscle_code_grow ("epilogue", translate_code ((yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])), (yylsp[(2) - (2)]));
code_props plain_code;
code_props_plain_init (&plain_code, (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)]));
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
muscle_code_grow ("epilogue", code_props_code_get (plain_code), (yylsp[(2) - (2)]));
code_scanner_last_string_free ();
}
break;
/* Line 1269 of yacc.c */
#line 2531 "parse-gram.c"
#line 2550 "parse-gram.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2746,7 +2765,7 @@ yyreturn:
/* Line 1486 of yacc.c */
#line 564 "parse-gram.y"
#line 583 "parse-gram.y"

View File

@@ -182,7 +182,7 @@ static int current_prec = 0;
%printer { fputs (char_name ($$), stderr); } CHAR
/* braceless is not to be used for rule or symbol actions, as it
calls translate_code. */
calls code_props_plain_init. */
%type <chars> STRING "%{...%}" EPILOGUE braceless content content.opt
%type <code> "{...}"
%printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
@@ -222,7 +222,14 @@ prologue_declarations:
prologue_declaration:
grammar_declaration
| "%{...%}" { prologue_augment (translate_code ($1, @1), @1, union_seen); }
| "%{...%}" {
code_props plain_code;
code_props_plain_init (&plain_code, $1, @1);
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
prologue_augment (code_props_code_get (plain_code), @1, union_seen);
code_scanner_last_string_free ();
}
| "%debug" { debug_flag = true; }
| "%define" STRING content.opt { muscle_insert ($2, $3); }
| "%defines" { defines_flag = true; }
@@ -237,7 +244,12 @@ prologue_declaration:
}
| "%initial-action" "{...}"
{
muscle_code_grow ("initial_action", translate_symbol_action ($2, @2), @2);
code_props action;
code_props_symbol_action_init (&action, $2, @2);
code_props_translate_code (&action);
gram_scanner_last_string_free ();
muscle_code_grow ("initial_action", code_props_code_get (action), @2);
code_scanner_last_string_free ();
}
| "%lex-param" "{...}" { add_param ("lex_param", $2, @2); }
| "%locations" { locations_flag = true; }
@@ -266,17 +278,15 @@ grammar_declaration:
| "%destructor" "{...}" generic_symlist
{
symbol_list *list;
const char *action = translate_symbol_action ($2, @2);
for (list = $3; list; list = list->next)
symbol_list_destructor_set (list, action, @2);
symbol_list_destructor_set (list, $2, @2);
symbol_list_free ($3);
}
| "%printer" "{...}" generic_symlist
{
symbol_list *list;
const char *action = translate_symbol_action ($2, @2);
for (list = $3; list; list = list->next)
symbol_list_printer_set (list, action, @2);
symbol_list_printer_set (list, $2, @2);
symbol_list_free ($3);
}
| "%default-prec"
@@ -327,6 +337,7 @@ grammar_declaration:
union_seen = true;
muscle_code_grow ("stype", body, @3);
gram_scanner_last_string_free ();
}
;
@@ -509,8 +520,12 @@ content.opt:
braceless:
"{...}"
{
code_props plain_code;
$1[strlen ($1) - 1] = '\n';
$$ = translate_code ($1 + 1, @1);
code_props_plain_init (&plain_code, $1+1, @1);
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
$$ = code_props_code_get (plain_code);
}
;
@@ -556,8 +571,12 @@ epilogue.opt:
/* Nothing. */
| "%%" EPILOGUE
{
muscle_code_grow ("epilogue", translate_code ($2, @2), @2);
code_props plain_code;
code_props_plain_init (&plain_code, $2, @2);
code_props_translate_code (&plain_code);
gram_scanner_last_string_free ();
muscle_code_grow ("epilogue", code_props_code_get (plain_code), @2);
code_scanner_last_string_free ();
}
;

View File

@@ -253,13 +253,21 @@ grammar_current_rule_begin (symbol *lhs, location loc)
static bool
symbol_should_be_used (symbol_list const *s)
{
if (symbol_destructor_get (s->content.sym))
if (code_props_code_get (symbol_destructor_get (s->content.sym)))
return true;
if (warnings_flag & warnings_midrule_values)
return ((s->midrule && s->midrule->used)
|| (s->midrule_parent_rule
&& symbol_list_n_get (s->midrule_parent_rule,
s->midrule_parent_rhs_index)->used));
{
if (s->midrule && code_props_is_value_used (s->midrule->action_props))
return true;
if (s->midrule_parent_rule)
{
symbol_list *rhs_node =
symbol_list_n_get (s->midrule_parent_rule,
s->midrule_parent_rhs_index);
if (code_props_is_value_used (rhs_node->action_props))
return true;
}
}
return false;
}
@@ -278,7 +286,7 @@ grammar_rule_check (const symbol_list *r)
Don't worry about the default action if $$ is untyped, since $$'s
value can't be used. */
if (!r->action && r->content.sym->type_name)
if (!code_props_code_get (r->action_props) && r->content.sym->type_name)
{
symbol *first_rhs = r->next->content.sym;
/* If $$ is being set in default way, report if any type mismatch. */
@@ -303,10 +311,11 @@ grammar_rule_check (const symbol_list *r)
symbol_list const *l = r;
int n = 0;
for (; l && l->content.sym; l = l->next, ++n)
if (! (l->used
if (! (code_props_is_value_used (l->action_props)
|| !symbol_should_be_used (l)
/* The default action, $$ = $1, `uses' both. */
|| (!r->action && (n == 0 || n == 1))))
|| (!code_props_code_get (r->action_props)
&& (n == 0 || n == 1))))
{
if (n)
warn_at (r->location, _("unused value: $%d"), n);
@@ -346,7 +355,8 @@ grammar_midrule_action (void)
/* Make a DUMMY nonterminal, whose location is that of the midrule
action. Create the MIDRULE. */
location dummy_location = current_rule->action_location;
location dummy_location =
code_props_location_get (current_rule->action_props);
symbol *dummy = dummy_symbol_get (dummy_location);
symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
@@ -356,12 +366,12 @@ grammar_midrule_action (void)
++nritems;
/* Attach its location and actions to that of the DUMMY. */
midrule->location = dummy_location;
midrule->action = current_rule->action;
midrule->action_location = dummy_location;
current_rule->action = NULL;
/* The action has not been translated yet, so $$ use hasn't been
detected yet. */
midrule->used = false;
code_props_rule_action_init (
&midrule->action_props,
code_props_code_get (current_rule->action_props),
code_props_location_get (current_rule->action_props),
midrule);
code_props_none_init (&current_rule->action_props);
if (previous_rule_end)
previous_rule_end->next = midrule;
@@ -426,7 +436,7 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
void
grammar_current_rule_symbol_append (symbol *sym, location loc)
{
if (current_rule->action)
if (code_props_code_get (current_rule->action_props))
grammar_midrule_action ();
grammar_symbol_append (sym, loc);
}
@@ -436,12 +446,12 @@ grammar_current_rule_symbol_append (symbol *sym, location loc)
void
grammar_current_rule_action_append (const char *action, location loc)
{
if (current_rule->action)
if (code_props_code_get (current_rule->action_props))
grammar_midrule_action ();
/* After all symbol declarations have been parsed, packgram invokes
translate_rule_action. */
current_rule->action = action;
current_rule->action_location = loc;
code_props_translate_code. */
code_props_rule_action_init (&current_rule->action_props, action, loc,
current_rule);
}
@@ -472,8 +482,7 @@ packgram (void)
`$' from any midrule symbol name. */
while (p)
{
if (p->action)
p->action = translate_rule_action (p);
code_props_translate_code (&p->action_props);
if (p)
p = p->next;
}
@@ -495,16 +504,20 @@ packgram (void)
rules[ruleno].precsym = NULL;
rules[ruleno].location = p->location;
rules[ruleno].useful = true;
rules[ruleno].action = p->action;
rules[ruleno].action_location = p->action_location;
rules[ruleno].action = code_props_code_get (p->action_props);
if (rules[ruleno].action)
rules[ruleno].action_location =
code_props_location_get (p->action_props);
/* If the midrule's $$ is set or its $n is used, remove the `$' from the
symbol name so that it's a user-defined symbol so that the default
%destructor and %printer apply. */
if (p->midrule_parent_rule
&& (p->used
|| symbol_list_n_get (p->midrule_parent_rule,
p->midrule_parent_rhs_index)->used))
&& (code_props_is_value_used (p->action_props)
|| code_props_is_value_used (
symbol_list_n_get (
p->midrule_parent_rule,
p->midrule_parent_rhs_index)->action_props)))
p->content.sym->tag += 1;
/* Don't check the generated rule 0. It has no action, so some rhs

View File

@@ -1,4 +1,4 @@
/* Bison Action Scanner
/* Bison Code Data Structure and Scanner.
Copyright (C) 2006 Free Software Foundation, Inc.
@@ -24,24 +24,210 @@
# define SCAN_CODE_H_
# include "location.h"
# include "symlist.h"
/* Keeps track of the maximum number of semantic values to the left of
a handle (those referenced by $0, $-1, etc.) are required by the
semantic actions of this grammar. */
struct symbol_list;
/**
* \brief
* Keeps track of the maximum number of semantic values to the left of a
* handle (those referenced by \c $0, \c $-1, etc.) that are required by the
* semantic actions of this grammar.
*/
extern int max_left_semantic_context;
/**
* \brief
* A code passage captured from the grammar file and possibly translated,
* and/or properties associated with such a code passage.
* \note
* - Don't break encapsulation by accessing the fields directly. Use the
* provided interface functions.
*/
typedef struct code_props {
/**
* \brief
* What kind of \c code_props this is.
* \sa
* - \c code_props_none_init
* - \c code_props_plain_init
* - \c code_props_symbol_action_init
* - \c code_props_rule_action_init
*/
enum {
CODE_PROPS_NONE, CODE_PROPS_PLAIN,
CODE_PROPS_SYMBOL_ACTION, CODE_PROPS_RULE_ACTION
} kind;
/**
* \brief
* The code passage contained within this \c code_props.
* \invariant
* - <tt>code_props::code = NULL</tt> iff
* <tt>code_props::kind = CODE_PROPS_NONE</tt>.
*/
char const *code;
/**
* \brief
* The grammar file location of \c code_props::code.
* \invariant
* - \c code_props::location is undefined iff
* <tt>code_props::code = NULL</tt>.
*/
location location;
/**
* \brief
* The value returned by \c code_props_is_value_used for this
* \c code_props.
*/
bool is_value_used;
/**
* \brief
* The \c symbol_list node associated with this code passage.
* \invariant
* - <tt>code_props::rule != NULL</tt> iff \c code_props::kind is
* \c CODE_PROPS_RULE_ACTION.
*/
struct symbol_list *rule;
} code_props;
/**
* \pre
* - <tt>self != NULL</tt>.
* \post
* - \c self has been overwritten to contain no code. (However, \c self may
* still be conceptually associated with some passage of code contained
* elsewhere. Thus, a call on <tt>code_props_is_value_used (*self)</tt>,
* for example, is still reasonable.)
*/
void code_props_none_init (code_props *self);
/**
* \brief A \c code_props initializer equivalent to \c code_props_none_init.
*/
#define CODE_PROPS_NONE_INIT \
{CODE_PROPS_NONE, NULL, EMPTY_LOCATION_INIT, false, NULL}
/**
* \brief
* A \c code_props initialized by \c CODE_PROPS_NONE_INIT with no further
* modification.
*/
extern code_props const code_props_none;
/**
* \pre
* - <tt>self != NULL</tt>.
* - <tt>code != NULL</tt>.
* - \c code is an untranslated code passage containing no Bison escapes.
* - \c code was extracted from the grammar file at \c code_loc.
* \post
* - \c self has been overwritten to represent the specified plain code
* passage.
* - \c self does not claim responsibility for the memory of \c code.
*/
void code_props_plain_init (code_props *self, char const *code,
location code_loc);
/**
* \pre
* - <tt>self != NULL</tt>.
* - <tt>code != NULL</tt>.
* - \c code is an untranslated code passage. The only Bison escapes it
* might contain are \c $$ and \c \@$, referring to a single symbol.
* - \c code was extracted from the grammar file at \c code_loc.
* \post
* - \c self has been overwritten to represent the specified symbol action.
* - \c self does not claim responsibility for the memory of \c code.
*/
void code_props_symbol_action_init (code_props *self, char const *code,
location code_loc);
/**
* \pre
* - <tt>self != NULL</tt>.
* - <tt>code != NULL</tt>.
* - <tt>rule != NULL</tt>.
* - \c code is the untranslated action of the rule for which \c rule is the
* LHS node. Thus, \c code possibly contains Bison escapes such as \c $$,
* \c $1, \c $2, etc referring to the values of the rule.
* \post
* - \c self has been overwritten to represent the specified rule action.
* - \c self does not claim responsibility for the memory of \c code or
* \c rule.
*/
void code_props_rule_action_init (code_props *self, char const *code,
location code_loc, struct symbol_list *rule);
/**
* \pre
* - If there's a code passage contained in \c self and it contains Bison
* escapes, all grammar declarations have already been parsed as they may
* affect warnings and complaints issued here.
* \post
* - All M4 special symbols and Bison escapes have been translated in
* <tt>code_props_code_get (*self)</tt> iff
* <tt>code_props_code_get (*self \@pre) != NULL</tt>.
*/
void code_props_translate_code (code_props *self);
/**
* \pre
* - None.
* \post
* - \c result = either:
* - The code passage contained with \c self.
* - \c NULL if none.
*/
char const *code_props_code_get (code_props const self);
/**
* \pre
* - <tt>code_props_code_get (self) != NULL</tt>.
* \post
* - \c result = the grammar file location of
* <tt>code_props_code_get (self)</tt>.
*/
location code_props_location_get (code_props const self);
/**
* \pre
* - \c self was not previously initialized with \c code_props_plain_init.
* \post
* - \c result = either:
* - \c false if either:
* - \c code_props_translate_code has never previously been invoked for
* the \c code_props that would contain the code passage associated
* with \c self. (If \c self is for a RHS \c symbol_list node, that
* \c code_props is not \c self. Instead, it's the \c code_props for
* the LHS symbol of the same rule.)
* - \c code_props_translate_code has been invoked for that
* \c code_props, but the symbol value associated with \c self was not
* referenced in the code passage.
* - \c true otherwise.
*/
bool code_props_is_value_used (code_props const self);
/**
* \pre
* - None.
* \post
* - The dynamic memory allocated by the previous invocation of
* \c code_props_translate_code (if any) was freed. The \c code_props
* instance for which that \c code_props_translate_code was invoked is now
* invalid.
*/
void code_scanner_last_string_free (void);
/**
* \pre
* - None.
* \post
* - All dynamic memory allocated during invocations of
* \c code_props_translate_code (if any) has been freed. All
* \c code_props instances and all pointers returned by
* \c code_props_code_get may now be invalid.
*/
void code_scanner_free (void);
/* The action of the rule R contains $$, $1 etc. referring to the values
of the rule R. */
char const *translate_rule_action (symbol_list *r);
/* The action A refers to $$ and @$ only, referring to a symbol. */
char const *translate_symbol_action (char const *a, location l);
/* The action contains no special escapes, just protect M4 special
symbols. */
char const *translate_code (char const *a, location l);
#endif /* !SCAN_CODE_H_ */

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)

View File

@@ -26,7 +26,6 @@
/* From the scanner. */
extern FILE *gram_in;
extern int gram__flex_debug;
extern char *gram_last_string;
void gram_scanner_initialize (void);
void gram_scanner_free (void);
void gram_scanner_last_string_free (void);

View File

@@ -58,7 +58,7 @@ static size_t no_cr_read (FILE *, char *, size_t);
#define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
/* A string representing the most recently saved token. */
char *last_string;
static char *last_string;
void
gram_scanner_last_string_free (void)

View File

@@ -23,6 +23,7 @@
#include "system.h"
#include "complain.h"
#include "scan-code.h"
#include "symlist.h"
@@ -43,8 +44,7 @@ symbol_list_sym_new (symbol *sym, location loc)
res->midrule_parent_rule = NULL;
res->midrule_parent_rhs_index = 0;
res->action = NULL;
res->used = false;
code_props_none_init (&res->action_props);
res->ruleprec = NULL;
res->dprec = 0;
@@ -118,7 +118,9 @@ symbol_list_syms_print (const symbol_list *l, FILE *f)
for (/* Nothing. */; l && l->content.sym; l = l->next)
{
symbol_print (l->content.sym, f);
fprintf (stderr, l->used ? " used" : " unused");
fprintf (stderr,
code_props_is_value_used (l->action_props)
? " used" : " unused");
if (l && l->content.sym)
fprintf (f, ", ");
}
@@ -207,57 +209,50 @@ symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
}
/*--------------------------------------.
| The item N in symbol list L is USED. |
`--------------------------------------*/
void
symbol_list_n_used_set (symbol_list *l, int n, bool used)
{
l = symbol_list_n_get (l, n);
if (l)
l->used = used;
}
void
symbol_list_destructor_set (symbol_list *node, const char *destructor,
location loc)
symbol_list_destructor_set (symbol_list *node, const char *code, location loc)
{
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, loc);
symbol_destructor_set (node->content.sym, destructor);
break;
case SYMLIST_TYPE:
semantic_type_destructor_set (
semantic_type_get (node->content.type_name), destructor, loc);
semantic_type_get (node->content.type_name), destructor);
break;
case SYMLIST_DEFAULT_TAGGED:
default_tagged_destructor_set (destructor, loc);
default_tagged_destructor_set (destructor);
break;
case SYMLIST_DEFAULT_TAGLESS:
default_tagless_destructor_set (destructor, loc);
default_tagless_destructor_set (destructor);
break;
}
}
void
symbol_list_printer_set (symbol_list *node, const char *printer, location loc)
symbol_list_printer_set (symbol_list *node, const char *code, location loc)
{
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, loc);
symbol_printer_set (node->content.sym, printer);
break;
case SYMLIST_TYPE:
semantic_type_printer_set (
semantic_type_get (node->content.type_name), printer, loc);
semantic_type_get (node->content.type_name), printer);
break;
case SYMLIST_DEFAULT_TAGGED:
default_tagged_printer_set (printer, loc);
default_tagged_printer_set (printer);
break;
case SYMLIST_DEFAULT_TAGLESS:
default_tagless_printer_set (printer, loc);
default_tagless_printer_set (printer);
break;
}
}

View File

@@ -22,6 +22,7 @@
#ifndef SYMLIST_H_
# define SYMLIST_H_
# include "scan-code.h"
# include "location.h"
# include "symtab.h"
@@ -55,12 +56,9 @@ typedef struct symbol_list
struct symbol_list *midrule_parent_rule;
int midrule_parent_rhs_index;
/* The action is attached to the LHS of a rule. */
const char *action;
location action_location;
/* Whether this symbol's value is used in the current action. */
bool used;
/* The action is attached to the LHS of a rule, but action properties for
* each RHS are also stored here. */
code_props action_props;
/* Precedence/associativity. */
symbol *ruleprec;
@@ -106,15 +104,12 @@ symbol_list *symbol_list_n_get (symbol_list *l, int n);
symbol N in rule RULE. */
uniqstr symbol_list_n_type_name_get (symbol_list *l, location loc, int n);
/** The item \c n in symbol list \c l is \c used. */
void symbol_list_n_used_set (symbol_list *l, int n, bool used);
/** Set the \c \%destructor for \c node as \c destructor at \c loc. */
void symbol_list_destructor_set (symbol_list *node, const char *destructor,
void symbol_list_destructor_set (symbol_list *node, const char *code,
location loc);
/** Set the \c \%printer for \c node as \c printer at \c loc. */
void symbol_list_printer_set (symbol_list *node, const char *printer,
void symbol_list_printer_set (symbol_list *node, const char *code,
location loc);
#endif /* !SYMLIST_H_ */

View File

@@ -45,15 +45,10 @@ location startsymbol_location;
| Default %destructor's and %printer's. |
`---------------------------------------*/
static const char *default_tagged_destructor = NULL;
static location default_tagged_destructor_location;
static const char *default_tagless_destructor = NULL;
static location default_tagless_destructor_location;
static const char *default_tagged_printer = NULL;
static location default_tagged_printer_location;
static const char *default_tagless_printer = NULL;
static location default_tagless_printer_location;
static code_props default_tagged_destructor = CODE_PROPS_NONE_INIT;
static code_props default_tagless_destructor = CODE_PROPS_NONE_INIT;
static code_props default_tagged_printer = CODE_PROPS_NONE_INIT;
static code_props default_tagless_printer = CODE_PROPS_NONE_INIT;
/*---------------------------------.
| Create a new symbol, named TAG. |
@@ -69,8 +64,8 @@ symbol_new (uniqstr tag, location loc)
res->location = loc;
res->type_name = NULL;
res->destructor = NULL;
res->printer = NULL;
code_props_none_init (&res->destructor);
code_props_none_init (&res->printer);
res->number = NUMBER_UNDEFINED;
res->prec = 0;
@@ -99,8 +94,8 @@ semantic_type_new (uniqstr tag)
uniqstr_assert (tag);
res->tag = tag;
res->destructor = NULL;
res->printer = NULL;
code_props_none_init (&res->destructor);
code_props_none_init (&res->printer);
return res;
}
@@ -114,6 +109,10 @@ semantic_type_new (uniqstr tag)
if (s->Attr) \
fprintf (f, " %s { %s }", #Attr, s->Attr)
#define SYMBOL_CODE_PRINT(Attr) \
if (code_props_code_get (s->Attr)) \
fprintf (f, " %s { %s }", #Attr, code_props_code_get(s->Attr))
void
symbol_print (symbol *s, FILE *f)
{
@@ -121,14 +120,15 @@ symbol_print (symbol *s, FILE *f)
{
fprintf (f, "\"%s\"", s->tag);
SYMBOL_ATTR_PRINT (type_name);
SYMBOL_ATTR_PRINT (destructor);
SYMBOL_ATTR_PRINT (printer);
SYMBOL_CODE_PRINT (destructor);
SYMBOL_CODE_PRINT (printer);
}
else
fprintf (f, "<NULL>");
}
#undef SYMBOL_ATTR_PRINT
#undef SYMBOL_CODE_PRINT
/*------------------------------------------------------------------.
| Complain that S's WHAT is redeclared at SECOND, and was first set |
@@ -171,170 +171,118 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
}
/*------------------------------------------------------------------.
| Set the DESTRUCTOR associated with SYM. Do nothing if passed 0. |
`------------------------------------------------------------------*/
/*-----------------------------------------.
| Set the DESTRUCTOR associated with SYM. |
`-----------------------------------------*/
void
symbol_destructor_set (symbol *sym, const char *destructor, location loc)
symbol_destructor_set (symbol *sym, code_props destructor)
{
if (destructor)
{
if (sym->destructor)
symbol_redeclaration (sym, "%destructor", sym->destructor_location,
loc);
sym->destructor = destructor;
sym->destructor_location = loc;
}
if (code_props_code_get (sym->destructor))
symbol_redeclaration (sym, "%destructor",
code_props_location_get (sym->destructor),
code_props_location_get (destructor));
sym->destructor = destructor;
}
/*-------------------------------------------------------------------.
| Set the DESTRUCTOR associated with TYPE. Do nothing if passed 0. |
`-------------------------------------------------------------------*/
/*------------------------------------------.
| Set the DESTRUCTOR associated with TYPE. |
`------------------------------------------*/
void
semantic_type_destructor_set (semantic_type *type, const char *destructor,
location loc)
semantic_type_destructor_set (semantic_type *type, code_props destructor)
{
if (destructor)
{
if (type->destructor)
semantic_type_redeclaration (type, "%destructor",
type->destructor_location, loc);
type->destructor = destructor;
type->destructor_location = loc;
}
if (code_props_code_get (type->destructor))
semantic_type_redeclaration (type, "%destructor",
code_props_location_get (type->destructor),
code_props_location_get (destructor));
type->destructor = destructor;
}
/*---------------------------------------.
| Get the computed %destructor for SYM. |
`---------------------------------------*/
const char *
code_props
symbol_destructor_get (symbol *sym)
{
/* Per-symbol %destructor. */
if (sym->destructor != NULL)
if (code_props_code_get (sym->destructor))
return sym->destructor;
/* Per-type %destructor. */
if (sym->type_name)
{
semantic_type *type = semantic_type_get (sym->type_name);
if (type->destructor)
return type->destructor;
code_props destructor = semantic_type_get (sym->type_name)->destructor;
if (code_props_code_get (destructor))
return destructor;
}
/* Apply default %destructor's only to user-defined symbols. */
if (sym->tag[0] == '$' || sym == errtoken)
return NULL;
return code_props_none;
if (sym->type_name)
return default_tagged_destructor;
return default_tagless_destructor;
}
/*---------------------------------------------------------------.
| Get the grammar location of the %destructor computed for SYM. |
`---------------------------------------------------------------*/
location
symbol_destructor_location_get (symbol *sym)
{
if (sym->destructor != NULL)
return sym->destructor_location;
if (sym->type_name)
{
semantic_type *type = semantic_type_get (sym->type_name);
if (type->destructor)
return type->destructor_location;
return default_tagged_destructor_location;
}
return default_tagless_destructor_location;
}
/*---------------------------------------------------------------.
| Set the PRINTER associated with SYM. Do nothing if passed 0. |
`---------------------------------------------------------------*/
/*--------------------------------------.
| Set the PRINTER associated with SYM. |
`--------------------------------------*/
void
symbol_printer_set (symbol *sym, const char *printer, location loc)
symbol_printer_set (symbol *sym, code_props printer)
{
if (printer)
{
if (sym->printer)
symbol_redeclaration (sym, "%printer", sym->printer_location, loc);
sym->printer = printer;
sym->printer_location = loc;
}
if (code_props_code_get (sym->printer))
symbol_redeclaration (sym, "%printer",
code_props_location_get (sym->printer),
code_props_location_get (printer));
sym->printer = printer;
}
/*----------------------------------------------------------------.
| Set the PRINTER associated with TYPE. Do nothing if passed 0. |
`----------------------------------------------------------------*/
/*---------------------------------------.
| Set the PRINTER associated with TYPE. |
`---------------------------------------*/
void
semantic_type_printer_set (semantic_type *type, const char *printer,
location loc)
semantic_type_printer_set (semantic_type *type, code_props printer)
{
if (printer)
{
if (type->printer)
semantic_type_redeclaration (type, "%printer", type->printer_location,
loc);
type->printer = printer;
type->printer_location = loc;
}
if (code_props_code_get (type->printer))
semantic_type_redeclaration (type, "%printer",
code_props_location_get (type->printer),
code_props_location_get (printer));
type->printer = printer;
}
/*------------------------------------.
| Get the computed %printer for SYM. |
`------------------------------------*/
const char *
code_props
symbol_printer_get (symbol *sym)
{
/* Per-symbol %printer. */
if (sym->printer != NULL)
if (code_props_code_get (sym->printer))
return sym->printer;
/* Per-type %printer. */
if (sym->type_name)
{
semantic_type *type = semantic_type_get (sym->type_name);
if (type->printer)
return type->printer;
code_props printer = semantic_type_get (sym->type_name)->printer;
if (code_props_code_get (printer))
return printer;
}
/* Apply the default %printer only to user-defined symbols. */
if (sym->tag[0] == '$' || sym == errtoken)
return NULL;
return code_props_none;
if (sym->type_name)
return default_tagged_printer;
return default_tagless_printer;
}
/*------------------------------------------------------------.
| Get the grammar location of the %printer computed for SYM. |
`------------------------------------------------------------*/
location
symbol_printer_location_get (symbol *sym)
{
if (sym->printer != NULL)
return sym->printer_location;
if (sym->type_name)
{
semantic_type *type = semantic_type_get (sym->type_name);
if (type->printer)
return type->printer_location;
return default_tagged_printer_location;
}
return default_tagless_printer_location;
}
/*-----------------------------------------------------------------.
| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
| with UNDEF_ASSOC as ASSOC. |
@@ -498,22 +446,22 @@ symbol_check_alias_consistency (symbol *this)
}
if (orig->destructor || alias->destructor)
if (code_props_code_get (orig->destructor)
|| code_props_code_get (alias->destructor))
{
if (orig->destructor)
symbol_destructor_set (alias, orig->destructor,
orig->destructor_location);
if (code_props_code_get (orig->destructor))
symbol_destructor_set (alias, orig->destructor);
else
symbol_destructor_set (orig, alias->destructor,
alias->destructor_location);
symbol_destructor_set (orig, alias->destructor);
}
if (orig->printer || alias->printer)
if (code_props_code_get (orig->printer)
|| code_props_code_get (alias->printer))
{
if (orig->printer)
symbol_printer_set (alias, orig->printer, orig->printer_location);
if (code_props_code_get (orig->printer))
symbol_printer_set (alias, orig->printer);
else
symbol_printer_set (orig, alias->printer, alias->printer_location);
symbol_printer_set (orig, alias->printer);
}
if (alias->prec || orig->prec)
@@ -942,53 +890,54 @@ symbols_pack (void)
`--------------------------------------------------*/
void
default_tagged_destructor_set (const char *destructor, location loc)
default_tagged_destructor_set (code_props destructor)
{
if (default_tagged_destructor != NULL)
if (code_props_code_get (default_tagged_destructor))
{
complain_at (loc, _("redeclaration for default tagged %%destructor"));
complain_at (default_tagged_destructor_location,
complain_at (code_props_location_get (destructor),
_("redeclaration for default tagged %%destructor"));
complain_at (code_props_location_get (default_tagged_destructor),
_("previous declaration"));
}
default_tagged_destructor = destructor;
default_tagged_destructor_location = loc;
}
void
default_tagless_destructor_set (const char *destructor, location loc)
default_tagless_destructor_set (code_props destructor)
{
if (default_tagless_destructor != NULL)
if (code_props_code_get (default_tagless_destructor))
{
complain_at (loc, _("redeclaration for default tagless %%destructor"));
complain_at (default_tagless_destructor_location,
complain_at (code_props_location_get (destructor),
_("redeclaration for default tagless %%destructor"));
complain_at (code_props_location_get (default_tagless_destructor),
_("previous declaration"));
}
default_tagless_destructor = destructor;
default_tagless_destructor_location = loc;
}
void
default_tagged_printer_set (const char *printer, location loc)
default_tagged_printer_set (code_props printer)
{
if (default_tagged_printer != NULL)
if (code_props_code_get (default_tagged_printer))
{
complain_at (loc, _("redeclaration for default tagged %%printer"));
complain_at (default_tagged_printer_location,
complain_at (code_props_location_get (printer),
_("redeclaration for default tagged %%printer"));
complain_at (code_props_location_get (default_tagged_printer),
_("previous declaration"));
}
default_tagged_printer = printer;
default_tagged_printer_location = loc;
}
void
default_tagless_printer_set (const char *printer, location loc)
default_tagless_printer_set (code_props printer)
{
if (default_tagless_printer != NULL)
if (code_props_code_get (default_tagless_printer))
{
complain_at (loc, _("redeclaration for default tagless %%printer"));
complain_at (default_tagless_printer_location,
complain_at (code_props_location_get (printer),
_("redeclaration for default tagless %%printer"));
complain_at (code_props_location_get (default_tagless_printer),
_("previous declaration"));
}
default_tagless_printer = printer;
default_tagless_printer_location = loc;
}

View File

@@ -30,6 +30,7 @@
# include "assoc.h"
# include "location.h"
# include "scan-code.h"
# include "uniqstr.h"
/*----------.
@@ -72,25 +73,13 @@ struct symbol
example, if <tt>symbol::destructor = NULL</tt>, a default \c \%destructor
or a per-type \c \%destructor might be appropriate, and
\c symbol_destructor_get will compute the correct one. */
const char *destructor;
/** The location of \c symbol::destructor.
Access this field only through <tt>symbol</tt>'s interface functions.
\sa symbol::destructor */
location destructor_location;
code_props destructor;
/** Any \c \%printer declared specifically for this symbol.
Access this field only through <tt>symbol</tt>'s interface functions.
\sa symbol::destructor */
const char *printer;
/** The location of \c symbol::printer.
Access this field only through <tt>symbol</tt>'s interface functions.
\sa symbol::destructor */
location printer_location;
code_props printer;
symbol_number number;
location prec_location;
@@ -144,26 +133,18 @@ void symbol_make_alias (symbol *sym, symbol *symval, location loc);
void symbol_type_set (symbol *sym, uniqstr type_name, location loc);
/** Set the \c destructor associated with \c sym. */
void symbol_destructor_set (symbol *sym, const char *destructor, location loc);
void symbol_destructor_set (symbol *sym, code_props destructor);
/** Get the computed \c \%destructor for \c sym, or \c NULL if none. */
const char *symbol_destructor_get (symbol *sym);
/** Get the grammar location of the computed \c \%destructor for \c sym.
\pre <tt>symbol_destructor_get (sym) != NULL</tt> */
location symbol_destructor_location_get (symbol *sym);
/** Get the computed \c \%destructor for \c sym, which was initialized with
\c code_props_none_init if there's no \c \%destructor. */
code_props symbol_destructor_get (symbol *sym);
/** Set the \c printer associated with \c sym. */
void symbol_printer_set (symbol *sym, const char *printer, location loc);
void symbol_printer_set (symbol *sym, code_props printer);
/** Get the computed \c \%printer for \c sym, or \c NULL if none. */
const char *symbol_printer_get (symbol *sym);
/** Get the grammar location of the computed \c \%printer for \c sym.
\pre <tt>symbol_printer_get (sym) != NULL</tt> */
location symbol_printer_location_get (symbol *sym);
/** Get the computed \c \%printer for \c sym, which was initialized with
\c code_props_none_init if there's no \c \%printer. */
code_props symbol_printer_get (symbol *sym);
/* Set the \c precedence associated with \c sym.
@@ -209,14 +190,9 @@ typedef struct semantic_type {
uniqstr tag;
/** Any \c %destructor declared for this semantic type. */
const char *destructor;
/** The location of \c semantic_type::destructor. */
location destructor_location;
code_props destructor;
/** Any \c %printer declared for this semantic type. */
const char *printer;
/** The location of \c semantic_type::printer. */
location printer_location;
code_props printer;
} semantic_type;
/** Fetch (or create) the semantic type associated to KEY. */
@@ -226,12 +202,10 @@ semantic_type *semantic_type_from_uniqstr (const uniqstr key);
semantic_type *semantic_type_get (const char *key);
/** Set the \c destructor associated with \c type. */
void semantic_type_destructor_set (semantic_type *type, const char *destructor,
location loc);
void semantic_type_destructor_set (semantic_type *type, code_props destructor);
/** Set the \c printer associated with \c type. */
void semantic_type_printer_set (semantic_type *type, const char *printer,
location loc);
void semantic_type_printer_set (semantic_type *type, code_props printer);
/*----------------------------------.
| Symbol and semantic type tables. |
@@ -260,13 +234,13 @@ void symbols_pack (void);
`---------------------------------------*/
/** Set the default \c \%destructor for tagged values. */
void default_tagged_destructor_set (const char *destructor, location loc);
void default_tagged_destructor_set (code_props destructor);
/** Set the default \c \%destructor for tagless values. */
void default_tagless_destructor_set (const char *destructor, location loc);
void default_tagless_destructor_set (code_props destructor);
/** Set the default \c \%printer for tagged values. */
void default_tagged_printer_set (const char *printer, location loc);
void default_tagged_printer_set (code_props printer);
/** Set the default \c \%printer for tagless values. */
void default_tagless_printer_set (const char *printer, location loc);
void default_tagless_printer_set (code_props printer);
#endif /* !SYMTAB_H_ */