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 */