]> git.saurik.com Git - bison.git/blob - tests/conflicts.at
(getargs) [MSDOS]: Don't assume optarg != NULL
[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 -o input.c input.y], 0, [],
41 [[input.y:4.9: warning: rule never reduced because of conflicts: e: /* empty */
42 ]])
43
44 AT_CLEANUP
45
46
47 ## ------------------- ##
48 ## %nonassoc and eof. ##
49 ## ------------------- ##
50
51 AT_SETUP([%nonassoc and eof])
52
53 AT_DATA_GRAMMAR([input.y],
54 [[
55 %{
56 #include <stdio.h>
57
58 #if STDC_HEADERS
59 # include <stdlib.h>
60 #endif
61
62 #define YYERROR_VERBOSE 1
63 static void
64 yyerror (const char *msg)
65 {
66 fprintf (stderr, "%s\n", msg);
67 exit (1);
68 }
69
70 /* The current argument. */
71 static const char *input = NULL;
72
73 static int
74 yylex (void)
75 {
76 /* No token stands for end of file. */
77 if (input && *input)
78 return *input++;
79 else
80 return 0;
81 }
82
83 %}
84
85 %nonassoc '<' '>'
86
87 %%
88 expr: expr '<' expr
89 | expr '>' expr
90 | '0'
91 ;
92 %%
93 int
94 main (int argc, const char *argv[])
95 {
96 if (argc > 1)
97 input = argv[1];
98 return yyparse ();
99 }
100 ]])
101
102 # Specify the output files to avoid problems on different file systems.
103 AT_CHECK([bison -o input.c input.y])
104 AT_COMPILE([input])
105
106 AT_PARSER_CHECK([./input '0<0'])
107 # FIXME: This is an actual bug, but a new one, in the sense that
108 # no one has ever spotted it! The messages are *wrong*: there should
109 # be nothing there, it should be expected eof.
110 AT_PARSER_CHECK([./input '0<0<0'], [1], [],
111 [syntax error, unexpected '<', expecting '<' or '>'
112 ])
113
114 AT_PARSER_CHECK([./input '0>0'])
115 AT_PARSER_CHECK([./input '0>0>0'], [1], [],
116 [syntax error, unexpected '>', expecting '<' or '>'
117 ])
118
119 AT_PARSER_CHECK([./input '0<0>0'], [1], [],
120 [syntax error, unexpected '>', expecting '<' or '>'
121 ])
122
123 AT_CLEANUP
124
125
126
127 ## ------------------------- ##
128 ## Unresolved SR Conflicts. ##
129 ## ------------------------- ##
130
131 AT_SETUP([Unresolved SR Conflicts])
132
133 AT_KEYWORDS([report])
134
135 AT_DATA([input.y],
136 [[%token NUM OP
137 %%
138 exp: exp OP exp | NUM;
139 ]])
140
141 AT_CHECK([bison -o input.c --report=all input.y], 0, [],
142 [input.y: warning: 1 shift/reduce conflict
143 ])
144
145 # Check the contents of the report.
146 AT_CHECK([cat input.output], [],
147 [[State 5 contains 1 shift/reduce conflict.
148
149
150 Grammar
151
152 0 $accept: exp $end
153
154 1 exp: exp OP exp
155 2 | NUM
156
157
158 Terminals, with rules where they appear
159
160 $end (0) 0
161 error (256)
162 NUM (258) 2
163 OP (259) 1
164
165
166 Nonterminals, with rules where they appear
167
168 $accept (5)
169 on left: 0
170 exp (6)
171 on left: 1 2, on right: 0 1
172
173
174 state 0
175
176 0 $accept: . exp $end
177 1 exp: . exp OP exp
178 2 | . NUM
179
180 NUM shift, and go to state 1
181
182 exp go to state 2
183
184
185 state 1
186
187 2 exp: NUM .
188
189 $default reduce using rule 2 (exp)
190
191
192 state 2
193
194 0 $accept: exp . $end
195 1 exp: exp . OP exp
196
197 $end shift, and go to state 3
198 OP shift, and go to state 4
199
200
201 state 3
202
203 0 $accept: exp $end .
204
205 $default accept
206
207
208 state 4
209
210 1 exp: . exp OP exp
211 1 | exp OP . exp
212 2 | . NUM
213
214 NUM shift, and go to state 1
215
216 exp go to state 5
217
218
219 state 5
220
221 1 exp: exp . OP exp [$end, OP]
222 1 | exp OP exp . [$end, OP]
223
224 OP shift, and go to state 4
225
226 OP [reduce using rule 1 (exp)]
227 $default reduce using rule 1 (exp)
228 ]])
229
230 AT_CLEANUP
231
232
233
234 ## ----------------------- ##
235 ## Resolved SR Conflicts. ##
236 ## ----------------------- ##
237
238 AT_SETUP([Resolved SR Conflicts])
239
240 AT_KEYWORDS([report])
241
242 AT_DATA([input.y],
243 [[%token NUM OP
244 %left OP
245 %%
246 exp: exp OP exp | NUM;
247 ]])
248
249 AT_CHECK([bison -o input.c --report=all input.y])
250
251 # Check the contents of the report.
252 AT_CHECK([cat input.output], [],
253 [[Grammar
254
255 0 $accept: exp $end
256
257 1 exp: exp OP exp
258 2 | NUM
259
260
261 Terminals, with rules where they appear
262
263 $end (0) 0
264 error (256)
265 NUM (258) 2
266 OP (259) 1
267
268
269 Nonterminals, with rules where they appear
270
271 $accept (5)
272 on left: 0
273 exp (6)
274 on left: 1 2, on right: 0 1
275
276
277 state 0
278
279 0 $accept: . exp $end
280 1 exp: . exp OP exp
281 2 | . NUM
282
283 NUM shift, and go to state 1
284
285 exp go to state 2
286
287
288 state 1
289
290 2 exp: NUM .
291
292 $default reduce using rule 2 (exp)
293
294
295 state 2
296
297 0 $accept: exp . $end
298 1 exp: exp . OP exp
299
300 $end shift, and go to state 3
301 OP shift, and go to state 4
302
303
304 state 3
305
306 0 $accept: exp $end .
307
308 $default accept
309
310
311 state 4
312
313 1 exp: . exp OP exp
314 1 | exp OP . exp
315 2 | . NUM
316
317 NUM shift, and go to state 1
318
319 exp go to state 5
320
321
322 state 5
323
324 1 exp: exp . OP exp [$end, OP]
325 1 | exp OP exp . [$end, OP]
326
327 $default reduce using rule 1 (exp)
328
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 -o input.c --report=all input.y], 0, [],
372 [[input.y: warning: 1 reduce/reduce conflict
373 input.y:4.6-8: warning: rule never reduced because of conflicts: id: '0'
374 ]])
375
376 # Check the contents of the report.
377 AT_CHECK([cat input.output], [],
378 [[Rules never reduced
379
380 4 id: '0'
381
382
383 State 1 contains 1 reduce/reduce conflict.
384
385
386 Grammar
387
388 0 $accept: exp $end
389
390 1 exp: num
391 2 | id
392
393 3 num: '0'
394
395 4 id: '0'
396
397
398 Terminals, with rules where they appear
399
400 $end (0) 0
401 '0' (48) 3 4
402 error (256)
403
404
405 Nonterminals, with rules where they appear
406
407 $accept (4)
408 on left: 0
409 exp (5)
410 on left: 1 2, on right: 0
411 num (6)
412 on left: 3, on right: 1
413 id (7)
414 on left: 4, on right: 2
415
416
417 state 0
418
419 0 $accept: . exp $end
420 1 exp: . num
421 2 | . id
422 3 num: . '0'
423 4 id: . '0'
424
425 '0' shift, and go to state 1
426
427 exp go to state 2
428 num go to state 3
429 id go to state 4
430
431
432 state 1
433
434 3 num: '0' . [$end]
435 4 id: '0' . [$end]
436
437 $end reduce using rule 3 (num)
438 $end [reduce using rule 4 (id)]
439 $default reduce using rule 3 (num)
440
441
442 state 2
443
444 0 $accept: exp . $end
445
446 $end shift, and go to state 5
447
448
449 state 3
450
451 1 exp: num .
452
453 $default reduce using rule 1 (exp)
454
455
456 state 4
457
458 2 exp: id .
459
460 $default reduce using rule 2 (exp)
461
462
463 state 5
464
465 0 $accept: exp $end .
466
467 $default accept
468 ]])
469
470 AT_CLEANUP
471
472
473
474
475 ## -------------------- ##
476 ## %expect not enough. ##
477 ## -------------------- ##
478
479 AT_SETUP([%expect not enough])
480
481 AT_DATA([input.y],
482 [[%token NUM OP
483 %expect 0
484 %%
485 exp: exp OP exp | NUM;
486 ]])
487
488 AT_CHECK([bison -o input.c input.y], 1, [],
489 [input.y: warning: 1 shift/reduce conflict
490 input.y: expected 0 shift/reduce conflicts
491 ])
492 AT_CLEANUP
493
494
495 ## --------------- ##
496 ## %expect right. ##
497 ## --------------- ##
498
499 AT_SETUP([%expect right])
500
501 AT_DATA([input.y],
502 [[%token NUM OP
503 %expect 1
504 %%
505 exp: exp OP exp | NUM;
506 ]])
507
508 AT_CHECK([bison -o input.c input.y])
509 AT_CLEANUP
510
511
512 ## ------------------ ##
513 ## %expect too much. ##
514 ## ------------------ ##
515
516 AT_SETUP([%expect too much])
517
518 AT_DATA([input.y],
519 [[%token NUM OP
520 %expect 2
521 %%
522 exp: exp OP exp | NUM;
523 ]])
524
525 AT_CHECK([bison -o input.c input.y], 1, [],
526 [input.y: warning: 1 shift/reduce conflict
527 input.y: expected 2 shift/reduce conflicts
528 ])
529 AT_CLEANUP