Prepare @$ in %destructor, but currently don't bind it in the

skeleton, as %location use is not cleaned up yet.
* src/scan-gram.l (handle_dollar, handle_destructor_at)
(handle_action_at): New.
(handle_at, handle_action_dollar, handle_destructor_dollar): Take
a braced_code_t and a location as additional arguments.
(handle_destructor_dollar): Instead of requiring `b4_eval', just
unquote one when outputting `b4_dollar_dollar'.
Adjust callers.
* data/bison.simple (b4_eval): Remove.
(b4_symbol_destructor): Adjust.
* tests/input.at (Invalid @n): Adjust.
This commit is contained in:
Akim Demaille
2002-06-19 08:22:49 +00:00
parent c732d2c6dc
commit f25bfb75aa
5 changed files with 237 additions and 105 deletions

View File

@@ -1,3 +1,19 @@
2002-06-19 Akim Demaille <akim@epita.fr>
Prepare @$ in %destructor, but currently don't bind it in the
skeleton, as %location use is not cleaned up yet.
* src/scan-gram.l (handle_dollar, handle_destructor_at)
(handle_action_at): New.
(handle_at, handle_action_dollar, handle_destructor_dollar): Take
a braced_code_t and a location as additional arguments.
(handle_destructor_dollar): Instead of requiring `b4_eval', just
unquote one when outputting `b4_dollar_dollar'.
Adjust callers.
* data/bison.simple (b4_eval): Remove.
(b4_symbol_destructor): Adjust.
* tests/input.at (Invalid @n): Adjust.
2002-06-19 Zack Weinberg <zack@codesourcery.com> 2002-06-19 Zack Weinberg <zack@codesourcery.com>
* doc/bison.texinfo: Document ability to have multiple * doc/bison.texinfo: Document ability to have multiple

View File

@@ -1275,21 +1275,13 @@ yyreturn:
`-------------------------------------------------*/ `-------------------------------------------------*/
m4_divert_push([KILL])# M4 code. m4_divert_push([KILL])# M4 code.
# b4_eval
# -------
# FIXME: This is really wrong, we no longer guarantee we don't evaluate
# the user's input. This demonstrates that decoding actions (BRACED_CODE)
# ought to be done when output, not when read.
m4_define([b4_eval],
[$*])
# b4_symbol_destructor(SYMBOL-NUMBER, DESTRUCTOR, TYPE-NAME) # b4_symbol_destructor(SYMBOL-NUMBER, DESTRUCTOR, TYPE-NAME)
# ---------------------------------------------------------- # ----------------------------------------------------------
m4_define([b4_symbol_destructor], m4_define([b4_symbol_destructor],
[m4_pushdef([b4_dollar_dollar], [symbol_value.$6])dnl [m4_pushdef([b4_dollar_dollar], [symbol_value.$6])dnl
case $4: /* $3 */ case $4: /* $3 */
#line $2 "$1" #line $2 "$1"
b4_eval($5); $5;
#line __oline__ "__ofile__" #line __oline__ "__ofile__"
break; break;
m4_popdef([b4_dollar_dollar])]) m4_popdef([b4_dollar_dollar])])

View File

