* src/reader.c (grammar_current_rule_prec_set).

(grammar_current_rule_check): New, eved out from...
(readgram): here.
Remove `xaction', `first_rhs': useless.
* tests/input.at (Type clashes): New.
* tests/existing.at (GNU Cim Grammar): Adjust.
This commit is contained in:
Akim Demaille
2002-06-11 08:08:22 +00:00
parent 1485e106a4
commit 9af3fbce7c
5 changed files with 95 additions and 37 deletions

View File

@@ -1,3 +1,12 @@
2002-06-11 Akim Demaille <akim@epita.fr>
* src/reader.c (grammar_current_rule_prec_set).
(grammar_current_rule_check): New, eved out from...
(readgram): here.
Remove `xaction', `first_rhs': useless.
* tests/input.at (Type clashes): New.
* tests/existing.at (GNU Cim Grammar): Adjust.
2002-06-11 Akim Demaille <akim@epita.fr> 2002-06-11 Akim Demaille <akim@epita.fr>
* src/reader.c (grammar_midrule_action): New, Eved out from * src/reader.c (grammar_midrule_action): New, Eved out from

9
NEWS
View File

@@ -96,6 +96,15 @@ Changes in version 1.49b:
Bison used to systematically output this information on top of Bison used to systematically output this information on top of
the report. Solved conflicts are now attached to their states. the report. Solved conflicts are now attached to their states.
* Type clashes
Previous versions don't complain when there is a type clash on
the default action if the rule has a mid-rule action, such as in:
%type <foo> bar
%%
bar: '0' {} '0';
This is fixed.
Changes in version 1.35, 2002-03-25: Changes in version 1.35, 2002-03-25:

View File

@@ -972,8 +972,6 @@ read_declarations (void)
| which says where to find `$0' with respect to the top of the | | 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 case of mid | | stack. It is not the same as the rule->length in the case of mid |
| rule actions. | | rule actions. |
| |
| This routine is used for actions. |
`------------------------------------------------------------------*/ `------------------------------------------------------------------*/
static void static void
@@ -1169,6 +1167,48 @@ grammar_midrule_action (void)
grammar_symbol_append (sdummy); grammar_symbol_append (sdummy);
} }
/* Set the precedence symbol of the current rule to PRECSYM. */
static void
grammar_current_rule_prec_set (symbol_t *precsym)
{
if (current_rule->ruleprec)
complain (_("two @prec's in a row"));
current_rule->ruleprec = precsym;
}
/* Check that the last rule (CURRENT_RULE) is properly defined. For
instance, there should be no type clash on the default action. */
static void
grammar_current_rule_check (void)
{
symbol_t *lhs = current_rule->sym;
symbol_t *first_rhs = current_rule->next->sym;
/* If there is an action, then there is nothing we can do: the user
is allowed to shoot in her foot. */
if (current_rule->action)
return;
/* If $$ is being set in default way, report if any type mismatch.
*/
if (first_rhs)
{
const char *lhs_type = lhs->type_name ? lhs->type_name : "";
const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : "";
if (strcmp (lhs_type, rhs_type))
complain (_("type clash (`%s' `%s') on default action"),
lhs_type, rhs_type);
}
/* Warn if there is no default for $$ but we need one. */
else
{
if (lhs->type_name)
complain (_("empty rule for typed nonterminal, and no action"));
}
}
static void static void
readgram (void) readgram (void)
@@ -1184,8 +1224,6 @@ readgram (void)
int action_flag = 0; int action_flag = 0;
/* Number of symbols in rhs of this rule so far */ /* Number of symbols in rhs of this rule so far */
int rulelength = 0; int rulelength = 0;
int xactions = 0; /* JF for error checking */
symbol_t *first_rhs = 0;
if (t == tok_identifier) if (t == tok_identifier)
{ {
@@ -1213,7 +1251,7 @@ readgram (void)
if (t == tok_prec) if (t == tok_prec)
{ {
t = lex (); t = lex ();
current_rule->ruleprec = symval; grammar_current_rule_prec_set (symval);
t = lex (); t = lex ();
} }
@@ -1236,11 +1274,8 @@ readgram (void)
warn (_("previous rule lacks an ending `;'")); warn (_("previous rule lacks an ending `;'"));
break; break;
} }
/* Not followed by colon => process as part of this
if (!first_rhs) /* JF */ rule's rhs. */
first_rhs = symval;
/* Not followed by colon =>
process as part of this rule's rhs. */
} }
/* If we just passed an action, that action was in the middle /* If we just passed an action, that action was in the middle
@@ -1261,7 +1296,6 @@ readgram (void)
{ {
parse_action (current_rule, rulelength); parse_action (current_rule, rulelength);
action_flag = 1; action_flag = 1;
++xactions; /* JF */
} }
++rulelength; ++rulelength;
} /* end of read rhs of rule */ } /* end of read rhs of rule */
@@ -1271,37 +1305,20 @@ readgram (void)
if (t == tok_prec) if (t == tok_prec)
{ {
complain (_("two @prec's in a row"));
t = lex (); t = lex ();
current_rule->ruleprec = symval; grammar_current_rule_prec_set (symval);
t = lex (); t = lex ();
} }
if (t == tok_left_curly) if (t == tok_left_curly)
{ {
/* This case never occurs -wjh */
if (action_flag)
complain (_("two actions at end of one rule"));
parse_action (current_rule, rulelength); parse_action (current_rule, rulelength);
action_flag = 1; action_flag = 1;
++xactions; /* -wjh */
t = lex (); t = lex ();
} }
/* If $$ is being set in default way, report if any type
mismatch. */ grammar_current_rule_check ();
else if (!xactions
&& first_rhs && lhs->type_name != first_rhs->type_name)
{
if (lhs->type_name == 0
|| first_rhs->type_name == 0
|| strcmp (lhs->type_name, first_rhs->type_name))
complain (_("type clash (`%s' `%s') on default action"),
lhs->type_name ? lhs->type_name : "",
first_rhs->type_name ? first_rhs->type_name : "");
}
/* Warn if there is no default for $$ but we need one. */
else if (!xactions && !first_rhs && lhs->type_name != 0)
complain (_("empty rule for typed nonterminal, and no action"));
if (t == tok_two_percents || t == tok_eof) if (t == tok_two_percents || t == tok_eof)
warn (_("previous rule lacks an ending `;'")); warn (_("previous rule lacks an ending `;'"));
if (t == tok_semicolon) if (t == tok_semicolon)

