# Checking diagnostics. -*- Autotest -*- # Copyright (C) 2019-2022 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . AT_BANNER([[Diagnostics.]]) # AT_TEST($1: TITLE, $2: GRAMMAR, $3: EXIT-STATUS, $4: OUTPUT-WITH-STYLE, # $5: EXTRA_ENV, $6: SKIP-IF) # ----------------------------------------------------------------------- # Run Bison on GRAMMAR with debugging style enabled, and expect # OUTPUT-WITH-STYLE as diagnostics. m4_pushdef([AT_TEST], [ AT_SETUP([$1]) AT_KEYWORDS([diagnostics]) m4_if(m4_index([$1], [Counterexample]), [-1], [], [AT_KEYWORDS([cex])]) # We need UTF-8 support for correct screen-width computation of UTF-8 # characters. Skip the test if not available. locale=`locale -a | $EGREP '^en_US\.(UTF-8|utf8)$' | sed 1q` AT_SKIP_IF([[test x = x"$locale"]]) m4_ifval([$6], [AT_SKIP_IF([$6])]) AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [$2]) AT_DATA([experr], [$4]) # For some reason, literal ^M in the input are removed and don't end # in `input.y`. So use the two-character ^M represent it, and let # Perl insert real CR characters. if $EGREP ['\^M|\\[0-9][0-9][0-9]'] input.y experr >/dev/null; then AT_PERL_REQUIRE([-pi -e 's{\^M}{\r}g;s{\\(\d{3}|.)}{$v = $[]1; $v =~ /\A\d+\z/ ? chr($v) : $v}ge' input.y experr]) fi AT_CHECK(AT_SET_ENV [LC_ALL="$locale" $5 bison -fcaret --color=debug -Wall,cex input.y], [$3], [], [experr]) # When no style, same messages, but without style. # Except for the second display of the counterexample, # which is not displayed at all. AT_PERL_REQUIRE([-pi -e ' s{()}{ $[]1 eq "" ? $[]1 : "" }ge; if (/Example/) { ++$example; $_ = "" if $example % 2 == 0; } ' experr]) # Cannot use AT_BISON_CHECK easily as we need to change the # environment. # FIXME: Enhance AT_BISON_CHECK. AT_CHECK(AT_SET_ENV [LC_ALL="$locale" $5 bison -fcaret -Wall,cex input.y], [$3], [], [experr]) AT_BISON_OPTION_POPDEFS AT_CLEANUP ]) ## ---------- ## ## Warnings. ## ## ---------- ## AT_TEST([[Warnings]], [[%token FOO FOO FOO %token FOO FOO FOO %% exp: %empty; ]], [0], [[input.y:9.12-14: warning: symbol FOO redeclared [-Wother] 9 | %token FOO FOO FOO | ^~~ input.y:9.8-10: note: previous declaration 9 | %token FOO FOO FOO | ^~~ input.y:9.16-18: warning: symbol FOO redeclared [-Wother] 9 | %token FOO FOO FOO | ^~~ input.y:9.8-10: note: previous declaration 9 | %token FOO FOO FOO | ^~~ input.y:10.8-10: warning: symbol FOO redeclared [-Wother] 10 | %token FOO FOO FOO | ^~~ input.y:9.8-10: note: previous declaration 9 | %token FOO FOO FOO | ^~~ input.y:10.13-15: warning: symbol FOO redeclared [-Wother] 10 | %token FOO FOO FOO | ^~~ input.y:9.8-10: note: previous declaration 9 | %token FOO FOO FOO | ^~~ input.y:10.18-20: warning: symbol FOO redeclared [-Wother] 10 | %token FOO FOO FOO | ^~~ input.y:9.8-10: note: previous declaration 9 | %token FOO FOO FOO | ^~~ ]]) ## ------------------------ ## ## Single point locations. ## ## ------------------------ ## # Single point locations (equal boundaries) are troublesome: it's easy # to mess up the opening/closing of style. They come from the parser, # rules with empty rhs. Their position is therefore debatable # (between the previous token and the next one). AT_TEST([[Single point locations]], [[%% exp: a b c d e a: {} b:{ }; c: d : e: ]], [0], [[input.y:11.4-5: warning: empty rule without %empty [-Wempty-rule] 11 | a: {} | ^~ | %empty input.y:12.3-13.1: warning: empty rule without %empty [-Wempty-rule] 12 | b:{ | ^ | %empty input.y:14.3: warning: empty rule without %empty [-Wempty-rule] 14 | c: | ^ | %empty input.y:16.2: warning: empty rule without %empty [-Wempty-rule] 16 | : | ^ | %empty input.y:17.3: warning: empty rule without %empty [-Wempty-rule] 17 | e: | ^ | %empty input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother] ]]) ## ------------------------------------- ## ## Line is too short, and then you die. ## ## ------------------------------------- ## # We trust the "#line", since that's what allows us to quote the # actual source from which the grammar file was generated. But #line # can also be wrong, and point to a line which is shorter that the bad # one. In which case we can easily forget to close the styling. # # Be sure to have #line point to a line long enough to open the # styling, but not enough to close it. AT_TEST([[Line is too short, and then you die]], [[// Beware that there are 9 lines inserted before (including this one). #line 12 %token foo 123 %token foo 123123 %token foo 123 %% exp: ]], [1], [[input.y:13.8-10: warning: symbol foo redeclared [-Wother] 13 | %token foo 123 | ^~~ input.y:12.8-10: note: previous declaration 12 | %token foo 123123 | ^~~ input.y:13.12-17: error: redefining code of token foo 13 | %token foo 123 | ^~~~~~ input.y:14.8-10: warning: symbol foo redeclared [-Wother] 14 | %% | ^~~ input.y:12.8-10: note: previous declaration 12 | %token foo 123123 | ^~~ ]]) ## ----------------------- ## ## Zero-width characters. ## ## ----------------------- ## # We used to open twice the styling for characters that have a # zero-width on display (e.g., \005). AT_TEST([[Zero-width characters]], [[%% exp: an\005error. ]], [1], [[input.y:10.8: error: invalid character: '\\005' 10 | exp: an\005error. | ^ ]]) ## -------------------------------------- ## ## Tabulations and multibyte characters. ## ## -------------------------------------- ## # Make sure we treat tabulations as eight spaces, and that multibyte # characters have correct width. AT_TEST([[Tabulations and multibyte characters]], [[%% exp: a b c d e f g a: { } b: { } c: {------------} d: {éééééééééééé} e: { 42 } f: { "฿¥$€₦" } g: { 🐃 } ]], [0], [[input.y:11.4-17: warning: empty rule without %empty [-Wempty-rule] 11 | a: { } | ^~~~~~~~~~~~~~ | %empty input.y:12.4-17: warning: empty rule without %empty [-Wempty-rule] 12 | b: { } | ^~~~~~~~~~~~~~ | %empty input.y:13.4-17: warning: empty rule without %empty [-Wempty-rule] 13 | c: {------------} | ^~~~~~~~~~~~~~ | %empty input.y:14.4-17: warning: empty rule without %empty [-Wempty-rule] 14 | d: {éééééééééééé} | ^~~~~~~~~~~~~~ | %empty input.y:15.4-17: warning: empty rule without %empty [-Wempty-rule] 15 | e: { 42 } | ^~~~~~~~~~~~~~ | %empty input.y:16.4-17: warning: empty rule without %empty [-Wempty-rule] 16 | f: { "฿¥$€₦" } | ^~~~~~~~~~~~~~ | %empty input.y:17.4-17: warning: empty rule without %empty [-Wempty-rule] 17 | g: { 🐃 } | ^~~~~~~~~~~~~~ | %empty input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother] ]]) # Likewise, but currently not portable to AIX and Cygwin. # https://lists.gnu.org/r/bug-bison/2020-05/msg00050.html # https://lists.gnu.org/r/bug-bison/2020-05/msg00003.html. AT_TEST([[Tabulations and multibyte characters]], [[%% e: {∇⃗×𝐸⃗ = -∂𝐵⃗/∂t} ]], [0], [[input.y:10.4-17: warning: empty rule without %empty [-Wempty-rule] 10 | e: {∇⃗×𝐸⃗ = -∂𝐵⃗/∂t} | ^~~~~~~~~~~~~~ | %empty input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother] ]], [], [uname -a | $EGREP -i 'aix|cygwin']) ## --------------- ## ## Special files. ## ## --------------- ## # Don't try to quote special files. # https://lists.gnu.org/r/bug-bison/2019-04/msg00000.html # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90034 AT_TEST([[Special files]], [[%% exp: a b a: {} #line 1 "/dev/stdout" b: {} ]], [0], [[input.y:11.4-5: warning: empty rule without %empty [-Wempty-rule] 11 | a: {} | ^~ | %empty /dev/stdout:1.4-5: warning: empty rule without %empty [-Wempty-rule] | %empty input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother] ]]) ## -------------------- ## ## Complaints from M4. ## ## -------------------- ## # Complaints issued m4 need complete locations (byte and column) for # diagnostics. AT_TEST([[Complaints from M4]], [[%define error1 {e} %define error2 {é} %% exp: %empty; ]], [1], [[input.y:9.1-27: error: %define variable 'error1' is not used 9 | %define error1 {e} | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:10.1-27: error: %define variable 'error2' is not used 10 | %define error2 {é} | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]) ## ----------------- ## ## Carriage return. ## ## ----------------- ## # Carriage-return used to count as a newline in the scanner, and not # in diagnostics. Resulting in all kinds of nice bugs. AT_TEST([[Carriage return]], [[^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M %token " %% ]], [1], [[input.y:10.8-11.0: error: missing '"' at end of line 10 | %token " | ^ input.y:10.8-11.0: error: expected character literal or identifier or before string 10 | %token " | ^ ]]) ## ------- ## ## CR NL. ## ## ------- ## # Check Windows EOLs. AT_TEST([[CR NL]], [[^M %token ^M FOO^M %token ^M FOO^M %%^M exp:^M ]], [0], [[input.y:11.9-11: warning: symbol FOO redeclared [-Wother] 11 | %token FOO | ^~~ input.y:10.9-11: note: previous declaration 10 | %token FOO | ^~~ input.y:13.5: warning: empty rule without %empty [-Wempty-rule] 13 | exp: | ^ | %empty input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother] ]]) ## -------------- ## ## Screen width. ## ## -------------- ## AT_TEST([[Screen width: 200 columns]], [[%token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ %error-verbose %% exp: ABCDEFGHIJKLMNOPQRSTUVWXYZ ]], [0], [[input.y:9.36-61: warning: symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [-Wother] 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.8-33: note: previous declaration 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.64-89: warning: symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [-Wother] 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.8-33: note: previous declaration 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.92-117: warning: symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [-Wother] 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.8-33: note: previous declaration 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:10.56-69: warning: deprecated directive: '%error-verbose', use '%define parse.error verbose' [-Wdeprecated] 10 | %error-verbose | ^~~~~~~~~~~~~~ | %define parse.error verbose input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother] ]], [[COLUMNS=200]]) AT_TEST([[Screen width: 80 columns]], [[%token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ %error-verbose %% exp: ABCDEFGHIJKLMNOPQRSTUVWXYZ ]], [0], [[input.y:9.36-61: warning: symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [-Wother] 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEF... | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.8-33: note: previous declaration 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEF... | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.64-89: warning: symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [-Wother] 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEF... | ^~~~~~ input.y:9.8-33: note: previous declaration 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEF... | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.92-117: warning: symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [-Wother] 9 | ...TUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.8-33: note: previous declaration 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEF... | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:10.56-69: warning: deprecated directive: '%error-verbose', use '%define parse.error verbose' [-Wdeprecated] 10 | %error-verbose | ^~~~~~~~~~~~~~ | %define parse.error verbose input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother] ]], [[COLUMNS=80]]) AT_TEST([[Screen width: 60 columns]], [[%token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ %error-verbose %% exp: ABCDEFGHIJKLMNOPQRSTUVWXYZ ]], [0], [[input.y:9.36-61: warning: symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [-Wother] 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMN... | ^~~~~~~~~~~~~~ input.y:9.8-33: note: previous declaration 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMN... | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.64-89: warning: symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [-Wother] 9 | ...TUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHI... | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.8-33: note: previous declaration 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMN... | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.92-117: warning: symbol ABCDEFGHIJKLMNOPQRSTUVWXYZ redeclared [-Wother] 9 | ...TUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:9.8-33: note: previous declaration 9 | %token ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMN... | ^~~~~~~~~~~~~~~~~~~~~~~~~~ input.y:10.56-69: warning: deprecated directive: '%error-verbose', use '%define parse.error verbose' [-Wdeprecated] 10 | ... %error-verbose | ^~~~~~~~~~~~~~ | %define parse.error verbose input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother] ]], [[COLUMNS=60]]) ## ------------- ## ## Suggestions. ## ## ------------- ## # Don't suggest to fix QUX with QUUX and QUUX with QUX... AT_TEST([[Suggestions]], [[%% res: QUX baz bar: QUUX ]], [1], [[input.y:10.6-8: error: symbol 'QUX' is used, but is not defined as a token and has no rules 10 | res: QUX baz | ^~~ input.y:10.10-12: error: symbol 'baz' is used, but is not defined as a token and has no rules; did you mean 'bar'? 10 | res: QUX baz | ^~~ | bar input.y:11.6-9: error: symbol 'QUUX' is used, but is not defined as a token and has no rules 11 | bar: QUUX | ^~~~ ]]) ## ----------------- ## ## Counterexamples. ## ## ----------------- ## AT_TEST([[Counterexamples]], [[%expect 0 %% exp : "if" exp "then" exp | "if" exp "then" exp "else" exp | exp "+" exp | "num" | empty "a" | "a" empty empty : %empty ]], [1], [[input.y: error: shift/reduce conflicts: 9 found, 0 expected input.y: warning: shift/reduce conflict on token "a" [-Wcounterexamples] Example: "a" Shift derivation exp ↳ 6: "a" empty ↳ 6: ε Example: "a" Reduce derivation exp ↳ 5: empty "a" ↳ 7: ε input.y: warning: shift/reduce conflict on token "a" [-Wcounterexamples] Example: "a" Shift derivation exp ↳ 6: "a" empty ↳ 6: ε Example: "a" Reduce derivation exp ↳ 5: empty "a" ↳ 7: ε input.y: warning: shift/reduce conflict on token "a" [-Wcounterexamples] Example: "a" Shift derivation exp ↳ 6: "a" empty ↳ 6: ε Example: "a" Reduce derivation exp ↳ 5: empty "a" ↳ 7: ε input.y: warning: shift/reduce conflict on token "a" [-Wcounterexamples] Example: "a" Shift derivation exp ↳ 6: "a" empty ↳ 6: ε Example: "a" Reduce derivation exp ↳ 5: empty "a" ↳ 7: ε input.y: warning: shift/reduce conflict on token "+" [-Wcounterexamples] Example: exp "+" exp "+" exp Shift derivation exp ↳ 3: exp "+" exp ↳ 3: exp "+" exp Example: exp "+" exp "+" exp Reduce derivation exp ↳ 3: exp "+" exp ↳ 3: exp "+" exp input.y: warning: shift/reduce conflict on token "else" [-Wcounterexamples] Example: "if" exp "then" "if" exp "then" exp "else" exp Shift derivation exp ↳ 1: "if" exp "then" exp ↳ 2: "if" exp "then" exp "else" exp Example: "if" exp "then" "if" exp "then" exp "else" exp Reduce derivation exp ↳ 2: "if" exp "then" exp "else" exp ↳ 1: "if" exp "then" exp input.y: warning: shift/reduce conflict on token "+" [-Wcounterexamples] Example: "if" exp "then" exp "+" exp Shift derivation exp ↳ 1: "if" exp "then" exp ↳ 3: exp "+" exp Example: "if" exp "then" exp "+" exp Reduce derivation exp ↳ 3: exp "+" exp ↳ 1: "if" exp "then" exp input.y: warning: shift/reduce conflict on token "a" [-Wcounterexamples] Example: "a" Shift derivation exp ↳ 6: "a" empty ↳ 6: ε Example: "a" Reduce derivation exp ↳ 5: empty "a" ↳ 7: ε input.y: warning: shift/reduce conflict on token "+" [-Wcounterexamples] Example: "if" exp "then" exp "else" exp "+" exp Shift derivation exp ↳ 2: "if" exp "then" exp "else" exp ↳ 3: exp "+" exp Example: "if" exp "then" exp "else" exp "+" exp Reduce derivation exp ↳ 3: exp "+" exp ↳ 2: "if" exp "then" exp "else" exp ]]) AT_TEST([[Deep Counterexamples]], [[%expect 0 %% exp: x1 e1 foo1 x1 | y1 e2 bar1 y1 foo1: foo2 foo2: foo3 foo3: x1 foo4 foo4: "quuux" bar1: bar2 bar2: bar3 bar3: y1 bar4 bar4: "quuux" x1: x2 x2: x3 x3: "X" y1: y2 y2: y3 y3: "X" e1: e2: ]], [1], [[input.y:30.4: warning: empty rule without %empty [-Wempty-rule] 30 | e1: | ^ | %empty input.y:31.4: warning: empty rule without %empty [-Wempty-rule] 31 | e2: | ^ | %empty input.y: error: reduce/reduce conflicts: 1 found, 0 expected input.y: warning: reduce/reduce conflict on token "X" [-Wcounterexamples] Example: "X" "X" "quuux" "X" First reduce derivation exp ↳ 1: x1 e1 foo1 x1 ↳ 11: x2 ↳ 1: ε ↳ 3: foo2 ↳ 11: x2 ↳ 12: x3 ↳ 4: foo3 ↳ 12: x3 ↳ 13: "X" ↳ 5: x1 foo4 ↳ 13: "X" ↳ 11: x2 ↳ 6: "quuux" ↳ 12: x3 ↳ 13: "X" Example: "X" "X" "quuux" "X" Second reduce derivation exp ↳ 2: y1 e2 bar1 y1 ↳ 14: y2 ↳ 2: ε ↳ 7: bar2 ↳ 14: y2 ↳ 15: y3 ↳ 8: bar3 ↳ 15: y3 ↳ 16: "X" ↳ 9: y1 bar4 ↳ 16: "X" ↳ 14: y2 ↳ 10: "quuux" ↳ 15: y3 ↳ 16: "X" input.y: warning: fix-its can be applied. Rerun with option '--update'. [-Wother] ]]) m4_popdef([AT_TEST]) ## -------------------------------------- ## ## Indentation with message suppression. ## ## -------------------------------------- ## AT_SETUP([[Indentation with message suppression]]) # https://lists.gnu.org/r/bug-bison/2019-08/msg00002.html AT_DATA([[input.y]], [[%define api.pure %pure-parser %error-verbose %% exp : '0' ]]) AT_BISON_CHECK([[-fcaret -Wno-other input.y]], [0], [], [[input.y:2.1-12: warning: deprecated directive: '%pure-parser', use '%define api.pure' [-Wdeprecated] 2 | %pure-parser | ^~~~~~~~~~~~ | %define api.pure input.y:3.1-14: warning: deprecated directive: '%error-verbose', use '%define parse.error verbose' [-Wdeprecated] 3 | %error-verbose | ^~~~~~~~~~~~~~ | %define parse.error verbose ]]) AT_CLEANUP