mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-18 00:33:03 +00:00
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:
16
ChangeLog
16
ChangeLog
@@ -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
|
||||||
|
|||||||
@@ -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])])
|
||||||
|
|||||||
174
src/scan-gram.c
174
src/scan-gram.c
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
140
src/scan-gram.l
140
src/scan-gram.l
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user