View File

@@ -907,7 +907,7 @@ MBEE_LISTV : /*EMPT*/
LISTV : HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);} LISTV : HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);}
| FPP_CATEG HDOTDOTDOT { regDecl(varargsid, TVARARGS, KNOKD, categ);} | FPP_CATEG HDOTDOTDOT { regDecl(varargsid, TVARARGS, KNOKD, categ);}
| HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);} | HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);}
HPAREXPSEPARATOR LISTV HPAREXPSEPARATOR LISTV {}
| FPP_SPEC | FPP_SPEC
| FPP_SPEC | FPP_SPEC
HPAREXPSEPARATOR LISTV HPAREXPSEPARATOR LISTV
@@ -947,7 +947,7 @@ FPP_PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE
IDENTIFIER_LISTV: HIDENTIFIER { regDecl($1, type, kind, categ);} IDENTIFIER_LISTV: HIDENTIFIER { regDecl($1, type, kind, categ);}
| HDOTDOTDOT { regDecl(varargsid, TVARARGS, kind, categ);} | HDOTDOTDOT { regDecl(varargsid, TVARARGS, kind, categ);}
| HIDENTIFIER { regDecl($1, type, kind, categ);} | HIDENTIFIER { regDecl($1, type, kind, categ);}
HPAREXPSEPARATOR IDENTIFIER_LISTV HPAREXPSEPARATOR IDENTIFIER_LISTV {}
; ;
MBEE_MODE_PART : /*EMPT*/ MBEE_MODE_PART : /*EMPT*/
| MODE_PART | MODE_PART
@@ -1153,7 +1153,7 @@ EXPRESSION_SIMP : EXPRESSION_SIMP
| HNONE { mout(MNONE);$$=NULL;} | HNONE { mout(MNONE);$$=NULL;}
| HIDENTIFIER | HIDENTIFIER
{ $<ident>$=$1;} { $<ident>$=$1;}
MBEE_ARG_R_PT MBEE_ARG_R_PT {}
| HTHIS HIDENTIFIER { mout(MTHIS); | HTHIS HIDENTIFIER { mout(MTHIS);
moutId($2);$$=NULL;} moutId($2);$$=NULL;}
| HNEW | HNEW

View File

@@ -24,7 +24,6 @@ AT_BANNER([[Input Processing.]])
## Invalid $n. ## ## Invalid $n. ##
## ------------ ## ## ------------ ##
AT_SETUP([Invalid $n]) AT_SETUP([Invalid $n])
AT_DATA([input.y], AT_DATA([input.y],
@@ -43,7 +42,6 @@ AT_CLEANUP
## Invalid @n. ## ## Invalid @n. ##
## ------------ ## ## ------------ ##
AT_SETUP([Invalid @n]) AT_SETUP([Invalid @n])
AT_DATA([input.y], AT_DATA([input.y],
@@ -56,3 +54,28 @@ AT_CHECK([bison input.y], [1], [],
]]) ]])
AT_CLEANUP AT_CLEANUP
## -------------- ##
## Type clashes. ##
## -------------- ##
AT_SETUP([Type clashes])
AT_DATA([input.y],
[[%token foo
%type <bar> exp
%%
exp: foo {} foo
| foo
| /* Empty. */
;
]])
AT_CHECK([bison input.y], [1], [],
[[input.y:5: type clash (`bar' `') on default action
input.y:6: type clash (`bar' `') on default action
input.y:7: empty rule for typed nonterminal, and no action
]])
AT_CLEANUP