]> git.saurik.com Git - bison.git/blob - tests/regression.at
During deterministic GLR operation, user actions should be able to
[bison.git] / tests / regression.at
1 # Bison Regressions. -*- Autotest -*-
2
3 # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
4 # Foundation, Inc.
5
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2, or (at your option)
9 # any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21 AT_BANNER([[Regression tests.]])
22
23
24 ## ------------------------- ##
25 ## Early token definitions. ##
26 ## ------------------------- ##
27
28
29 AT_SETUP([Early token definitions])
30
31 # Found in GCJ: they expect the tokens to be defined before the user
32 # prologue, so that they can use the token definitions in it.
33
34 AT_DATA_GRAMMAR([input.y],
35 [[%{
36 void yyerror (const char *s);
37 int yylex (void);
38 %}
39
40 %union
41 {
42 int val;
43 };
44 %{
45 #ifndef MY_TOKEN
46 # error "MY_TOKEN not defined."
47 #endif
48 %}
49 %token MY_TOKEN
50 %%
51 exp: MY_TOKEN;
52 %%
53 ]])
54
55 AT_CHECK([bison -o input.c input.y])
56 AT_COMPILE([input.o], [-c input.c])
57
58 AT_CLEANUP
59
60
61
62 ## ---------------- ##
63 ## Braces parsing. ##
64 ## ---------------- ##
65
66
67 AT_SETUP([Braces parsing])
68
69 AT_DATA([input.y],
70 [[/* Bison used to swallow the character after `}'. */
71
72 %%
73 exp: { tests = {{{{{{{{{{}}}}}}}}}}; };
74 %%
75 ]])
76
77 AT_CHECK([bison -v -o input.c input.y])
78
79 AT_CHECK([grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c], 0, [ignore])
80
81 AT_CLEANUP
82
83
84 ## ------------------ ##
85 ## Duplicate string. ##
86 ## ------------------ ##
87
88
89 AT_SETUP([Duplicate string])
90
91 AT_DATA([input.y],
92 [[/* `Bison -v' used to dump core when two tokens are defined with the same
93 string, as LE and GE below. */
94
95 %token NUM
96 %token LE "<="
97 %token GE "<="
98
99 %%
100 exp: '(' exp ')' | NUM ;
101 %%
102 ]])
103
104 AT_CHECK([bison -v -o input.c input.y], 0, [],
105 [[input.y:6.8-14: warning: symbol `"<="' used more than once as a literal string
106 ]])
107
108 AT_CLEANUP
109
110
111 ## ------------------- ##
112 ## Rule Line Numbers. ##
113 ## ------------------- ##
114
115 AT_SETUP([Rule Line Numbers])
116
117 AT_KEYWORDS([report])
118
119 AT_DATA([input.y],
120 [[%%
121 expr:
122 'a'
123
124 {
125
126 }
127
128 'b'
129
130 {
131
132 }
133
134 |
135
136
137 {
138
139
140 }
141
142 'c'
143
144 {
145
146 };
147 ]])
148
149 AT_CHECK([bison -o input.c -v input.y])
150
151 # Check the contents of the report.
152 AT_CHECK([cat input.output], [],
153 [[Grammar
154
155 0 $accept: expr $end
156
157 1 @1: /* empty */
158
159 2 expr: 'a' @1 'b'
160
161 3 @2: /* empty */
162
163 4 expr: @2 'c'
164
165
166 Terminals, with rules where they appear
167
168 $end (0) 0
169 'a' (97) 2
170 'b' (98) 2
171 'c' (99) 4
172 error (256)
173
174
175 Nonterminals, with rules where they appear
176
177 $accept (6)
178 on left: 0
179 expr (7)
180 on left: 2 4, on right: 0
181 @1 (8)
182 on left: 1, on right: 2
183 @2 (9)
184 on left: 3, on right: 4
185
186
187 state 0
188
189 0 $accept: . expr $end
190
191 'a' shift, and go to state 1
192
193 $default reduce using rule 3 (@2)
194
195 expr go to state 2
196 @2 go to state 3
197
198
199 state 1
200
201 2 expr: 'a' . @1 'b'
202
203 $default reduce using rule 1 (@1)
204
205 @1 go to state 4
206
207
208 state 2
209
210 0 $accept: expr . $end
211
212 $end shift, and go to state 5
213
214
215 state 3
216
217 4 expr: @2 . 'c'
218
219 'c' shift, and go to state 6
220
221
222 state 4
223
224 2 expr: 'a' @1 . 'b'
225
226 'b' shift, and go to state 7
227
228
229 state 5
230
231 0 $accept: expr $end .
232
233 $default accept
234
235
236 state 6
237
238 4 expr: @2 'c' .
239
240 $default reduce using rule 4 (expr)
241
242
243 state 7
244
245 2 expr: 'a' @1 'b' .
246
247 $default reduce using rule 2 (expr)
248 ]])
249
250 AT_CLEANUP
251
252
253
254 ## ---------------------- ##
255 ## Mixing %token styles. ##
256 ## ---------------------- ##
257
258
259 AT_SETUP([Mixing %token styles])
260
261 # Taken from the documentation.
262 AT_DATA([input.y],
263 [[%token <operator> OR "||"
264 %token <operator> LE 134 "<="
265 %left OR "<="
266 %%
267 exp: ;
268 %%
269 ]])
270
271 AT_CHECK([bison -v -o input.c input.y])
272
273 AT_CLEANUP
274
275
276
277 ## ---------------- ##
278 ## Invalid inputs. ##
279 ## ---------------- ##
280
281
282 AT_SETUP([Invalid inputs])
283
284 AT_DATA([input.y],
285 [[%%
286 ?
287 default: 'a' }
288 %&
289 %a-does-not-exist
290 %-
291 %{
292 ]])
293
294 AT_CHECK([bison input.y], [1], [],
295 [[input.y:2.1: invalid character: `?'
296 input.y:3.14: invalid character: `}'
297 input.y:4.1: invalid character: `%'
298 input.y:4.2: invalid character: `&'
299 input.y:5.1-17: invalid directive: `%a-does-not-exist'
300 input.y:6.1: invalid character: `%'
301 input.y:6.2: invalid character: `-'
302 input.y:7.1-8.0: missing `%}' at end of file
303 ]])
304
305 AT_CLEANUP
306
307
308 AT_SETUP([Invalid inputs with {}])
309
310 AT_DATA([input.y],
311 [[
312 %destructor
313 %initial-action
314 %lex-param
315 %parse-param
316 %printer
317 %union
318 ]])
319
320 AT_CHECK([bison input.y], [1], [],
321 [[input.y:3.1: missing `{' in "%destructor {...}"
322 input.y:4.1: missing `{' in "%initial-action {...}"
323 input.y:4.1: syntax error, unexpected %initial-action {...}, expecting string or identifier
324 ]])
325
326 AT_CLEANUP
327
328
329
330 ## ------------------- ##
331 ## Token definitions. ##
332 ## ------------------- ##
333
334
335 AT_SETUP([Token definitions])
336
337 # Bison managed, when fed with `%token 'f' "f"' to #define 'f'!
338 AT_DATA_GRAMMAR([input.y],
339 [%{
340 #include <stdio.h>
341 void yyerror (const char *s);
342 int yylex (void);
343 %}
344 [%error-verbose
345 %token MYEOF 0 "end of file"
346 %token 'a' "a"
347 %token B_TOKEN "b"
348 %token C_TOKEN 'c'
349 %token 'd' D_TOKEN
350 %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
351 %%
352 exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!";
353 %%
354 void
355 yyerror (char const *s)
356 {
357 fprintf (stderr, "%s\n", s);
358 }
359
360 int
361 yylex (void)
362 {
363 return SPECIAL;
364 }
365
366 int
367 main (void)
368 {
369 return yyparse ();
370 }
371 ]])
372
373 AT_CHECK([bison -o input.c input.y])
374 AT_COMPILE([input])
375 AT_DATA([experr],
376 [[syntax error, unexpected "\\'?\"\a\b\f\n\r\t\v\001\201\001\201?\?!", expecting a
377 ]])
378 AT_PARSER_CHECK([./input], 1, [], [experr])
379 AT_CLEANUP
380
381
382
383 ## -------------------- ##
384 ## Characters Escapes. ##
385 ## -------------------- ##
386
387
388 AT_SETUP([Characters Escapes])
389
390 AT_DATA_GRAMMAR([input.y],
391 [%{
392 void yyerror (const char *s);
393 int yylex (void);
394 %}
395 [%%
396 exp:
397 '\'' "\'"
398 | '\"' "\""
399 | '"' "'"
400 ;
401 ]])
402 # Pacify font-lock-mode: "
403
404 AT_CHECK([bison -o input.c input.y])
405 AT_COMPILE([input.o], [-c input.c])
406 AT_CLEANUP
407
408
409
410 ## -------------- ##
411 ## Web2c Report. ##
412 ## -------------- ##
413
414 # The generation of the reduction was once wrong in Bison, and made it
415 # miss some reductions. In the following test case, the reduction on
416 # `undef_id_tok' in state 1 was missing. This is stripped down from
417 # the actual web2c.y.
418
419 AT_SETUP([Web2c Report])
420
421 AT_KEYWORDS([report])
422
423 AT_DATA([input.y],
424 [[%token undef_id_tok const_id_tok
425
426 %start CONST_DEC_PART
427 \f
428 %%
429 CONST_DEC_PART:
430 CONST_DEC_LIST
431 ;
432
433 CONST_DEC_LIST:
434 CONST_DEC
435 | CONST_DEC_LIST CONST_DEC
436 ;
437
438 CONST_DEC:
439 { } undef_id_tok '=' const_id_tok ';'
440 ;
441 %%
442 ]])
443
444 AT_CHECK([bison -v input.y])
445 AT_CHECK([cat input.output], 0,
446 [[Grammar
447
448 0 $accept: CONST_DEC_PART $end
449
450 1 CONST_DEC_PART: CONST_DEC_LIST
451
452 2 CONST_DEC_LIST: CONST_DEC
453 3 | CONST_DEC_LIST CONST_DEC
454
455 4 @1: /* empty */
456
457 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';'
458
459
460 Terminals, with rules where they appear
461
462 $end (0) 0
463 ';' (59) 5
464 '=' (61) 5
465 error (256)
466 undef_id_tok (258) 5
467 const_id_tok (259) 5
468
469
470 Nonterminals, with rules where they appear
471
472 $accept (7)
473 on left: 0
474 CONST_DEC_PART (8)
475 on left: 1, on right: 0
476 CONST_DEC_LIST (9)
477 on left: 2 3, on right: 1 3
478 CONST_DEC (10)
479 on left: 5, on right: 2 3
480 @1 (11)
481 on left: 4, on right: 5
482
483
484 state 0
485
486 0 $accept: . CONST_DEC_PART $end
487
488 $default reduce using rule 4 (@1)
489
490 CONST_DEC_PART go to state 1
491 CONST_DEC_LIST go to state 2
492 CONST_DEC go to state 3
493 @1 go to state 4
494
495
496 state 1
497
498 0 $accept: CONST_DEC_PART . $end
499
500 $end shift, and go to state 5
501
502
503 state 2
504
505 1 CONST_DEC_PART: CONST_DEC_LIST .
506 3 CONST_DEC_LIST: CONST_DEC_LIST . CONST_DEC
507
508 undef_id_tok reduce using rule 4 (@1)
509 $default reduce using rule 1 (CONST_DEC_PART)
510
511 CONST_DEC go to state 6
512 @1 go to state 4
513
514
515 state 3
516
517 2 CONST_DEC_LIST: CONST_DEC .
518
519 $default reduce using rule 2 (CONST_DEC_LIST)
520
521
522 state 4
523
524 5 CONST_DEC: @1 . undef_id_tok '=' const_id_tok ';'
525
526 undef_id_tok shift, and go to state 7
527
528
529 state 5
530
531 0 $accept: CONST_DEC_PART $end .
532
533 $default accept
534
535
536 state 6
537
538 3 CONST_DEC_LIST: CONST_DEC_LIST CONST_DEC .
539
540 $default reduce using rule 3 (CONST_DEC_LIST)
541
542
543 state 7
544
545 5 CONST_DEC: @1 undef_id_tok . '=' const_id_tok ';'
546
547 '=' shift, and go to state 8
548
549
550 state 8
551
552 5 CONST_DEC: @1 undef_id_tok '=' . const_id_tok ';'
553
554 const_id_tok shift, and go to state 9
555
556
557 state 9
558
559 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok . ';'
560
561 ';' shift, and go to state 10
562
563
564 state 10
565
566 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';' .
567
568 $default reduce using rule 5 (CONST_DEC)
569 ]])
570
571 AT_CLEANUP
572
573
574 ## --------------- ##
575 ## Web2c Actions. ##
576 ## --------------- ##
577
578 # The generation of the mapping `state -> action' was once wrong in
579 # extremely specific situations. web2c.y exhibits this situation.
580 # Below is a stripped version of the grammar. It looks like one can
581 # simplify it further, but just don't: it is tuned to exhibit a bug,
582 # which disapears when applying sane grammar transformations.
583 #
584 # It used to be wrong on yydefact only:
585 #
586 # static const yytype_uint8 yydefact[] =
587 # {
588 # - 2, 0, 1, 0, 0, 2, 3, 2, 5, 4,
589 # + 2, 0, 1, 0, 0, 0, 3, 2, 5, 4,
590 # 0, 0
591 # };
592 #
593 # but let's check all the tables.
594
595
596 AT_SETUP([Web2c Actions])
597
598 AT_KEYWORDS([report])
599
600 AT_DATA([input.y],
601 [[%%
602 statement: struct_stat;
603 struct_stat: /* empty. */ | if else;
604 if: "if" "const" "then" statement;
605 else: "else" statement;
606 %%
607 ]])
608
609 AT_CHECK([bison -v -o input.c input.y])
610
611 # Check only the tables. We don't use --no-parser, because it is
612 # still to be implemented in the experimental branch of Bison.
613 [sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c >tables.c]
614
615 AT_CHECK([[cat tables.c]], 0,
616 [[static const yytype_uint8 yytranslate[] =
617 {
618 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
619 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
620 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
621 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
622 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
623 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
624 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
625 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
626 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
627 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
628 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
629 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
630 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
631 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
632 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
633 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
634 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
635 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
636 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
637 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
638 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
639 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
640 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
641 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
642 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
643 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
644 5, 6
645 };
646 static const yytype_uint8 yyprhs[] =
647 {
648 0, 0, 3, 5, 6, 9, 14
649 };
650 static const yytype_int8 yyrhs[] =
651 {
652 8, 0, -1, 9, -1, -1, 10, 11, -1, 3,
653 4, 5, 8, -1, 6, 8, -1
654 };
655 static const yytype_uint8 yyrline[] =
656 {
657 0, 2, 2, 3, 3, 4, 5
658 };
659 static const char *const yytname[] =
660 {
661 "$end", "error", "$undefined", "\"if\"", "\"const\"", "\"then\"",
662 "\"else\"", "$accept", "statement", "struct_stat", "if", "else", 0
663 };
664 static const yytype_uint16 yytoknum[] =
665 {
666 0, 256, 257, 258, 259, 260, 261
667 };
668 static const yytype_uint8 yyr1[] =
669 {
670 0, 7, 8, 9, 9, 10, 11
671 };
672 static const yytype_uint8 yyr2[] =
673 {
674 0, 2, 1, 0, 2, 4, 2
675 };
676 static const yytype_uint8 yydefact[] =
677 {
678 3, 0, 0, 2, 0, 0, 1, 3, 4, 3,
679 6, 5
680 };
681 static const yytype_int8 yydefgoto[] =
682 {
683 -1, 2, 3, 4, 8
684 };
685 static const yytype_int8 yypact[] =
686 {
687 -2, -1, 4, -8, 0, 2, -8, -2, -8, -2,
688 -8, -8
689 };
690 static const yytype_int8 yypgoto[] =
691 {
692 -8, -7, -8, -8, -8
693 };
694 static const yytype_uint8 yytable[] =
695 {
696 10, 1, 11, 5, 6, 0, 7, 9
697 };
698 static const yytype_int8 yycheck[] =
699 {
700 7, 3, 9, 4, 0, -1, 6, 5
701 };
702 static const yytype_uint8 yystos[] =
703 {
704 0, 3, 8, 9, 10, 4, 0, 6, 11, 5,
705 8, 8
706 };
707 ]])
708
709 AT_CLEANUP
710
711
712 ## ------------------------- ##
713 ## yycheck Bound Violation. ##
714 ## ------------------------- ##
715
716
717 # _AT_DATA_DANCER_Y(BISON-OPTIONS)
718 # --------------------------------
719 # The following grammar, taken from Andrew Suffield's GPL'd implementation
720 # of DGMTP, the Dancer Generic Message Transport Protocol, used to violate
721 # yycheck's bounds where issuing a verbose error message. Keep this test
722 # so that possible bound checking compilers could check all the skeletons.
723 m4_define([_AT_DATA_DANCER_Y],
724 [AT_DATA_GRAMMAR([dancer.y],
725 [%{
726 static int yylex (AT_LALR1_CC_IF([int *], [void]));
727 AT_LALR1_CC_IF([],
728 [#include <stdio.h>
729 static void yyerror (const char *);])
730 %}
731 $1
732 %token ARROW INVALID NUMBER STRING DATA
733 %defines
734 %verbose
735 %error-verbose
736 /* Grammar follows */
737 %%
738 line: header body
739 ;
740
741 header: '<' from ARROW to '>' type ':'
742 | '<' ARROW to '>' type ':'
743 | ARROW to type ':'
744 | type ':'
745 | '<' '>'
746 ;
747
748 from: DATA
749 | STRING
750 | INVALID
751 ;
752
753 to: DATA
754 | STRING
755 | INVALID
756 ;
757
758 type: DATA
759 | STRING
760 | INVALID
761 ;
762
763 body: /* empty */
764 | body member
765 ;
766
767 member: STRING
768 | DATA
769 | '+' NUMBER
770 | '-' NUMBER
771 | NUMBER
772 | INVALID
773 ;
774 %%
775 AT_LALR1_CC_IF(
776 [/* A C++ error reporting function. */
777 void
778 yy::parser::error (const location&, const std::string& m)
779 {
780 std::cerr << m << std::endl;
781 }
782
783 int
784 yyparse ()
785 {
786 yy::parser parser;
787 parser.set_debug_level (!!YYDEBUG);
788 return parser.parse ();
789 }
790 ],
791 [static void
792 yyerror (const char *s)
793 {
794 fprintf (stderr, "%s\n", s);
795 }])
796
797 static int
798 yylex (AT_LALR1_CC_IF([int *lval], [void]))
799 [{
800 static int toknum = 0;
801 int tokens[] =
802 {
803 ':', -1
804 };
805 ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[
806 return tokens[toknum++];
807 }]
808
809 int
810 main (void)
811 {
812 return yyparse ();
813 }
814 ])
815 ])# _AT_DATA_DANCER_Y
816
817
818 # AT_CHECK_DANCER(BISON-OPTIONS)
819 # ------------------------------
820 # Generate the grammar, compile it, run it.
821 m4_define([AT_CHECK_DANCER],
822 [AT_SETUP([Dancer $1])
823 AT_BISON_OPTION_PUSHDEFS([$1])
824 _AT_DATA_DANCER_Y([$1])
825 AT_CHECK([bison -o dancer.c dancer.y])
826 AT_LALR1_CC_IF(
827 [AT_CHECK([bison -o dancer.cc dancer.y])
828 AT_COMPILE_CXX([dancer])],
829 [AT_CHECK([bison -o dancer.c dancer.y])
830 AT_COMPILE([dancer])])
831 AT_PARSER_CHECK([./dancer], 1, [],
832 [syntax error, unexpected ':'
833 ])
834 AT_BISON_OPTION_POPDEFS
835 AT_CLEANUP
836 ])
837
838 AT_CHECK_DANCER()
839 AT_CHECK_DANCER([%glr-parser])
840 AT_CHECK_DANCER([%skeleton "lalr1.cc"])