Module Name:    src
Committed By:   rillig
Date:           Sun Jul 11 16:57:21 UTC 2021

Modified Files:
        src/usr.bin/xlint/lint1: cgram.y

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.306 -r1.307 src/usr.bin/xlint/lint1/cgram.y

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/xlint/lint1/cgram.y
diff -u src/usr.bin/xlint/lint1/cgram.y:1.306 src/usr.bin/xlint/lint1/cgram.y:1.307
--- src/usr.bin/xlint/lint1/cgram.y:1.306	Sun Jul 11 15:07:39 2021
+++ src/usr.bin/xlint/lint1/cgram.y	Sun Jul 11 16:57:21 2021
@@ -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 @@ anonymize(sym_t *s)
 
 %}
 
-%expect 178
+%expect 173
 
 %union {
 	val_t	*y_val;
@@ -278,6 +278,9 @@ anonymize(sym_t *s)
 %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 @@ assignment_expression:		/* C99 6.5.16 */
 	  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);
 	  }
-	| string {
-		$$ = new_string_node($1);
-	  }
 	| T_CON {
 		$$ = expr_new_constant(gettyp($1->v_tspec), $1);
 	  }
+	| string {
+		$$ = new_string_node($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 @@ term:				/* see C99 6.5.1 */
 		$$ = 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 @@ term:				/* see C99 6.5.1 */
 		}
 		$$ = 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 @@ term:				/* see C99 6.5.1 */
 	| 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 */

Reply via email to