]> git.saurik.com Git - bison.git/blob - tests/conflicts.at
84b4fcdaba5f510866f8f4ced984b0c0fabd4510
[bison.git] / tests / conflicts.at
1 # Exercising Bison on conflicts. -*- Autotest -*-
2 # Copyright (C) 2002 Free Software Foundation, Inc.
3
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2, or (at your option)
7 # any later version.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 # 02111-1307, USA.
18
19 AT_BANNER([[Conflicts.]])
20
21
22 ## ---------------- ##
23 ## S/R in initial. ##
24 ## ---------------- ##
25
26 # I once hacked Bison in such a way that it lost its reductions on the
27 # initial state (because it was confusing it with the last state). It
28 # took me a while to strip down my failures to this simple case. So
29 # make sure it finds the s/r conflict below.
30
31 AT_SETUP([S/R in initial])
32
33 AT_DATA([[input.y]],
34 [[%expect 1
35 %%
36 exp: e 'e';
37 e: 'e' | /* Nothing. */;
38 ]])
39
40 AT_CHECK([bison input.y -o input.c])
41
42 AT_CLEANUP
43
44
45 ## ------------------- ##
46 ## %nonassoc and eof. ##
47 ## ------------------- ##
48
49 AT_SETUP([%nonassoc and eof])
50
51 AT_DATA([input.y],
52 [[
53 %{
54 #include <config.h>
55 /* We don't need a perfect malloc for these tests. */
56 #undef malloc
57 #include <stdio.h>
58
59 #if STDC_HEADERS
60 # include <stdlib.h>
61 #endif
62
63 #define YYERROR_VERBOSE 1
64 static void
65 yyerror (const char *msg)
66 {
67 fprintf (stderr, "%s\n", msg);
68 exit (1);
69 }
70
71 /* The current argument. */
72 static const char *input = NULL;
73
74 static int
75 yylex (void)
76 {
77 /* No token stands for end of file. */
78 if (input && *input)
79 return *input++;
80 else
81 return 0;
82 }
83
84 %}
85
86 %nonassoc '<' '>'
87
88 %%
89 expr: expr '<' expr
90 | expr '>' expr
91 | '0'
92 ;
93 %%
94 int
95 main (int argc, const char *argv[])
96 {
97 if (argc > 1)
98 input = argv[1];
99 return yyparse ();
100 }
101 ]])
102
103 # Specify the output files to avoid problems on different file systems.
104 AT_CHECK([bison input.y -o input.c])
105 AT_COMPILE([input])
106
107 AT_PARSER_CHECK([./input '0<0'])
108 # FIXME: This is an actual bug, but a new one, in the sense that
109 # no one has ever spotted it! The messages are *wrong*: there should
110 # be nothing there, it should be expected eof.
111 AT_PARSER_CHECK([./input '0<0<0'], [1], [],
112 [parse error, unexpected '<', expecting '<' or '>'
113 ])
114
115 AT_PARSER_CHECK([./input '0>0'])
116 AT_PARSER_CHECK([./input '0>0>0'], [1], [],
117 [parse error, unexpected '>', expecting '<' or '>'
118 ])
119
120 AT_PARSER_CHECK([./input '0<0>0'], [1], [],
121 [parse error, unexpected '>', expecting '<' or '>'
122 ])
123
124 AT_CLEANUP
125
126
127
128 ## ------------------------- ##
129 ## Unresolved SR Conflicts. ##
130 ## ------------------------- ##
131
132 AT_SETUP([Unresolved SR Conflicts])
133
134 AT_KEYWORDS([report])
135
136 AT_DATA([input.y],
137 [[%token NUM OP
138 %%
139 exp: exp OP exp | NUM;
140 ]])
141
142 AT_CHECK([bison input.y -o input.c --report=all], 0, [],
143 [input.y contains 1 shift/reduce conflict.
144 ])
145
146 # Check the contents of the report.
147 AT_CHECK([cat input.output], [],
148 [[State 5 contains 1 shift/reduce conflict.
149
150
151 Grammar
152
153 0 $accept: exp $end
154
155 1 exp: exp OP exp
156 2 | NUM
157
158
159 Terminals, with rules where they appear
160
161 $end (0) 0
162 error (256)
163 NUM (258) 2
164 OP (259) 1
165
166
167 Nonterminals, with rules where they appear
168
169 $accept (5)
170 on left: 0
171 exp (6)
172 on left: 1 2, on right: 0 1
173
174
175 state 0
176
177 0 $accept: . exp $end
178 1 exp: . exp OP exp
179 2 | . NUM
180
181 NUM shift, and go to state 1
182
183 exp go to state 2
184
185
186 state 1
187
188 2 exp: NUM .
189
190 $default reduce using rule 2 (exp)
191
192
193 state 2
194
195 0 $accept: exp . $end
196 1 exp: exp . OP exp
197
198 $end shift, and go to state 3
199 OP shift, and go to state 4
200
201
202 state 3
203
204 0 $accept: exp $end .
205
206 $default accept
207
208
209 state 4
210
211 1 exp: . exp OP exp
212 1 | exp OP . exp
213 2 | . NUM
214
215 NUM shift, and go to state 1
216
217 exp go to state 5
218
219
220 state 5
221
222 1 exp: exp . OP exp [$end, OP]
223 1 | exp OP exp . [$end, OP]
224
225 OP shift, and go to state 4
226
227 OP [reduce using rule 1 (exp)]
228 $default reduce using rule 1 (exp)
229 ]])
230
231 AT_CLEANUP
232
233
234
235 ## ----------------------- ##
236 ## Resolved SR Conflicts. ##
237 ## ----------------------- ##
238
239 AT_SETUP([Resolved SR Conflicts])
240
241 AT_KEYWORDS([report])
242
243 AT_DATA([input.y],
244 [[%token NUM OP
245 %left OP
246 %%
247 exp: exp OP exp | NUM;
248 ]])
249
250 AT_CHECK([bison input.y -o input.c --report=all])
251
252 # Check the contents of the report.
253 AT_CHECK([cat input.output], [],
254 [[Grammar
255
256 0 $accept: exp $end
257
258 1 exp: exp OP exp
259 2 | NUM
260
261
262 Terminals, with rules where they appear
263
264 $end (0) 0
265 error (256)
266 NUM (258) 2
267 OP (259) 1
268
269
270 Nonterminals, with rules where they appear
271
272 $accept (5)
273 on left: 0
274 exp (6)
275 on left: 1 2, on right: 0 1
276
277
278 state 0
279
280 0 $accept: . exp $end
281 1 exp: . exp OP exp
282 2 | . NUM
283
284 NUM shift, and go to state 1
285
286 exp go to state 2
287
288
289 state 1
290
291 2 exp: NUM .
292
293 $default reduce using rule 2 (exp)
294
295
296 state 2
297
298 0 $accept: exp . $end
299 1 exp: exp . OP exp
300
301 $end shift, and go to state 3
302 OP shift, and go to state 4
303
304
305 state 3
306
307 0 $accept: exp $end .
308
309 $default accept
310
311
312 state 4
313
314 1 exp: . exp OP exp
315 1 | exp OP . exp
316 2 | . NUM
317
318 NUM shift, and go to state 1
319
320 exp go to state 5
321
322
323 state 5
324
325 1 exp: exp . OP exp [$end, OP]
326 1 | exp OP exp . [$end, OP]
327
328 $default reduce using rule 1 (exp)
329 Conflict between rule 1 and token OP resolved as reduce (%left OP).
330 ]])
331
332 AT_CLEANUP
333
334
335 ## -------------------------------- ##
336 ## Defaulted Conflicted Reduction. ##
337 ## -------------------------------- ##
338
339 # When there are RR conflicts, some rules are disabled. Usually it is
340 # simply displayed as:
341 #
342 # $end reduce using rule 3 (num)
343 # $end [reduce using rule 4 (id)]
344 #
345 # But when `reduce 3' is the default action, we'd produce:
346 #
347 # $end [reduce using rule 4 (id)]
348 # $default reduce using rule 3 (num)
349 #
350 # In this precise case (a reduction is masked by the default
351 # reduction), we make the `reduce 3' explicit:
352 #
353 # $end reduce using rule 3 (num)
354 # $end [reduce using rule 4 (id)]
355 # $default reduce using rule 3 (num)
356 #
357 # Maybe that's not the best display, but then, please propose something
358 # else.
359
360 AT_SETUP([Defaulted Conflicted Reduction])
361 AT_KEYWORDS([report])
362
363 AT_DATA([input.y],
364 [[%%
365 exp: num | id;
366 num: '0';
367 id : '0';
368 %%
369 ]])
370
371 AT_CHECK([bison input.y -o input.c --report=all], 0, [],
372 [input.y contains 1 reduce/reduce conflict.
373 ])
374
375 # Check the contents of the report.
376 AT_CHECK([cat input.output], [],
377 [[State 1 contains 1 reduce/reduce conflict.
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_CHECK([bison input.y -o input.c], 1, [],
483 [input.y contains 1 shift/reduce conflict.
484 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_CHECK([bison input.y -o input.c])
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_CHECK([bison input.y -o input.c], 1, [],
520 [input.y contains 1 shift/reduce conflict.
521 expected 2 shift/reduce conflicts
522 ])
523 AT_CLEANUP