OLD | NEW |
(Empty) | |
| 1 # Exercising Bison on conflicts. -*- Autotest -*- |
| 2 |
| 3 # Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. |
| 4 |
| 5 # This program is free software: you can redistribute it and/or modify |
| 6 # it under the terms of the GNU General Public License as published by |
| 7 # the Free Software Foundation, either version 3 of the License, or |
| 8 # (at your option) any later version. |
| 9 # |
| 10 # This program is distributed in the hope that it will be useful, |
| 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 # GNU General Public License for more details. |
| 14 # |
| 15 # You should have received a copy of the GNU General Public License |
| 16 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 |
| 18 AT_BANNER([[Conflicts.]]) |
| 19 |
| 20 |
| 21 ## ---------------- ## |
| 22 ## S/R in initial. ## |
| 23 ## ---------------- ## |
| 24 |
| 25 # I once hacked Bison in such a way that it lost its reductions on the |
| 26 # initial state (because it was confusing it with the last state). It |
| 27 # took me a while to strip down my failures to this simple case. So |
| 28 # make sure it finds the s/r conflict below. |
| 29 |
| 30 AT_SETUP([S/R in initial]) |
| 31 |
| 32 AT_DATA([[input.y]], |
| 33 [[%expect 1 |
| 34 %% |
| 35 exp: e 'e'; |
| 36 e: 'e' | /* Nothing. */; |
| 37 ]]) |
| 38 |
| 39 AT_BISON_CHECK([-o input.c input.y], 0, [], |
| 40 [[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ |
| 41 ]]) |
| 42 |
| 43 AT_CLEANUP |
| 44 |
| 45 |
| 46 ## ------------------- ## |
| 47 ## %nonassoc and eof. ## |
| 48 ## ------------------- ## |
| 49 |
| 50 AT_SETUP([%nonassoc and eof]) |
| 51 |
| 52 AT_DATA_GRAMMAR([input.y], |
| 53 [[ |
| 54 %{ |
| 55 #include <stdio.h> |
| 56 #include <stdlib.h> |
| 57 #include <string.h> |
| 58 |
| 59 #define YYERROR_VERBOSE 1 |
| 60 static void |
| 61 yyerror (const char *msg) |
| 62 { |
| 63 fprintf (stderr, "%s\n", msg); |
| 64 } |
| 65 |
| 66 /* The current argument. */ |
| 67 static const char *input; |
| 68 |
| 69 static int |
| 70 yylex (void) |
| 71 { |
| 72 static size_t toknum; |
| 73 if (! (toknum <= strlen (input))) |
| 74 abort (); |
| 75 return input[toknum++]; |
| 76 } |
| 77 |
| 78 %} |
| 79 |
| 80 %nonassoc '<' '>' |
| 81 |
| 82 %% |
| 83 expr: expr '<' expr |
| 84 | expr '>' expr |
| 85 | '0' |
| 86 ; |
| 87 %% |
| 88 int |
| 89 main (int argc, const char *argv[]) |
| 90 { |
| 91 input = argc <= 1 ? "" : argv[1]; |
| 92 return yyparse (); |
| 93 } |
| 94 ]]) |
| 95 |
| 96 # Specify the output files to avoid problems on different file systems. |
| 97 AT_BISON_CHECK([-o input.c input.y]) |
| 98 AT_COMPILE([input]) |
| 99 |
| 100 AT_PARSER_CHECK([./input '0<0']) |
| 101 # FIXME: This is an actual bug, but a new one, in the sense that |
| 102 # no one has ever spotted it! The messages are *wrong*: there should |
| 103 # be nothing there, it should be expected eof. |
| 104 AT_PARSER_CHECK([./input '0<0<0'], [1], [], |
| 105 [syntax error, unexpected '<', expecting '<' or '>' |
| 106 ]) |
| 107 |
| 108 AT_PARSER_CHECK([./input '0>0']) |
| 109 AT_PARSER_CHECK([./input '0>0>0'], [1], [], |
| 110 [syntax error, unexpected '>', expecting '<' or '>' |
| 111 ]) |
| 112 |
| 113 AT_PARSER_CHECK([./input '0<0>0'], [1], [], |
| 114 [syntax error, unexpected '>', expecting '<' or '>' |
| 115 ]) |
| 116 |
| 117 AT_CLEANUP |
| 118 |
| 119 |
| 120 |
| 121 ## ------------------------- ## |
| 122 ## Unresolved SR Conflicts. ## |
| 123 ## ------------------------- ## |
| 124 |
| 125 AT_SETUP([Unresolved SR Conflicts]) |
| 126 |
| 127 AT_KEYWORDS([report]) |
| 128 |
| 129 AT_DATA([input.y], |
| 130 [[%token NUM OP |
| 131 %% |
| 132 exp: exp OP exp | NUM; |
| 133 ]]) |
| 134 |
| 135 AT_BISON_CHECK([-o input.c --report=all input.y], 0, [], |
| 136 [input.y: conflicts: 1 shift/reduce |
| 137 ]) |
| 138 |
| 139 # Check the contents of the report. |
| 140 AT_CHECK([cat input.output], [], |
| 141 [[State 5 conflicts: 1 shift/reduce |
| 142 |
| 143 |
| 144 Grammar |
| 145 |
| 146 0 $accept: exp $end |
| 147 |
| 148 1 exp: exp OP exp |
| 149 2 | NUM |
| 150 |
| 151 |
| 152 Terminals, with rules where they appear |
| 153 |
| 154 $end (0) 0 |
| 155 error (256) |
| 156 NUM (258) 2 |
| 157 OP (259) 1 |
| 158 |
| 159 |
| 160 Nonterminals, with rules where they appear |
| 161 |
| 162 $accept (5) |
| 163 on left: 0 |
| 164 exp (6) |
| 165 on left: 1 2, on right: 0 1 |
| 166 |
| 167 |
| 168 state 0 |
| 169 |
| 170 0 $accept: . exp $end |
| 171 1 exp: . exp OP exp |
| 172 2 | . NUM |
| 173 |
| 174 NUM shift, and go to state 1 |
| 175 |
| 176 exp go to state 2 |
| 177 |
| 178 |
| 179 state 1 |
| 180 |
| 181 2 exp: NUM . |
| 182 |
| 183 $default reduce using rule 2 (exp) |
| 184 |
| 185 |
| 186 state 2 |
| 187 |
| 188 0 $accept: exp . $end |
| 189 1 exp: exp . OP exp |
| 190 |
| 191 $end shift, and go to state 3 |
| 192 OP shift, and go to state 4 |
| 193 |
| 194 |
| 195 state 3 |
| 196 |
| 197 0 $accept: exp $end . |
| 198 |
| 199 $default accept |
| 200 |
| 201 |
| 202 state 4 |
| 203 |
| 204 1 exp: . exp OP exp |
| 205 1 | exp OP . exp |
| 206 2 | . NUM |
| 207 |
| 208 NUM shift, and go to state 1 |
| 209 |
| 210 exp go to state 5 |
| 211 |
| 212 |
| 213 state 5 |
| 214 |
| 215 1 exp: exp . OP exp |
| 216 1 | exp OP exp . [$end, OP] |
| 217 |
| 218 OP shift, and go to state 4 |
| 219 |
| 220 OP [reduce using rule 1 (exp)] |
| 221 $default reduce using rule 1 (exp) |
| 222 ]]) |
| 223 |
| 224 AT_CLEANUP |
| 225 |
| 226 |
| 227 |
| 228 ## ----------------------- ## |
| 229 ## Resolved SR Conflicts. ## |
| 230 ## ----------------------- ## |
| 231 |
| 232 AT_SETUP([Resolved SR Conflicts]) |
| 233 |
| 234 AT_KEYWORDS([report]) |
| 235 |
| 236 AT_DATA([input.y], |
| 237 [[%token NUM OP |
| 238 %left OP |
| 239 %% |
| 240 exp: exp OP exp | NUM; |
| 241 ]]) |
| 242 |
| 243 AT_BISON_CHECK([-o input.c --report=all input.y]) |
| 244 |
| 245 # Check the contents of the report. |
| 246 AT_CHECK([cat input.output], [], |
| 247 [[Grammar |
| 248 |
| 249 0 $accept: exp $end |
| 250 |
| 251 1 exp: exp OP exp |
| 252 2 | NUM |
| 253 |
| 254 |
| 255 Terminals, with rules where they appear |
| 256 |
| 257 $end (0) 0 |
| 258 error (256) |
| 259 NUM (258) 2 |
| 260 OP (259) 1 |
| 261 |
| 262 |
| 263 Nonterminals, with rules where they appear |
| 264 |
| 265 $accept (5) |
| 266 on left: 0 |
| 267 exp (6) |
| 268 on left: 1 2, on right: 0 1 |
| 269 |
| 270 |
| 271 state 0 |
| 272 |
| 273 0 $accept: . exp $end |
| 274 1 exp: . exp OP exp |
| 275 2 | . NUM |
| 276 |
| 277 NUM shift, and go to state 1 |
| 278 |
| 279 exp go to state 2 |
| 280 |
| 281 |
| 282 state 1 |
| 283 |
| 284 2 exp: NUM . |
| 285 |
| 286 $default reduce using rule 2 (exp) |
| 287 |
| 288 |
| 289 state 2 |
| 290 |
| 291 0 $accept: exp . $end |
| 292 1 exp: exp . OP exp |
| 293 |
| 294 $end shift, and go to state 3 |
| 295 OP shift, and go to state 4 |
| 296 |
| 297 |
| 298 state 3 |
| 299 |
| 300 0 $accept: exp $end . |
| 301 |
| 302 $default accept |
| 303 |
| 304 |
| 305 state 4 |
| 306 |
| 307 1 exp: . exp OP exp |
| 308 1 | exp OP . exp |
| 309 2 | . NUM |
| 310 |
| 311 NUM shift, and go to state 1 |
| 312 |
| 313 exp go to state 5 |
| 314 |
| 315 |
| 316 state 5 |
| 317 |
| 318 1 exp: exp . OP exp |
| 319 1 | exp OP exp . [$end, OP] |
| 320 |
| 321 $default reduce using rule 1 (exp) |
| 322 |
| 323 Conflict between rule 1 and token OP resolved as reduce (%left OP). |
| 324 ]]) |
| 325 |
| 326 AT_CLEANUP |
| 327 |
| 328 |
| 329 ## -------------------------------- ## |
| 330 ## Defaulted Conflicted Reduction. ## |
| 331 ## -------------------------------- ## |
| 332 |
| 333 # When there are RR conflicts, some rules are disabled. Usually it is |
| 334 # simply displayed as: |
| 335 # |
| 336 # $end reduce using rule 3 (num) |
| 337 # $end [reduce using rule 4 (id)] |
| 338 # |
| 339 # But when `reduce 3' is the default action, we'd produce: |
| 340 # |
| 341 # $end [reduce using rule 4 (id)] |
| 342 # $default reduce using rule 3 (num) |
| 343 # |
| 344 # In this precise case (a reduction is masked by the default |
| 345 # reduction), we make the `reduce 3' explicit: |
| 346 # |
| 347 # $end reduce using rule 3 (num) |
| 348 # $end [reduce using rule 4 (id)] |
| 349 # $default reduce using rule 3 (num) |
| 350 # |
| 351 # Maybe that's not the best display, but then, please propose something |
| 352 # else. |
| 353 |
| 354 AT_SETUP([Defaulted Conflicted Reduction]) |
| 355 AT_KEYWORDS([report]) |
| 356 |
| 357 AT_DATA([input.y], |
| 358 [[%% |
| 359 exp: num | id; |
| 360 num: '0'; |
| 361 id : '0'; |
| 362 %% |
| 363 ]]) |
| 364 |
| 365 AT_BISON_CHECK([-o input.c --report=all input.y], 0, [], |
| 366 [[input.y: conflicts: 1 reduce/reduce |
| 367 input.y:4.6-8: warning: rule useless in parser due to conflicts: id: '0' |
| 368 ]]) |
| 369 |
| 370 # Check the contents of the report. |
| 371 AT_CHECK([cat input.output], [], |
| 372 [[Rules useless in parser due to conflicts |
| 373 |
| 374 4 id: '0' |
| 375 |
| 376 |
| 377 State 1 conflicts: 1 reduce/reduce |
| 378 |
| 379 |
| 380 Grammar |
| 381 |
| 382 0 $accept: exp $end |
| 383 |
| 384 1 exp: num |
| 385 2 | id |
| 386 |
| 387 3 num: '0' |
| 388 |
| 389 4 id: '0' |
| 390 |
| 391 |
| 392 Terminals, with rules where they appear |
| 393 |
| 394 $end (0) 0 |
| 395 '0' (48) 3 4 |
| 396 error (256) |
| 397 |
| 398 |
| 399 Nonterminals, with rules where they appear |
| 400 |
| 401 $accept (4) |
| 402 on left: 0 |
| 403 exp (5) |
| 404 on left: 1 2, on right: 0 |
| 405 num (6) |
| 406 on left: 3, on right: 1 |
| 407 id (7) |
| 408 on left: 4, on right: 2 |
| 409 |
| 410 |
| 411 state 0 |
| 412 |
| 413 0 $accept: . exp $end |
| 414 1 exp: . num |
| 415 2 | . id |
| 416 3 num: . '0' |
| 417 4 id: . '0' |
| 418 |
| 419 '0' shift, and go to state 1 |
| 420 |
| 421 exp go to state 2 |
| 422 num go to state 3 |
| 423 id go to state 4 |
| 424 |
| 425 |
| 426 state 1 |
| 427 |
| 428 3 num: '0' . [$end] |
| 429 4 id: '0' . [$end] |
| 430 |
| 431 $end reduce using rule 3 (num) |
| 432 $end [reduce using rule 4 (id)] |
| 433 $default reduce using rule 3 (num) |
| 434 |
| 435 |
| 436 state 2 |
| 437 |
| 438 0 $accept: exp . $end |
| 439 |
| 440 $end shift, and go to state 5 |
| 441 |
| 442 |
| 443 state 3 |
| 444 |
| 445 1 exp: num . |
| 446 |
| 447 $default reduce using rule 1 (exp) |
| 448 |
| 449 |
| 450 state 4 |
| 451 |
| 452 2 exp: id . |
| 453 |
| 454 $default reduce using rule 2 (exp) |
| 455 |
| 456 |
| 457 state 5 |
| 458 |
| 459 0 $accept: exp $end . |
| 460 |
| 461 $default accept |
| 462 ]]) |
| 463 |
| 464 AT_CLEANUP |
| 465 |
| 466 |
| 467 |
| 468 |
| 469 ## -------------------- ## |
| 470 ## %expect not enough. ## |
| 471 ## -------------------- ## |
| 472 |
| 473 AT_SETUP([%expect not enough]) |
| 474 |
| 475 AT_DATA([input.y], |
| 476 [[%token NUM OP |
| 477 %expect 0 |
| 478 %% |
| 479 exp: exp OP exp | NUM; |
| 480 ]]) |
| 481 |
| 482 AT_BISON_CHECK([-o input.c input.y], 1, [], |
| 483 [input.y: conflicts: 1 shift/reduce |
| 484 input.y: expected 0 shift/reduce conflicts |
| 485 ]) |
| 486 AT_CLEANUP |
| 487 |
| 488 |
| 489 ## --------------- ## |
| 490 ## %expect right. ## |
| 491 ## --------------- ## |
| 492 |
| 493 AT_SETUP([%expect right]) |
| 494 |
| 495 AT_DATA([input.y], |
| 496 [[%token NUM OP |
| 497 %expect 1 |
| 498 %% |
| 499 exp: exp OP exp | NUM; |
| 500 ]]) |
| 501 |
| 502 AT_BISON_CHECK([-o input.c input.y]) |
| 503 AT_CLEANUP |
| 504 |
| 505 |
| 506 ## ------------------ ## |
| 507 ## %expect too much. ## |
| 508 ## ------------------ ## |
| 509 |
| 510 AT_SETUP([%expect too much]) |
| 511 |
| 512 AT_DATA([input.y], |
| 513 [[%token NUM OP |
| 514 %expect 2 |
| 515 %% |
| 516 exp: exp OP exp | NUM; |
| 517 ]]) |
| 518 |
| 519 AT_BISON_CHECK([-o input.c input.y], 1, [], |
| 520 [input.y: conflicts: 1 shift/reduce |
| 521 input.y: expected 2 shift/reduce conflicts |
| 522 ]) |
| 523 AT_CLEANUP |
| 524 |
| 525 |
| 526 ## ------------------------------ ## |
| 527 ## %expect with reduce conflicts ## |
| 528 ## ------------------------------ ## |
| 529 |
| 530 AT_SETUP([%expect with reduce conflicts]) |
| 531 |
| 532 AT_DATA([input.y], |
| 533 [[%expect 0 |
| 534 %% |
| 535 program: a 'a' | a a; |
| 536 a: 'a'; |
| 537 ]]) |
| 538 |
| 539 AT_BISON_CHECK([-o input.c input.y], 1, [], |
| 540 [input.y: conflicts: 1 reduce/reduce |
| 541 input.y: expected 0 reduce/reduce conflicts |
| 542 ]) |
| 543 AT_CLEANUP |
| 544 |
| 545 |
| 546 ## ------------------------------- ## |
| 547 ## %no-default-prec without %prec ## |
| 548 ## ------------------------------- ## |
| 549 |
| 550 AT_SETUP([%no-default-prec without %prec]) |
| 551 |
| 552 AT_DATA([[input.y]], |
| 553 [[%left '+' |
| 554 %left '*' |
| 555 |
| 556 %% |
| 557 |
| 558 %no-default-prec; |
| 559 |
| 560 e: e '+' e |
| 561 | e '*' e |
| 562 | '0' |
| 563 ; |
| 564 ]]) |
| 565 |
| 566 AT_BISON_CHECK([-o input.c input.y], 0, [], |
| 567 [[input.y: conflicts: 4 shift/reduce |
| 568 ]]) |
| 569 AT_CLEANUP |
| 570 |
| 571 |
| 572 ## ---------------------------- ## |
| 573 ## %no-default-prec with %prec ## |
| 574 ## ---------------------------- ## |
| 575 |
| 576 AT_SETUP([%no-default-prec with %prec]) |
| 577 |
| 578 AT_DATA([[input.y]], |
| 579 [[%left '+' |
| 580 %left '*' |
| 581 |
| 582 %% |
| 583 |
| 584 %no-default-prec; |
| 585 |
| 586 e: e '+' e %prec '+' |
| 587 | e '*' e %prec '*' |
| 588 | '0' |
| 589 ; |
| 590 ]]) |
| 591 |
| 592 AT_BISON_CHECK([-o input.c input.y]) |
| 593 AT_CLEANUP |
| 594 |
| 595 |
| 596 ## ---------------- ## |
| 597 ## %default-prec ## |
| 598 ## ---------------- ## |
| 599 |
| 600 AT_SETUP([%default-prec]) |
| 601 |
| 602 AT_DATA([[input.y]], |
| 603 [[%left '+' |
| 604 %left '*' |
| 605 |
| 606 %% |
| 607 |
| 608 %default-prec; |
| 609 |
| 610 e: e '+' e |
| 611 | e '*' e |
| 612 | '0' |
| 613 ; |
| 614 ]]) |
| 615 |
| 616 AT_BISON_CHECK([-o input.c input.y]) |
| 617 AT_CLEANUP |
| 618 |
| 619 |
| 620 ## ---------------------------------------------- ## |
| 621 ## Unreachable States After Conflict Resolution. ## |
| 622 ## ---------------------------------------------- ## |
| 623 |
| 624 AT_SETUP([[Unreachable States After Conflict Resolution]]) |
| 625 |
| 626 # If conflict resolution makes states unreachable, remove those states, report |
| 627 # rules that are then unused, and don't report conflicts in those states. Test |
| 628 # what happens when a nonterminal becomes useless as a result of state removal |
| 629 # since that causes lalr.o's goto map to be rewritten. |
| 630 |
| 631 AT_DATA([[input.y]], |
| 632 [[%output "input.c" |
| 633 %left 'a' |
| 634 |
| 635 %% |
| 636 |
| 637 start: resolved_conflict 'a' reported_conflicts 'a' ; |
| 638 |
| 639 /* S/R conflict resolved as reduce, so the state with item |
| 640 * (resolved_conflict: 'a' . unreachable1) and all it transition successors are |
| 641 * unreachable, and the associated production is useless. */ |
| 642 resolved_conflict: |
| 643 'a' unreachable1 |
| 644 | %prec 'a' |
| 645 ; |
| 646 |
| 647 /* S/R conflict that need not be reported since it is unreachable because of |
| 648 * the previous conflict resolution. Nonterminal unreachable1 and all its |
| 649 * productions are useless. */ |
| 650 unreachable1: |
| 651 'a' unreachable2 |
| 652 | |
| 653 ; |
| 654 |
| 655 /* Likewise for a R/R conflict and nonterminal unreachable2. */ |
| 656 unreachable2: | ; |
| 657 |
| 658 /* Make sure remaining S/R and R/R conflicts are still reported correctly even |
| 659 * when their states are renumbered due to state removal. */ |
| 660 reported_conflicts: |
| 661 'a' |
| 662 | 'a' |
| 663 | |
| 664 ; |
| 665 |
| 666 ]]) |
| 667 |
| 668 AT_BISON_CHECK([[--report=all input.y]], 0, [], |
| 669 [[input.y: conflicts: 1 shift/reduce, 1 reduce/reduce |
| 670 input.y:12.5-20: warning: rule useless in parser due to conflicts: resolved_conf
lict: 'a' unreachable1 |
| 671 input.y:20.5-20: warning: rule useless in parser due to conflicts: unreachable1:
'a' unreachable2 |
| 672 input.y:21.4: warning: rule useless in parser due to conflicts: unreachable1: /*
empty */ |
| 673 input.y:25.13: warning: rule useless in parser due to conflicts: unreachable2: /
* empty */ |
| 674 input.y:25.16: warning: rule useless in parser due to conflicts: unreachable2: /
* empty */ |
| 675 input.y:31.5-7: warning: rule useless in parser due to conflicts: reported_confl
icts: 'a' |
| 676 input.y:32.4: warning: rule useless in parser due to conflicts: reported_conflic
ts: /* empty */ |
| 677 ]]) |
| 678 |
| 679 AT_CHECK([[cat input.output]], 0, |
| 680 [[Rules useless in parser due to conflicts |
| 681 |
| 682 2 resolved_conflict: 'a' unreachable1 |
| 683 |
| 684 4 unreachable1: 'a' unreachable2 |
| 685 5 | /* empty */ |
| 686 |
| 687 6 unreachable2: /* empty */ |
| 688 7 | /* empty */ |
| 689 |
| 690 9 reported_conflicts: 'a' |
| 691 10 | /* empty */ |
| 692 |
| 693 |
| 694 State 4 conflicts: 1 shift/reduce |
| 695 State 5 conflicts: 1 reduce/reduce |
| 696 |
| 697 |
| 698 Grammar |
| 699 |
| 700 0 $accept: start $end |
| 701 |
| 702 1 start: resolved_conflict 'a' reported_conflicts 'a' |
| 703 |
| 704 2 resolved_conflict: 'a' unreachable1 |
| 705 3 | /* empty */ |
| 706 |
| 707 4 unreachable1: 'a' unreachable2 |
| 708 5 | /* empty */ |
| 709 |
| 710 6 unreachable2: /* empty */ |
| 711 7 | /* empty */ |
| 712 |
| 713 8 reported_conflicts: 'a' |
| 714 9 | 'a' |
| 715 10 | /* empty */ |
| 716 |
| 717 |
| 718 Terminals, with rules where they appear |
| 719 |
| 720 $end (0) 0 |
| 721 'a' (97) 1 2 4 8 9 |
| 722 error (256) |
| 723 |
| 724 |
| 725 Nonterminals, with rules where they appear |
| 726 |
| 727 $accept (4) |
| 728 on left: 0 |
| 729 start (5) |
| 730 on left: 1, on right: 0 |
| 731 resolved_conflict (6) |
| 732 on left: 2 3, on right: 1 |
| 733 unreachable1 (7) |
| 734 on left: 4 5, on right: 2 |
| 735 unreachable2 (8) |
| 736 on left: 6 7, on right: 4 |
| 737 reported_conflicts (9) |
| 738 on left: 8 9 10, on right: 1 |
| 739 |
| 740 |
| 741 state 0 |
| 742 |
| 743 0 $accept: . start $end |
| 744 1 start: . resolved_conflict 'a' reported_conflicts 'a' |
| 745 2 resolved_conflict: . 'a' unreachable1 |
| 746 3 | . ['a'] |
| 747 |
| 748 $default reduce using rule 3 (resolved_conflict) |
| 749 |
| 750 start go to state 1 |
| 751 resolved_conflict go to state 2 |
| 752 |
| 753 Conflict between rule 3 and token 'a' resolved as reduce (%left 'a'). |
| 754 |
| 755 |
| 756 state 1 |
| 757 |
| 758 0 $accept: start . $end |
| 759 |
| 760 $end shift, and go to state 3 |
| 761 |
| 762 |
| 763 state 2 |
| 764 |
| 765 1 start: resolved_conflict . 'a' reported_conflicts 'a' |
| 766 |
| 767 'a' shift, and go to state 4 |
| 768 |
| 769 |
| 770 state 3 |
| 771 |
| 772 0 $accept: start $end . |
| 773 |
| 774 $default accept |
| 775 |
| 776 |
| 777 state 4 |
| 778 |
| 779 1 start: resolved_conflict 'a' . reported_conflicts 'a' |
| 780 8 reported_conflicts: . 'a' |
| 781 9 | . 'a' |
| 782 10 | . ['a'] |
| 783 |
| 784 'a' shift, and go to state 5 |
| 785 |
| 786 'a' [reduce using rule 10 (reported_conflicts)] |
| 787 |
| 788 reported_conflicts go to state 6 |
| 789 |
| 790 |
| 791 state 5 |
| 792 |
| 793 8 reported_conflicts: 'a' . ['a'] |
| 794 9 | 'a' . ['a'] |
| 795 |
| 796 'a' reduce using rule 8 (reported_conflicts) |
| 797 'a' [reduce using rule 9 (reported_conflicts)] |
| 798 $default reduce using rule 8 (reported_conflicts) |
| 799 |
| 800 |
| 801 state 6 |
| 802 |
| 803 1 start: resolved_conflict 'a' reported_conflicts . 'a' |
| 804 |
| 805 'a' shift, and go to state 7 |
| 806 |
| 807 |
| 808 state 7 |
| 809 |
| 810 1 start: resolved_conflict 'a' reported_conflicts 'a' . |
| 811 |
| 812 $default reduce using rule 1 (start) |
| 813 ]]) |
| 814 |
| 815 AT_DATA([[input-keep.y]], |
| 816 [[%define lr.keep_unreachable_states |
| 817 ]]) |
| 818 AT_CHECK([[cat input.y >> input-keep.y]]) |
| 819 |
| 820 AT_BISON_CHECK([[input-keep.y]], 0, [], |
| 821 [[input-keep.y: conflicts: 2 shift/reduce, 2 reduce/reduce |
| 822 input-keep.y:22.4: warning: rule useless in parser due to conflicts: unreachable
1: /* empty */ |
| 823 input-keep.y:26.16: warning: rule useless in parser due to conflicts: unreachabl
e2: /* empty */ |
| 824 input-keep.y:32.5-7: warning: rule useless in parser due to conflicts: reported_
conflicts: 'a' |
| 825 input-keep.y:33.4: warning: rule useless in parser due to conflicts: reported_co
nflicts: /* empty */ |
| 826 ]]) |
| 827 |
| 828 AT_CLEANUP |
| 829 |
| 830 |
| 831 ## ------------------------------------------------------------ ## |
| 832 ## Solved conflicts report for multiple reductions in a state. ## |
| 833 ## ------------------------------------------------------------ ## |
| 834 |
| 835 AT_SETUP([[Solved conflicts report for multiple reductions in a state]]) |
| 836 |
| 837 # Used to lose earlier solved conflict messages even within a single S/R/R. |
| 838 |
| 839 AT_DATA([[input.y]], |
| 840 [[%left 'a' |
| 841 %right 'b' |
| 842 %right 'c' |
| 843 %right 'd' |
| 844 %% |
| 845 start: |
| 846 'a' |
| 847 | empty_a 'a' |
| 848 | 'b' |
| 849 | empty_b 'b' |
| 850 | 'c' |
| 851 | empty_c1 'c' |
| 852 | empty_c2 'c' |
| 853 | empty_c3 'c' |
| 854 ; |
| 855 empty_a: %prec 'a' ; |
| 856 empty_b: %prec 'b' ; |
| 857 empty_c1: %prec 'c' ; |
| 858 empty_c2: %prec 'c' ; |
| 859 empty_c3: %prec 'd' ; |
| 860 ]]) |
| 861 AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore]) |
| 862 AT_CHECK([[cat input.output | sed -n '/^state 0$/,/^state 1$/p']], 0, |
| 863 [[state 0 |
| 864 |
| 865 0 $accept: . start $end |
| 866 1 start: . 'a' |
| 867 2 | . empty_a 'a' |
| 868 3 | . 'b' |
| 869 4 | . empty_b 'b' |
| 870 5 | . 'c' |
| 871 6 | . empty_c1 'c' |
| 872 7 | . empty_c2 'c' |
| 873 8 | . empty_c3 'c' |
| 874 9 empty_a: . ['a'] |
| 875 10 empty_b: . [] |
| 876 11 empty_c1: . [] |
| 877 12 empty_c2: . [] |
| 878 13 empty_c3: . ['c'] |
| 879 |
| 880 'b' shift, and go to state 1 |
| 881 |
| 882 'c' reduce using rule 13 (empty_c3) |
| 883 $default reduce using rule 9 (empty_a) |
| 884 |
| 885 start go to state 2 |
| 886 empty_a go to state 3 |
| 887 empty_b go to state 4 |
| 888 empty_c1 go to state 5 |
| 889 empty_c2 go to state 6 |
| 890 empty_c3 go to state 7 |
| 891 |
| 892 Conflict between rule 9 and token 'a' resolved as reduce (%left 'a'). |
| 893 Conflict between rule 10 and token 'b' resolved as shift (%right 'b'). |
| 894 Conflict between rule 11 and token 'c' resolved as shift (%right 'c'). |
| 895 Conflict between rule 12 and token 'c' resolved as shift (%right 'c'). |
| 896 Conflict between rule 13 and token 'c' resolved as reduce ('c' < 'd'). |
| 897 |
| 898 |
| 899 state 1 |
| 900 ]]) |
| 901 |
| 902 AT_CLEANUP |
| 903 |
| 904 |
| 905 ## ------------------------------------------------------------ ## |
| 906 ## %nonassoc error actions for multiple reductions in a state. ## |
| 907 ## ------------------------------------------------------------ ## |
| 908 |
| 909 # Used to abort when trying to resolve conflicts as %nonassoc error actions for |
| 910 # multiple reductions in a state. |
| 911 |
| 912 # For a %nonassoc error action token, used to print the first remaining |
| 913 # reduction on that token without brackets. |
| 914 |
| 915 AT_SETUP([[%nonassoc error actions for multiple reductions in a state]]) |
| 916 |
| 917 AT_DATA([[input.y]], |
| 918 [[%nonassoc 'a' 'b' 'c' |
| 919 %% |
| 920 start: |
| 921 'a' |
| 922 | empty_a 'a' |
| 923 | 'b' |
| 924 | empty_b 'b' |
| 925 | 'c' |
| 926 | empty_c1 'c' |
| 927 | empty_c2 'c' |
| 928 | empty_c3 'c' |
| 929 ; |
| 930 empty_a: %prec 'a' ; |
| 931 empty_b: %prec 'b' ; |
| 932 empty_c1: %prec 'c' ; |
| 933 empty_c2: %prec 'c' ; |
| 934 empty_c3: %prec 'c' ; |
| 935 ]]) |
| 936 |
| 937 AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [], [ignore]) |
| 938 AT_CHECK([[cat input.output | sed -n '/^state 0$/,/^state 1$/p']], 0, |
| 939 [[state 0 |
| 940 |
| 941 0 $accept: . start $end |
| 942 1 start: . 'a' |
| 943 2 | . empty_a 'a' |
| 944 3 | . 'b' |
| 945 4 | . empty_b 'b' |
| 946 5 | . 'c' |
| 947 6 | . empty_c1 'c' |
| 948 7 | . empty_c2 'c' |
| 949 8 | . empty_c3 'c' |
| 950 9 empty_a: . [] |
| 951 10 empty_b: . [] |
| 952 11 empty_c1: . [] |
| 953 12 empty_c2: . ['c'] |
| 954 13 empty_c3: . ['c'] |
| 955 |
| 956 'a' error (nonassociative) |
| 957 'b' error (nonassociative) |
| 958 'c' error (nonassociative) |
| 959 |
| 960 'c' [reduce using rule 12 (empty_c2)] |
| 961 'c' [reduce using rule 13 (empty_c3)] |
| 962 |
| 963 start go to state 1 |
| 964 empty_a go to state 2 |
| 965 empty_b go to state 3 |
| 966 empty_c1 go to state 4 |
| 967 empty_c2 go to state 5 |
| 968 empty_c3 go to state 6 |
| 969 |
| 970 Conflict between rule 9 and token 'a' resolved as an error (%nonassoc 'a'). |
| 971 Conflict between rule 10 and token 'b' resolved as an error (%nonassoc 'b'). |
| 972 Conflict between rule 11 and token 'c' resolved as an error (%nonassoc 'c'). |
| 973 |
| 974 |
| 975 state 1 |
| 976 ]]) |
| 977 AT_CLEANUP |
OLD | NEW |