@@ -697,8 +697,8 @@ static yyconst short int yy_rule_linenum[93] =
238, 255, 264, 266, 286, 300, 302, 322, 334, 338, 238, 255, 264, 266, 286, 300, 302, 322, 334, 338,
339, 340, 341, 342, 343, 344, 345, 346, 361, 367, 339, 340, 341, 342, 343, 344, 345, 346, 361, 367,
368, 370, 388, 394, 395, 397, 415, 418, 421, 422, 368, 370, 388, 394, 395, 397, 415, 418, 421, 422,
433, 444, 446, 458, 460, 461, 464, 484, 491, 492, 433, 444, 446, 448, 451, 452, 455, 475, 482, 483,
493, 514 484, 505
} ; } ;
@@ -789,13 +789,13 @@ scanner_last_string_free (void)
} }
static int braces_level = 0; static int braces_level = 0;
static int percent_percent_count = 0; static int percent_percent_count = 0;
static void handle_action_dollar PARAMS ((char *cp, location_t location)); static void handle_dollar PARAMS ((braced_code_t code_kind,
static void handle_destructor_dollar PARAMS ((char *cp, location_t location)); char *cp, location_t location));
static void handle_at PARAMS ((char *cp)); static void handle_at PARAMS ((braced_code_t code_kind,
char *cp, location_t location));
#define SC_COMMENT 1 #define SC_COMMENT 1
@@ -1705,42 +1705,33 @@ YY_OBS_GROW; braces_level++;
case 83: case 83:
YY_RULE_SETUP YY_RULE_SETUP
#line 446 "scan-gram.l" #line 446 "scan-gram.l"
{ { handle_dollar (current_braced_code,
switch (current_braced_code) yytext, *yylloc); }
{
case action_braced_code:
handle_action_dollar (yytext, *yylloc);
break;
case destructor_braced_code:
handle_destructor_dollar (yytext, *yylloc);
break;
}
}
YY_BREAK YY_BREAK
case 84: case 84:
YY_RULE_SETUP YY_RULE_SETUP
#line 458 "scan-gram.l" #line 448 "scan-gram.l"
{ handle_at (yytext); } { handle_at (current_braced_code,
yytext, *yylloc); }
YY_BREAK YY_BREAK
case 85: case 85:
YY_RULE_SETUP YY_RULE_SETUP
#line 460 "scan-gram.l" #line 451 "scan-gram.l"
YY_OBS_GROW; YY_OBS_GROW;
YY_BREAK YY_BREAK
case 86: case 86:
YY_RULE_SETUP YY_RULE_SETUP
#line 461 "scan-gram.l" #line 452 "scan-gram.l"
YY_OBS_GROW; YY_LINES; YY_OBS_GROW; YY_LINES;
YY_BREAK YY_BREAK
/* A lose $, or /, or etc. */ /* A lose $, or /, or etc. */
case 87: case 87:
YY_RULE_SETUP YY_RULE_SETUP
#line 464 "scan-gram.l" #line 455 "scan-gram.l"
YY_OBS_GROW; YY_OBS_GROW;
YY_BREAK YY_BREAK
case YY_STATE_EOF(SC_BRACED_CODE): case YY_STATE_EOF(SC_BRACED_CODE):
#line 466 "scan-gram.l" #line 457 "scan-gram.l"
{ {
LOCATION_PRINT (stderr, *yylloc); LOCATION_PRINT (stderr, *yylloc);
fprintf (stderr, ": unexpected end of file in a braced code\n"); fprintf (stderr, ": unexpected end of file in a braced code\n");
@@ -1758,7 +1749,7 @@ case YY_STATE_EOF(SC_BRACED_CODE):
case 88: case 88:
YY_RULE_SETUP YY_RULE_SETUP
#line 484 "scan-gram.l" #line 475 "scan-gram.l"
{ {
yy_pop_state (); yy_pop_state ();
YY_OBS_FINISH; YY_OBS_FINISH;
@@ -1768,21 +1759,21 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 89: case 89:
YY_RULE_SETUP YY_RULE_SETUP
#line 491 "scan-gram.l" #line 482 "scan-gram.l"
YY_OBS_GROW; YY_OBS_GROW;
YY_BREAK YY_BREAK
case 90: case 90:
YY_RULE_SETUP YY_RULE_SETUP
#line 492 "scan-gram.l" #line 483 "scan-gram.l"
YY_OBS_GROW; YY_OBS_GROW;
YY_BREAK YY_BREAK
case 91: case 91:
YY_RULE_SETUP YY_RULE_SETUP
#line 493 "scan-gram.l" #line 484 "scan-gram.l"
YY_OBS_GROW; YY_LINES; YY_OBS_GROW; YY_LINES;
YY_BREAK YY_BREAK
case YY_STATE_EOF(SC_PROLOGUE): case YY_STATE_EOF(SC_PROLOGUE):
#line 495 "scan-gram.l" #line 486 "scan-gram.l"
{ {
LOCATION_PRINT (stderr, *yylloc); LOCATION_PRINT (stderr, *yylloc);
fprintf (stderr, ": unexpected end of file in a prologue\n"); fprintf (stderr, ": unexpected end of file in a prologue\n");
@@ -1801,11 +1792,11 @@ case YY_STATE_EOF(SC_PROLOGUE):
case 92: case 92:
YY_RULE_SETUP YY_RULE_SETUP
#line 514 "scan-gram.l" #line 505 "scan-gram.l"
YY_OBS_GROW; YY_OBS_GROW;
YY_BREAK YY_BREAK
case YY_STATE_EOF(SC_EPILOGUE): case YY_STATE_EOF(SC_EPILOGUE):
#line 516 "scan-gram.l" #line 507 "scan-gram.l"
{ {
yy_pop_state (); yy_pop_state ();
YY_OBS_FINISH; YY_OBS_FINISH;
@@ -1816,10 +1807,10 @@ case YY_STATE_EOF(SC_EPILOGUE):
case 93: case 93:
YY_RULE_SETUP YY_RULE_SETUP
#line 525 "scan-gram.l" #line 516 "scan-gram.l"
YY_FATAL_ERROR( "flex scanner jammed" ); YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK YY_BREAK
#line 1823 "lex.yy.c" #line 1814 "lex.yy.c"
case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INITIAL):
yyterminate(); yyterminate();
@@ -2709,7 +2700,7 @@ int main()
return 0; return 0;
} }
#endif #endif
#line 525 "scan-gram.l" #line 516 "scan-gram.l"
/*------------------------------------------------------------------. /*------------------------------------------------------------------.
@@ -2720,7 +2711,7 @@ int main()
| Output to the STRING_OBSTACK a reference to this semantic value. | | Output to the STRING_OBSTACK a reference to this semantic value. |
`------------------------------------------------------------------*/ `------------------------------------------------------------------*/
static void static inline void
handle_action_dollar (char *cp, location_t location) handle_action_dollar (char *cp, location_t location)
{ {
const char *type_name = NULL; const char *type_name = NULL;
@@ -2784,21 +2775,17 @@ handle_action_dollar (char *cp, location_t location)
} }
/*---------------------------------------------------------------. /*---------------------------------------.
| CP is pointing to $$ in a destructor. This should probably be | | CP is pointing to $$ in a destructor. |
| done once the grammar completely parsed, instead of during its | `---------------------------------------*/
| parsing, since that means %type must be specified before |
| %destructor. |
`---------------------------------------------------------------*/
static void static inline void
handle_destructor_dollar (char *cp, location_t location) handle_destructor_dollar (char *cp, location_t location)
{ {
++cp; ++cp;
if (*cp == '$') if (*cp == '$')
{ {
/* FIXME: We should find something more robust. */ obstack_sgrow (&string_obstack, "]b4_dollar_dollar[");
obstack_sgrow (&string_obstack, "b4_dollar_dollar");
} }
else else
{ {
@@ -2808,32 +2795,55 @@ handle_destructor_dollar (char *cp, location_t location)
} }
} }
/*-------------------------------------------------------.
| CP is pointing to a location (i.e., a `@'). Output to | /*-----------------------------------------------------------------.
| STRING_OBSTACK a reference to this location. | | Dispatch onto handle_action_dollar, or handle_destructor_dollar, |
`-------------------------------------------------------*/ | depending upon CODE_KIND. |
`-----------------------------------------------------------------*/
static void static void
handle_at (char *cp) handle_dollar (braced_code_t braced_code_kind,
char *text, location_t location)
{
switch (braced_code_kind)
{
case action_braced_code:
handle_action_dollar (text, location);
break;
case destructor_braced_code:
handle_destructor_dollar (text, location);
break;
}
}
/*------------------------------------------------------.
| TEXT is a location token (i.e., a `@...'). Output to |
| STRING_OBSTACK a reference to this location. |
`------------------------------------------------------*/
static inline void
handle_action_at (char *text, location_t location)
{ {
locations_flag = 1; locations_flag = 1;
++cp; ++text;
if (*cp == '$') if (*text == '$')
{ {
obstack_sgrow (&string_obstack, "]b4_lhs_location["); obstack_sgrow (&string_obstack, "]b4_lhs_location[");
} }
else if (isdigit (*cp) || *cp == '-') else if (isdigit (*text) || *text == '-')
{ {
/* RULE_LENGTH is the number of values in the current rule so /* RULE_LENGTH is the number of values in the current rule so
far, which says where to find `$0' with respect to the top of far, which says where to find `$0' with respect to the top of
the stack. It is not the same as the rule->length in the the stack. It is not the same as the rule->length in the
case of mid rule actions. */ case of mid rule actions. */
int rule_length = symbol_list_length (current_rule->next); int rule_length = symbol_list_length (current_rule->next);
int n = strtol (cp, &cp, 10); int n = strtol (text, &text, 10);
if (n > rule_length) if (n > rule_length)
complain (_("invalid value: %s%d"), "@", n); complain_at (location, _("invalid value: %s%d"), "@", n);
else else
obstack_fgrow2 (&string_obstack, "]b4_rhs_location([%d], [%d])[", obstack_fgrow2 (&string_obstack, "]b4_rhs_location([%d], [%d])[",
rule_length, n); rule_length, n);
@@ -2841,11 +2851,59 @@ handle_at (char *cp)
else else
{ {
char buf[] = "@c"; char buf[] = "@c";
buf[1] = *cp; buf[1] = *text;
complain (_("%s is invalid"), quote (buf)); complain_at (location, _("%s is invalid"), quote (buf));
} }
} }
/*--------------------------------------------.
| TEXT is expexted tp be @$ in a destructor. |
`--------------------------------------------*/
static inline void
handle_destructor_at (char *text, location_t location)
{
++text;
if (*text == '$')
{
obstack_sgrow (&string_obstack, "]b4_at_dollar[");
}
else
{
char buf[] = "$c";
buf[1] = *text;
complain_at (location, _("%s is invalid"), quote (buf));
}
}
/*-------------------------------------------------------------------.
| Dispatch onto handle_action_at, or handle_destructor_at, depending |
| upon CODE_KIND. |
`-------------------------------------------------------------------*/
static void
handle_at (braced_code_t braced_code_kind,
char *text, location_t location)
{
switch (braced_code_kind)
{
case action_braced_code:
handle_action_at (text, location);
break;
case destructor_braced_code:
handle_destructor_at (text, location);
break;
}
}
/*-------------------------.
| Initialize the scanner. |
`-------------------------*/
void void
scanner_initialize (void) scanner_initialize (void)
{ {
@@ -2853,6 +2911,10 @@ scanner_initialize (void)
} }
/*-----------------------------------------------.
| Free all the memory allocated to the scanner. |
`-----------------------------------------------*/
void void
scanner_free (void) scanner_free (void)
{ {

View File

@@ -76,13 +76,13 @@ scanner_last_string_free (void)
} }
static int braces_level = 0; static int braces_level = 0;
static int percent_percent_count = 0; static int percent_percent_count = 0;
static void handle_action_dollar PARAMS ((char *cp, location_t location)); static void handle_dollar PARAMS ((braced_code_t code_kind,
static void handle_destructor_dollar PARAMS ((char *cp, location_t location)); char *cp, location_t location));
static void handle_at PARAMS ((char *cp)); static void handle_at PARAMS ((braced_code_t code_kind,
char *cp, location_t location));
%} %}
%x SC_COMMENT %x SC_COMMENT
@@ -443,19 +443,10 @@ blanks [ \t\f]+
"{" YY_OBS_GROW; braces_level++; "{" YY_OBS_GROW; braces_level++;
"$"("<"[^>]+">")?(-?[0-9]+|"$") { "$"("<"[^>]+">")?(-?[0-9]+|"$") { handle_dollar (current_braced_code,
switch (current_braced_code) yytext, *yylloc); }
{ "@"(-?[0-9]+|"$") { handle_at (current_braced_code,
case action_braced_code: yytext, *yylloc); }
handle_action_dollar (yytext, *yylloc);
break;
case destructor_braced_code:
handle_destructor_dollar (yytext, *yylloc);
break;
}
}
"@"(-?[0-9]+|"$") { handle_at (yytext); }
[^$@\[\]/\'\"\{\}\n\r]+ YY_OBS_GROW; [^$@\[\]/\'\"\{\}\n\r]+ YY_OBS_GROW;
{eols} YY_OBS_GROW; YY_LINES; {eols} YY_OBS_GROW; YY_LINES;
@@ -532,7 +523,7 @@ blanks [ \t\f]+
| Output to the STRING_OBSTACK a reference to this semantic value. | | Output to the STRING_OBSTACK a reference to this semantic value. |
`------------------------------------------------------------------*/ `------------------------------------------------------------------*/
static void static inline void
handle_action_dollar (char *cp, location_t location) handle_action_dollar (char *cp, location_t location)
{ {
const char *type_name = NULL; const char *type_name = NULL;
@@ -596,21 +587,17 @@ handle_action_dollar (char *cp, location_t location)
} }
/*---------------------------------------------------------------. /*---------------------------------------.
| CP is pointing to $$ in a destructor. This should probably be | | CP is pointing to $$ in a destructor. |
| done once the grammar completely parsed, instead of during its | `---------------------------------------*/
| parsing, since that means %type must be specified before |
| %destructor. |
`---------------------------------------------------------------*/
static void static inline void
handle_destructor_dollar (char *cp, location_t location) handle_destructor_dollar (char *cp, location_t location)
{ {
++cp; ++cp;
if (*cp == '$') if (*cp == '$')
{ {
/* FIXME: We should find something more robust. */ obstack_sgrow (&string_obstack, "]b4_dollar_dollar[");
obstack_sgrow (&string_obstack, "b4_dollar_dollar");
} }
else else
{ {
@@ -620,32 +607,55 @@ handle_destructor_dollar (char *cp, location_t location)
} }
} }
/*-------------------------------------------------------.
| CP is pointing to a location (i.e., a `@'). Output to | /*-----------------------------------------------------------------.
| STRING_OBSTACK a reference to this location. | | Dispatch onto handle_action_dollar, or handle_destructor_dollar, |
`-------------------------------------------------------*/ | depending upon CODE_KIND. |
`-----------------------------------------------------------------*/
static void static void
handle_at (char *cp) handle_dollar (braced_code_t braced_code_kind,
char *text, location_t location)
{
switch (braced_code_kind)
{
case action_braced_code:
handle_action_dollar (text, location);
break;
case destructor_braced_code:
handle_destructor_dollar (text, location);
break;
}
}
/*------------------------------------------------------.
| TEXT is a location token (i.e., a `@...'). Output to |
| STRING_OBSTACK a reference to this location. |
`------------------------------------------------------*/
static inline void
handle_action_at (char *text, location_t location)
{ {
locations_flag = 1; locations_flag = 1;
++cp; ++text;
if (*cp == '$') if (*text == '$')
{ {
obstack_sgrow (&string_obstack, "]b4_lhs_location["); obstack_sgrow (&string_obstack, "]b4_lhs_location[");
} }
else if (isdigit (*cp) || *cp == '-') else if (isdigit (*text) || *text == '-')
{ {
/* RULE_LENGTH is the number of values in the current rule so /* RULE_LENGTH is the number of values in the current rule so
far, which says where to find `$0' with respect to the top of far, which says where to find `$0' with respect to the top of
the stack. It is not the same as the rule->length in the the stack. It is not the same as the rule->length in the
case of mid rule actions. */ case of mid rule actions. */
int rule_length = symbol_list_length (current_rule->next); int rule_length = symbol_list_length (current_rule->next);
int n = strtol (cp, &cp, 10); int n = strtol (text, &text, 10);
if (n > rule_length) if (n > rule_length)
complain (_("invalid value: %s%d"), "@", n); complain_at (location, _("invalid value: %s%d"), "@", n);
else else
obstack_fgrow2 (&string_obstack, "]b4_rhs_location([%d], [%d])[", obstack_fgrow2 (&string_obstack, "]b4_rhs_location([%d], [%d])[",
rule_length, n); rule_length, n);
@@ -653,11 +663,59 @@ handle_at (char *cp)
else else
{ {
char buf[] = "@c"; char buf[] = "@c";
buf[1] = *cp; buf[1] = *text;
complain (_("%s is invalid"), quote (buf)); complain_at (location, _("%s is invalid"), quote (buf));
} }
} }
/*--------------------------------------------.
| TEXT is expexted tp be @$ in a destructor. |
`--------------------------------------------*/
static inline void
handle_destructor_at (char *text, location_t location)
{
++text;
if (*text == '$')
{
obstack_sgrow (&string_obstack, "]b4_at_dollar[");
}
else
{
char buf[] = "$c";
buf[1] = *text;
complain_at (location, _("%s is invalid"), quote (buf));
}
}
/*-------------------------------------------------------------------.
| Dispatch onto handle_action_at, or handle_destructor_at, depending |
| upon CODE_KIND. |
`-------------------------------------------------------------------*/
static void
handle_at (braced_code_t braced_code_kind,
char *text, location_t location)
{
switch (braced_code_kind)
{
case action_braced_code:
handle_action_at (text, location);
break;
case destructor_braced_code:
handle_destructor_at (text, location);
break;
}
}
/*-------------------------.
| Initialize the scanner. |
`-------------------------*/
void void
scanner_initialize (void) scanner_initialize (void)
{ {
@@ -665,6 +723,10 @@ scanner_initialize (void)
} }
/*-----------------------------------------------.
| Free all the memory allocated to the scanner. |
`-----------------------------------------------*/
void void
scanner_free (void) scanner_free (void)
{ {

View File

@@ -75,7 +75,7 @@ exp: { @$ = @1 ; };
]]) ]])
AT_CHECK([bison input.y], [1], [], AT_CHECK([bison input.y], [1], [],
[[input.y:2: invalid value: @1 [[input.y:2.6-14: invalid value: @1
]]) ]])
AT_CLEANUP AT_CLEANUP