From: Akim Demaille Date: Tue, 11 Jun 2002 08:08:22 +0000 (+0000) Subject: * src/reader.c (grammar_current_rule_prec_set). X-Git-Tag: BISON-1_49b~192 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/9af3fbce7c5f893ab9cd72b924e154d01f1f9190 * 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. --- diff --git a/ChangeLog b/ChangeLog index 300da61b..4c99aa23 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2002-06-11 Akim Demaille + + * 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 * src/reader.c (grammar_midrule_action): New, Eved out from diff --git a/NEWS b/NEWS index e4acf388..64258f23 100644 --- a/NEWS +++ b/NEWS @@ -96,6 +96,15 @@ Changes in version 1.49b: Bison used to systematically output this information on top of 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 bar + %% + bar: '0' {} '0'; + + This is fixed. Changes in version 1.35, 2002-03-25: diff --git a/src/reader.c b/src/reader.c index 949d74bb..42a48ee7 100644 --- a/src/reader.c +++ b/src/reader.c @@ -972,8 +972,6 @@ read_declarations (void) | 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 | | rule actions. | -| | -| This routine is used for actions. | `------------------------------------------------------------------*/ static void @@ -1169,6 +1167,48 @@ grammar_midrule_action (void) 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 readgram (void) @@ -1184,8 +1224,6 @@ readgram (void) int action_flag = 0; /* Number of symbols in rhs of this rule so far */ int rulelength = 0; - int xactions = 0; /* JF for error checking */ - symbol_t *first_rhs = 0; if (t == tok_identifier) { @@ -1213,7 +1251,7 @@ readgram (void) if (t == tok_prec) { t = lex (); - current_rule->ruleprec = symval; + grammar_current_rule_prec_set (symval); t = lex (); } @@ -1236,11 +1274,8 @@ readgram (void) warn (_("previous rule lacks an ending `;'")); break; } - - if (!first_rhs) /* JF */ - first_rhs = symval; - /* Not followed by colon => - process as part of this rule's rhs. */ + /* Not followed by colon => process as part of this + rule's rhs. */ } /* If we just passed an action, that action was in the middle @@ -1261,7 +1296,6 @@ readgram (void) { parse_action (current_rule, rulelength); action_flag = 1; - ++xactions; /* JF */ } ++rulelength; } /* end of read rhs of rule */ @@ -1271,37 +1305,20 @@ readgram (void) if (t == tok_prec) { - complain (_("two @prec's in a row")); t = lex (); - current_rule->ruleprec = symval; + grammar_current_rule_prec_set (symval); t = lex (); } 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); action_flag = 1; - ++xactions; /* -wjh */ t = lex (); } - /* If $$ is being set in default way, report if any type - mismatch. */ - 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")); + + grammar_current_rule_check (); + if (t == tok_two_percents || t == tok_eof) warn (_("previous rule lacks an ending `;'")); if (t == tok_semicolon) diff --git a/tests/existing.at b/tests/existing.at index 3f6612f7..6a1f7f39 100644 --- a/tests/existing.at +++ b/tests/existing.at @@ -907,7 +907,7 @@ MBEE_LISTV : /*EMPT*/ LISTV : HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);} | FPP_CATEG HDOTDOTDOT { regDecl(varargsid, TVARARGS, KNOKD, categ);} | HIDENTIFIER { regDecl($1, type, KNOKD, CDEFLT);} - HPAREXPSEPARATOR LISTV + HPAREXPSEPARATOR LISTV {} | FPP_SPEC | FPP_SPEC HPAREXPSEPARATOR LISTV @@ -947,7 +947,7 @@ FPP_PROC_DECL_IN_SPEC: MBEE_TYPE HPROCEDURE IDENTIFIER_LISTV: HIDENTIFIER { regDecl($1, type, kind, categ);} | HDOTDOTDOT { regDecl(varargsid, TVARARGS, kind, categ);} | HIDENTIFIER { regDecl($1, type, kind, categ);} - HPAREXPSEPARATOR IDENTIFIER_LISTV + HPAREXPSEPARATOR IDENTIFIER_LISTV {} ; MBEE_MODE_PART : /*EMPT*/ | MODE_PART @@ -1153,7 +1153,7 @@ EXPRESSION_SIMP : EXPRESSION_SIMP | HNONE { mout(MNONE);$$=NULL;} | HIDENTIFIER { $$=$1;} - MBEE_ARG_R_PT + MBEE_ARG_R_PT {} | HTHIS HIDENTIFIER { mout(MTHIS); moutId($2);$$=NULL;} | HNEW diff --git a/tests/input.at b/tests/input.at index 2ee59f29..9c223d37 100644 --- a/tests/input.at +++ b/tests/input.at @@ -24,7 +24,6 @@ AT_BANNER([[Input Processing.]]) ## Invalid $n. ## ## ------------ ## - AT_SETUP([Invalid $n]) AT_DATA([input.y], @@ -43,7 +42,6 @@ AT_CLEANUP ## Invalid @n. ## ## ------------ ## - AT_SETUP([Invalid @n]) AT_DATA([input.y], @@ -56,3 +54,28 @@ AT_CHECK([bison input.y], [1], [], ]]) AT_CLEANUP + + +## -------------- ## +## Type clashes. ## +## -------------- ## + +AT_SETUP([Type clashes]) + +AT_DATA([input.y], +[[%token foo +%type 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