Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/xlint/lint1 lint: resolve shift/reduce conflicts for...



details:   https://anonhg.NetBSD.org/src/rev/36fd60245fc4
branches:  trunk
changeset: 1022285:36fd60245fc4
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sun Jul 11 16:57:21 2021 +0000

description:
lint: resolve shift/reduce conflicts for unary expressions

The grammar rule 'term' was ambiguous since both the prefix and postfix
increment operators were listed with the same precedence.  The
expression '++x++' was parsed as '++ (x++)', as expected, since
conflicts resolve towards shift.

Resolve these conflicts by structuring the grammar as in C99, with the
GCC extension of statement-expressions.  The resolved conflicts are:

134: shift/reduce conflict (shift 161, reduce 347) on T_LBRACK
134: shift/reduce conflict (shift 162, reduce 347) on T_LPAREN
134: shift/reduce conflict (shift 163, reduce 347) on T_POINT
134: shift/reduce conflict (shift 164, reduce 347) on T_ARROW
134: shift/reduce conflict (shift 165, reduce 347) on T_INCDEC
state 134
        term : term . T_INCDEC  (335)
        term : term . T_LBRACK expr T_RBRACK  (341)
        term : term . T_LPAREN T_RPAREN  (342)
        term : term . T_LPAREN argument_expression_list T_RPAREN  (343)
        term : term . point_or_arrow T_NAME  (344)
        term : T_EXTENSION term .  (347)

No functional change.

diffstat:

 usr.bin/xlint/lint1/cgram.y |  111 ++++++++++++++++++++++++-------------------
 1 files changed, 61 insertions(+), 50 deletions(-)

diffs (182 lines):

diff -r 0b21b1828769 -r 36fd60245fc4 usr.bin/xlint/lint1/cgram.y
--- a/usr.bin/xlint/lint1/cgram.y       Sun Jul 11 16:30:41 2021 +0000
+++ b/usr.bin/xlint/lint1/cgram.y       Sun Jul 11 16:57:21 2021 +0000
@@ -1,5 +1,5 @@
 %{
-/* $NetBSD: cgram.y,v 1.306 2021/07/11 15:07:39 rillig Exp $ */
+/* $NetBSD: cgram.y,v 1.307 2021/07/11 16:57:21 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: cgram.y,v 1.306 2021/07/11 15:07:39 rillig Exp $");
+__RCSID("$NetBSD: cgram.y,v 1.307 2021/07/11 16:57:21 rillig Exp $");
 #endif
 
 #include <limits.h>
@@ -124,7 +124,7 @@
 
 %}
 
-%expect 178
+%expect 173
 
 %union {
        val_t   *y_val;
@@ -278,6 +278,9 @@
 %token <y_val>         T_CON
 %token <y_string>      T_STRING
 
+%type  <y_tnode>       primary_expression
+%type  <y_tnode>       postfix_expression
+
 %type  <y_sym>         func_decl
 %type  <y_sym>         notype_decl
 %type  <y_sym>         type_decl
@@ -1724,24 +1727,71 @@
          expr %prec T_ASSIGN
        ;
 
-term:                          /* see C99 6.5.1 */
+primary_expression:            /* C99 6.5.1 */
          T_NAME {
                /* XXX really necessary? */
                if (yychar < 0)
                        yychar = yylex();
                $$ = new_name_node(getsym($1), yychar);
          }
+       | T_CON {
+               $$ = expr_new_constant(gettyp($1->v_tspec), $1);
+         }
        | string {
                $$ = new_string_node($1);
          }
-       | T_CON {
-               $$ = expr_new_constant(gettyp($1->v_tspec), $1);
-         }
        | T_LPAREN expr T_RPAREN {
                if ($2 != NULL)
                        $2->tn_parenthesized = true;
                $$ = $2;
          }
+       ;
+
+postfix_expression:            /* C99 6.5.2 */
+         primary_expression
+       | postfix_expression T_LBRACK expr T_RBRACK {
+               $$ = build(INDIR, build(PLUS, $1, $3), NULL);
+         }
+       | postfix_expression T_LPAREN T_RPAREN {
+               $$ = new_function_call_node($1, NULL);
+         }
+       | postfix_expression T_LPAREN argument_expression_list T_RPAREN {
+               $$ = new_function_call_node($1, $3);
+         }
+       | postfix_expression point_or_arrow T_NAME {
+               if ($1 != NULL) {
+                       sym_t   *msym;
+                       /*
+                        * XXX struct_or_union_member should be integrated
+                        * in build()
+                        */
+                       if ($2 == ARROW) {
+                               /*
+                                * must do this before struct_or_union_member
+                                * is called
+                                */
+                               $1 = cconv($1);
+                       }
+                       msym = struct_or_union_member($1, $2, getsym($3));
+                       $$ = build($2, $1, new_name_node(msym, 0));
+               } else {
+                       $$ = NULL;
+               }
+         }
+       | postfix_expression T_INCDEC {
+               $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
+         }
+       | T_LPAREN type_name T_RPAREN { /* C99 6.5.2.5 "Compound literals" */
+               sym_t *tmp = mktempsym($2);
+               begin_initialization(tmp);
+               cgram_declare(tmp, true, NULL);
+         } init_lbrace initializer_list comma_opt init_rbrace {
+               if (!Sflag)
+                        /* compound literals are a C9X/GCC extension */
+                        gnuism(319);
+               $$ = new_name_node(*current_initsym(), 0);
+               end_initialization();
+         }
        | T_LPAREN compound_statement_lbrace gcc_statement_expr_list {
                block_level--;
                mem_block_level--;
@@ -1754,9 +1804,10 @@
                $$ = new_name_node(*current_initsym(), 0);
                end_initialization();
         }
-       | term T_INCDEC {
-               $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
-         }
+       ;
+
+term:                          /* see C99 6.5.1 */
+         postfix_expression
        | T_INCDEC term {
                $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
          }
@@ -1776,35 +1827,6 @@
                }
                $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
          }
