mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-10 12:53:03 +00:00
* NEWS: Instead of %union, you can define and use your own union type
YYSTYPE if your grammar contains at least one <type> tag. Your YYSTYPE need not be a macro; it can be a typedef. * doc/bison.texinfo (Value Type, Multiple Types, Location Type): (Union Decl, Decl Summary): Document this. * data/glr.c (YYSTYPE): Implement this. * data/glr.cc (YYSTYPE): Likewise. * data/lalr1.cc (YYSTYPE): Likewise. * data/yacc.c (YYSTYPE): Likewise. * src/output.c (prepare): Output tag_seen_flag. * src/parse-gram.y (declaration, grammar_declaration): Use 'union_seen' rather than 'typed' to determine whether %union has been seen, since grammars can now be typed without %union. (symbol_declaration, type.opt, symbol_def): Keep track of whether a tag has been seen. * src/reader.c (union_seen, tag_seen): New vars. (typed): remove. * src/reader.h (union_seen, tag_seen, typed): Likewise. * src/scan-code.l (untyped_var_seen): New variable. (handle_action_dollar): Adjust to above changes. (handle_action_dollar, handle_action_at): Improve overflow checking for outlandish numbers. * tests/input.at (AT_CHECK_UNUSED_VALUES): Redo test to avoid new diagnostics generated by above changes. * tests/regression.at (YYSTYPE typedef): Add test to check for type tags without %union.
This commit is contained in:
@@ -590,6 +590,7 @@ prepare (void)
|
||||
MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
|
||||
MUSCLE_INSERT_BOOL ("pure_flag", pure_parser);
|
||||
MUSCLE_INSERT_BOOL ("synclines_flag", !no_lines_flag);
|
||||
MUSCLE_INSERT_BOOL ("tag_seen_flag", tag_seen);
|
||||
MUSCLE_INSERT_BOOL ("yacc_flag", yacc_flag);
|
||||
|
||||
/* File names. */
|
||||
|
||||
@@ -57,7 +57,7 @@ static char const *char_name (char);
|
||||
static void add_param (char const *, char *, location);
|
||||
|
||||
static symbol_class current_class = unknown_sym;
|
||||
static uniqstr current_type = 0;
|
||||
static uniqstr current_type = NULL;
|
||||
static symbol *current_lhs;
|
||||
static location current_lhs_location;
|
||||
static int current_prec = 0;
|
||||
@@ -209,7 +209,7 @@ declaration:
|
||||
grammar_declaration
|
||||
| PROLOGUE
|
||||
{
|
||||
prologue_augment (translate_code ($1, @1), @1, typed);
|
||||
prologue_augment (translate_code ($1, @1), @1, union_seen);
|
||||
}
|
||||
| "%after-header" "{...}"
|
||||
{
|
||||
@@ -322,7 +322,7 @@ grammar_declaration:
|
||||
{
|
||||
char const *body = $3;
|
||||
|
||||
if (typed)
|
||||
if (union_seen)
|
||||
{
|
||||
/* Concatenate the union bodies, turning the first one's
|
||||
trailing '}' into '\n', and omitting the second one's '{'. */
|
||||
@@ -331,7 +331,7 @@ grammar_declaration:
|
||||
body++;
|
||||
}
|
||||
|
||||
typed = true;
|
||||
union_seen = true;
|
||||
muscle_code_grow ("stype", body, @3);
|
||||
}
|
||||
;
|
||||
@@ -352,6 +352,7 @@ symbol_declaration:
|
||||
}
|
||||
| "%type" TYPE symbols.1
|
||||
{
|
||||
tag_seen = true;
|
||||
symbol_list *list;
|
||||
for (list = $3; list; list = list->next)
|
||||
symbol_type_set (list->sym, $2, @2);
|
||||
@@ -382,7 +383,7 @@ precedence_declarator:
|
||||
|
||||
type.opt:
|
||||
/* Nothing. */ { current_type = NULL; }
|
||||
| TYPE { current_type = $1; }
|
||||
| TYPE { current_type = $1; tag_seen = true; }
|
||||
;
|
||||
|
||||
/* One or more nonterminals to be %typed. */
|
||||
@@ -396,6 +397,7 @@ symbol_def:
|
||||
TYPE
|
||||
{
|
||||
current_type = $1;
|
||||
tag_seen = true;
|
||||
}
|
||||
| id
|
||||
{
|
||||
|
||||
@@ -45,7 +45,10 @@ static bool start_flag = false;
|
||||
merger_list *merge_functions;
|
||||
|
||||
/* Was %union seen? */
|
||||
bool typed = false;
|
||||
bool union_seen = false;
|
||||
|
||||
/* Was a tag seen? */
|
||||
bool tag_seen = false;
|
||||
|
||||
/* Should rules have a default precedence? */
|
||||
bool default_prec = true;
|
||||
|
||||
@@ -59,7 +59,10 @@ void free_merger_functions (void);
|
||||
extern merger_list *merge_functions;
|
||||
|
||||
/* Was %union seen? */
|
||||
extern bool typed;
|
||||
extern bool union_seen;
|
||||
|
||||
/* Was a tag seen? */
|
||||
extern bool tag_seen;
|
||||
|
||||
/* Should rules have a default precedence? */
|
||||
extern bool default_prec;
|
||||
|
||||
@@ -55,6 +55,9 @@ static void handle_action_dollar (symbol_list *rule, char *cp,
|
||||
static void handle_action_at (symbol_list *rule, char *cp, location at_loc);
|
||||
static location the_location;
|
||||
static location *loc = &the_location;
|
||||
|
||||
/* True if an untyped $$ or $n was seen. */
|
||||
static bool untyped_var_seen;
|
||||
%}
|
||||
/* C and C++ comments in code. */
|
||||
%x SC_COMMENT SC_LINE_COMMENT
|
||||
@@ -262,48 +265,62 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc)
|
||||
++cp;
|
||||
*cp = '\0';
|
||||
++cp;
|
||||
if (untyped_var_seen)
|
||||
complain_at (dollar_loc, _("explicit type given in untyped grammar"));
|
||||
tag_seen = true;
|
||||
}
|
||||
|
||||
if (*cp == '$')
|
||||
{
|
||||
if (!type_name)
|
||||
type_name = symbol_list_n_type_name_get (rule, dollar_loc, 0);
|
||||
if (!type_name && typed)
|
||||
{
|
||||
if (rule->midrule_parent_rule)
|
||||
complain_at (dollar_loc,
|
||||
_("$$ for the midrule at $%d of `%s' has no declared"
|
||||
" type"),
|
||||
rule->midrule_parent_rhs_index,
|
||||
effective_rule->sym->tag);
|
||||
else
|
||||
complain_at (dollar_loc, _("$$ of `%s' has no declared type"),
|
||||
rule->sym->tag);
|
||||
}
|
||||
|
||||
if (!type_name)
|
||||
type_name = "";
|
||||
{
|
||||
if (union_seen | tag_seen)
|
||||
{
|
||||
if (rule->midrule_parent_rule)
|
||||
complain_at (dollar_loc,
|
||||
_("$$ for the midrule at $%d of `%s'"
|
||||
" has no declared type"),
|
||||
rule->midrule_parent_rhs_index,
|
||||
effective_rule->sym->tag);
|
||||
else
|
||||
complain_at (dollar_loc, _("$$ of `%s' has no declared type"),
|
||||
rule->sym->tag);
|
||||
}
|
||||
else
|
||||
untyped_var_seen = true;
|
||||
type_name = "";
|
||||
}
|
||||
|
||||
obstack_fgrow1 (&obstack_for_string,
|
||||
"]b4_lhs_value([%s])[", type_name);
|
||||
rule->used = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
long int num;
|
||||
set_errno (0);
|
||||
num = strtol (cp, 0, 10);
|
||||
if (INT_MIN <= num && num <= effective_rule_length && ! get_errno ())
|
||||
long int num = strtol (cp, NULL, 10);
|
||||
|
||||
if (1 - INT_MAX + effective_rule_length <= num
|
||||
&& num <= effective_rule_length)
|
||||
{
|
||||
int n = num;
|
||||
if (1-n > max_left_semantic_context)
|
||||
max_left_semantic_context = 1-n;
|
||||
if (!type_name && n > 0)
|
||||
if (max_left_semantic_context < 1 - n)
|
||||
max_left_semantic_context = 1 - n;
|
||||
if (!type_name && 0 < n)
|
||||
type_name =
|
||||
symbol_list_n_type_name_get (effective_rule, dollar_loc, n);
|
||||
if (!type_name && typed)
|
||||
complain_at (dollar_loc, _("$%d of `%s' has no declared type"),
|
||||
n, effective_rule->sym->tag);
|
||||
if (!type_name)
|
||||
type_name = "";
|
||||
{
|
||||
if (union_seen | tag_seen)
|
||||
complain_at (dollar_loc, _("$%d of `%s' has no declared type"),
|
||||
n, effective_rule->sym->tag);
|
||||
else
|
||||
untyped_var_seen = true;
|
||||
type_name = "";
|
||||
}
|
||||
|
||||
obstack_fgrow3 (&obstack_for_string,
|
||||
"]b4_rhs_value(%d, %d, [%s])[",
|
||||
effective_rule_length, n, type_name);
|
||||
@@ -336,11 +353,10 @@ handle_action_at (symbol_list *rule, char *text, location at_loc)
|
||||
obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
|
||||
else
|
||||
{
|
||||
long int num;
|
||||
set_errno (0);
|
||||
num = strtol (cp, 0, 10);
|
||||
long int num = strtol (cp, NULL, 10);
|
||||
|
||||
if (INT_MIN <= num && num <= effective_rule_length && ! get_errno ())
|
||||
if (1 - INT_MAX + effective_rule_length <= num
|
||||
&& num <= effective_rule_length)
|
||||
{
|
||||
int n = num;
|
||||
obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
|
||||
@@ -356,9 +372,9 @@ 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 l.
|
||||
Depending on the \a sc_context (SC_RULE_ACTION, SC_SYMBOL_ACTION,
|
||||
INITIAL), the processing is different. */
|
||||
/* 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
|
||||
(SC_RULE_ACTION, SC_SYMBOL_ACTION, INITIAL). */
|
||||
|
||||
static const char *
|
||||
translate_action (int sc_context, symbol_list *rule, const char *a, location l)
|
||||
|
||||
Reference in New Issue
Block a user