1# Exercising Bison on conflicts. -*- Autotest -*- 2 3# Copyright (C) 2002, 2003, 2004, 2005 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 2, or (at your option) 8# 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, write to the Free Software 17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18# 02110-1301, USA. 19 20AT_BANNER([[Conflicts.]]) 21 22 23## ---------------- ## 24## S/R in initial. ## 25## ---------------- ## 26 27# I once hacked Bison in such a way that it lost its reductions on the 28# initial state (because it was confusing it with the last state). It 29# took me a while to strip down my failures to this simple case. So 30# make sure it finds the s/r conflict below. 31 32AT_SETUP([S/R in initial]) 33 34AT_DATA([[input.y]], 35[[%expect 1 36%% 37exp: e 'e'; 38e: 'e' | /* Nothing. */; 39]]) 40 41AT_CHECK([bison -o input.c input.y], 0, [], 42[[input.y:4.9: warning: rule never reduced because of conflicts: e: /* empty */ 43]]) 44 45AT_CLEANUP 46 47 48## ------------------- ## 49## %nonassoc and eof. ## 50## ------------------- ## 51 52AT_SETUP([%nonassoc and eof]) 53 54AT_DATA_GRAMMAR([input.y], 55[[ 56%{ 57#include <stdio.h> 58#include <stdlib.h> 59 60#define YYERROR_VERBOSE 1 61static void 62yyerror (const char *msg) 63{ 64 fprintf (stderr, "%s\n", msg); 65} 66 67/* The current argument. */ 68static const char *input = NULL; 69 70static int 71yylex (void) 72{ 73 /* No token stands for end of file. */ 74 if (input && *input) 75 return *input++; 76 else 77 return 0; 78} 79 80%} 81 82%nonassoc '<' '>' 83 84%% 85expr: expr '<' expr 86 | expr '>' expr 87 | '0' 88 ; 89%% 90int 91main (int argc, const char *argv[]) 92{ 93 if (argc > 1) 94 input = argv[1]; 95 return yyparse (); 96} 97]]) 98 99# Specify the output files to avoid problems on different file systems. 100AT_CHECK([bison -o input.c input.y]) 101AT_COMPILE([input]) 102 103AT_PARSER_CHECK([./input '0<0']) 104# FIXME: This is an actual bug, but a new one, in the sense that 105# no one has ever spotted it! The messages are *wrong*: there should 106# be nothing there, it should be expected eof. 107AT_PARSER_CHECK([./input '0<0<0'], [1], [], 108 [syntax error, unexpected '<', expecting '<' or '>' 109]) 110 111AT_PARSER_CHECK([./input '0>0']) 112AT_PARSER_CHECK([./input '0>0>0'], [1], [], 113 [syntax error, unexpected '>', expecting '<' or '>' 114]) 115 116AT_PARSER_CHECK([./input '0<0>0'], [1], [], 117 [syntax error, unexpected '>', expecting '<' or '>' 118]) 119 120AT_CLEANUP 121 122 123 124## ------------------------- ## 125## Unresolved SR Conflicts. ## 126## ------------------------- ## 127 128AT_SETUP([Unresolved SR Conflicts]) 129 130AT_KEYWORDS([report]) 131 132AT_DATA([input.y], 133[[%token NUM OP 134%% 135exp: exp OP exp | NUM; 136]]) 137 138AT_CHECK([bison -o input.c --report=all input.y], 0, [], 139[input.y: conflicts: 1 shift/reduce 140]) 141 142# Check the contents of the report. 143AT_CHECK([cat input.output], [], 144[[State 5 conflicts: 1 shift/reduce 145 146 147Grammar 148 149 0 $accept: exp $end 150 151 1 exp: exp OP exp 152 2 | NUM 153 154 155Terminals, with rules where they appear 156 157$end (0) 0 158error (256) 159NUM (258) 2 160OP (259) 1 161 162 163Nonterminals, with rules where they appear 164 165$accept (5) 166 on left: 0 167exp (6) 168 on left: 1 2, on right: 0 1 169 170 171state 0 172 173 0 $accept: . exp $end 174 1 exp: . exp OP exp 175 2 | . NUM 176 177 NUM shift, and go to state 1 178 179 exp go to state 2 180 181 182state 1 183 184 2 exp: NUM . 185 186 $default reduce using rule 2 (exp) 187 188 189state 2 190 191 0 $accept: exp . $end 192 1 exp: exp . OP exp 193 194 $end shift, and go to state 3 195 OP shift, and go to state 4 196 197 198state 3 199 200 0 $accept: exp $end . 201 202 $default accept 203 204 205state 4 206 207 1 exp: . exp OP exp 208 1 | exp OP . exp 209 2 | . NUM 210 211 NUM shift, and go to state 1 212 213 exp go to state 5 214 215 216state 5 217 218 1 exp: exp . OP exp [$end, OP] 219 1 | exp OP exp . [$end, OP] 220 221 OP shift, and go to state 4 222 223 OP [reduce using rule 1 (exp)] 224 $default reduce using rule 1 (exp) 225]]) 226 227AT_CLEANUP 228 229 230 231## ----------------------- ## 232## Resolved SR Conflicts. ## 233## ----------------------- ## 234 235AT_SETUP([Resolved SR Conflicts]) 236 237AT_KEYWORDS([report]) 238 239AT_DATA([input.y], 240[[%token NUM OP 241%left OP 242%% 243exp: exp OP exp | NUM; 244]]) 245 246AT_CHECK([bison -o input.c --report=all input.y]) 247 248# Check the contents of the report. 249AT_CHECK([cat input.output], [], 250[[Grammar 251 252 0 $accept: exp $end 253 254 1 exp: exp OP exp 255 2 | NUM 256 257 258Terminals, with rules where they appear 259 260$end (0) 0 261error (256) 262NUM (258) 2 263OP (259) 1 264 265 266Nonterminals, with rules where they appear 267 268$accept (5) 269 on left: 0 270exp (6) 271 on left: 1 2, on right: 0 1 272 273 274state 0 275 276 0 $accept: . exp $end 277 1 exp: . exp OP exp 278 2 | . NUM 279 280 NUM shift, and go to state 1 281 282 exp go to state 2 283 284 285state 1 286 287 2 exp: NUM . 288 289 $default reduce using rule 2 (exp) 290 291 292state 2 293 294 0 $accept: exp . $end 295 1 exp: exp . OP exp 296 297 $end shift, and go to state 3 298 OP shift, and go to state 4 299 300 301state 3 302 303 0 $accept: exp $end . 304 305 $default accept 306 307 308state 4 309 310 1 exp: . exp OP exp 311 1 | exp OP . exp 312 2 | . NUM 313 314 NUM shift, and go to state 1 315 316 exp go to state 5 317 318 319state 5 320 321 1 exp: exp . OP exp [$end, OP] 322 1 | exp OP exp . [$end, OP] 323 324 $default reduce using rule 1 (exp) 325 326 Conflict between rule 1 and token OP resolved as reduce (%left OP). 327]]) 328 329AT_CLEANUP 330 331 332## -------------------------------- ## 333## Defaulted Conflicted Reduction. ## 334## -------------------------------- ## 335 336# When there are RR conflicts, some rules are disabled. Usually it is 337# simply displayed as: 338# 339# $end reduce using rule 3 (num) 340# $end [reduce using rule 4 (id)] 341# 342# But when `reduce 3' is the default action, we'd produce: 343# 344# $end [reduce using rule 4 (id)] 345# $default reduce using rule 3 (num) 346# 347# In this precise case (a reduction is masked by the default 348# reduction), we make the `reduce 3' explicit: 349# 350# $end reduce using rule 3 (num) 351# $end [reduce using rule 4 (id)] 352# $default reduce using rule 3 (num) 353# 354# Maybe that's not the best display, but then, please propose something 355# else. 356 357AT_SETUP([Defaulted Conflicted Reduction]) 358AT_KEYWORDS([report]) 359 360AT_DATA([input.y], 361[[%% 362exp: num | id; 363num: '0'; 364id : '0'; 365%% 366]]) 367 368AT_CHECK([bison -o input.c --report=all input.y], 0, [], 369[[input.y: conflicts: 1 reduce/reduce 370input.y:4.6-8: warning: rule never reduced because of conflicts: id: '0' 371]]) 372 373# Check the contents of the report. 374AT_CHECK([cat input.output], [], 375[[Rules never reduced 376 377 4 id: '0' 378 379 380State 1 conflicts: 1 reduce/reduce 381 382 383Grammar 384 385 0 $accept: exp $end 386 387 1 exp: num 388 2 | id 389 390 3 num: '0' 391 392 4 id: '0' 393 394 395Terminals, with rules where they appear 396 397$end (0) 0 398'0' (48) 3 4 399error (256) 400 401 402Nonterminals, with rules where they appear 403 404$accept (4) 405 on left: 0 406exp (5) 407 on left: 1 2, on right: 0 408num (6) 409 on left: 3, on right: 1 410id (7) 411 on left: 4, on right: 2 412 413 414state 0 415 416 0 $accept: . exp $end 417 1 exp: . num 418 2 | . id 419 3 num: . '0' 420 4 id: . '0' 421 422 '0' shift, and go to state 1 423 424 exp go to state 2 425 num go to state 3 426 id go to state 4 427 428 429state 1 430 431 3 num: '0' . [$end] 432 4 id: '0' . [$end] 433 434 $end reduce using rule 3 (num) 435 $end [reduce using rule 4 (id)] 436 $default reduce using rule 3 (num) 437 438 439state 2 440 441 0 $accept: exp . $end 442 443 $end shift, and go to state 5 444 445 446state 3 447 448 1 exp: num . 449 450 $default reduce using rule 1 (exp) 451 452 453state 4 454 455 2 exp: id . 456 457 $default reduce using rule 2 (exp) 458 459 460state 5 461 462 0 $accept: exp $end . 463 464 $default accept 465]]) 466 467AT_CLEANUP 468 469 470 471 472## -------------------- ## 473## %expect not enough. ## 474## -------------------- ## 475 476AT_SETUP([%expect not enough]) 477 478AT_DATA([input.y], 479[[%token NUM OP 480%expect 0 481%% 482exp: exp OP exp | NUM; 483]]) 484 485AT_CHECK([bison -o input.c input.y], 1, [], 486[input.y: conflicts: 1 shift/reduce 487input.y: expected 0 shift/reduce conflicts 488]) 489AT_CLEANUP 490 491 492## --------------- ## 493## %expect right. ## 494## --------------- ## 495 496AT_SETUP([%expect right]) 497 498AT_DATA([input.y], 499[[%token NUM OP 500%expect 1 501%% 502exp: exp OP exp | NUM; 503]]) 504 505AT_CHECK([bison -o input.c input.y]) 506AT_CLEANUP 507 508 509## ------------------ ## 510## %expect too much. ## 511## ------------------ ## 512 513AT_SETUP([%expect too much]) 514 515AT_DATA([input.y], 516[[%token NUM OP 517%expect 2 518%% 519exp: exp OP exp | NUM; 520]]) 521 522AT_CHECK([bison -o input.c input.y], 1, [], 523[input.y: conflicts: 1 shift/reduce 524input.y: expected 2 shift/reduce conflicts 525]) 526AT_CLEANUP 527 528 529## ------------------------------ ## 530## %expect with reduce conflicts ## 531## ------------------------------ ## 532 533AT_SETUP([%expect with reduce conflicts]) 534 535AT_DATA([input.y], 536[[%expect 0 537%% 538program: a 'a' | a a; 539a: 'a'; 540]]) 541 542AT_CHECK([bison -o input.c input.y], 1, [], 543[input.y: conflicts: 1 reduce/reduce 544input.y: expected 0 reduce/reduce conflicts 545]) 546AT_CLEANUP 547 548 549## ------------------------------- ## 550## %no-default-prec without %prec ## 551## ------------------------------- ## 552 553AT_SETUP([%no-default-prec without %prec]) 554 555AT_DATA([[input.y]], 556[[%left '+' 557%left '*' 558 559%% 560 561%no-default-prec; 562 563e: e '+' e 564 | e '*' e 565 | '0' 566 ; 567]]) 568 569AT_CHECK([bison -o input.c input.y], 0, [], 570[[input.y: conflicts: 4 shift/reduce 571]]) 572AT_CLEANUP 573 574 575## ---------------------------- ## 576## %no-default-prec with %prec ## 577## ---------------------------- ## 578 579AT_SETUP([%no-default-prec with %prec]) 580 581AT_DATA([[input.y]], 582[[%left '+' 583%left '*' 584 585%% 586 587%no-default-prec; 588 589e: e '+' e %prec '+' 590 | e '*' e %prec '*' 591 | '0' 592 ; 593]]) 594 595AT_CHECK([bison -o input.c input.y]) 596AT_CLEANUP 597 598 599## ---------------- ## 600## %default-prec ## 601## ---------------- ## 602 603AT_SETUP([%default-prec]) 604 605AT_DATA([[input.y]], 606[[%left '+' 607%left '*' 608 609%% 610 611%default-prec; 612 613e: e '+' e 614 | e '*' e 615 | '0' 616 ; 617]]) 618 619AT_CHECK([bison -o input.c input.y]) 620AT_CLEANUP 621