-       | term T_LBRACK expr T_RBRACK {
-               $$ = build(INDIR, build(PLUS, $1, $3), NULL);
-         }
-       | term T_LPAREN T_RPAREN {
-               $$ = new_function_call_node($1, NULL);
-         }
-       | term T_LPAREN argument_expression_list T_RPAREN {
-               $$ = new_function_call_node($1, $3);
-         }
-       | term point_or_arrow T_NAME {
-               if ($1 != NULL) {
-                       sym_t   *msym;
-                       /*
-                        * XXX struct_or_union_member should be integrated
-                        * in build()
-                        */
-                       if ($2 == ARROW) {
-                               /*
-                                * must do this before struct_or_union_member
-                                * is called
-                                */
-                               $1 = cconv($1);
-                       }
-                       msym = struct_or_union_member($1, $2, getsym($3));
-                       $$ = build($2, $1, new_name_node(msym, 0));
-               } else {
-                       $$ = NULL;
-               }
-         }
        | T_REAL term {
                $$ = build(REAL, $2, NULL);
          }
@@ -1838,17 +1860,6 @@
        | T_LPAREN type_name T_RPAREN term %prec T_UNARY {
                $$ = cast($4, $2);
          }
-       | T_LPAREN type_name T_RPAREN { /* C99 6.5.2.5 "Compound literals" */
-               sym_t *tmp = mktempsym($2);
-               begin_initialization(tmp);
-               cgram_declare(tmp, true, NULL);
-         } init_lbrace initializer_list comma_opt init_rbrace {
-               if (!Sflag)
-                        /* compound literals are a C9X/GCC extension */
-                        gnuism(319);
-               $$ = new_name_node(*current_initsym(), 0);
-               end_initialization();
-         }
        ;
 
 generic_selection:             /* C11 6.5.1.1 */



Home | Main Index | Thread Index | Old Index