]> git.saurik.com Git - bison.git/blame_incremental - tests/regression.at
During deterministic GLR operation, user actions should be able to
[bison.git] / tests / regression.at
... / ...
CommitLineData
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
21AT_BANNER([[Regression tests.]])
22
23
24## ------------------------- ##
25## Early token definitions. ##
26## ------------------------- ##
27
28
29AT_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
34AT_DATA_GRAMMAR([input.y],
35[[%{
36void yyerror (const char *s);
37int 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%%
51exp: MY_TOKEN;
52%%
53]])
54
55AT_CHECK([bison -o input.c input.y])
56AT_COMPILE([input.o], [-c input.c])
57
58AT_CLEANUP
59
60
61
62## ---------------- ##
63## Braces parsing. ##
64## ---------------- ##
65
66
67AT_SETUP([Braces parsing])
68
69AT_DATA([input.y],
70[[/* Bison used to swallow the character after `}'. */
71
72%%
73exp: { tests = {{{{{{{{{{}}}}}}}}}}; };
74%%
75]])
76
77AT_CHECK([bison -v -o input.c input.y])
78
79AT_CHECK([grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c], 0, [ignore])
80
81AT_CLEANUP
82
83
84## ------------------ ##
85## Duplicate string. ##
86## ------------------ ##
87
88
89AT_SETUP([Duplicate string])
90
91AT_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%%
100exp: '(' exp ')' | NUM ;
101%%
102]])
103
104AT_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
108AT_CLEANUP
109
110
111## ------------------- ##
112## Rule Line Numbers. ##
113## ------------------- ##
114
115AT_SETUP([Rule Line Numbers])
116
117AT_KEYWORDS([report])
118
119AT_DATA([input.y],
120[[%%
121expr:
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
149AT_CHECK([bison -o input.c -v input.y])
150
151# Check the contents of the report.
152AT_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
166Terminals, with rules where they appear
167
168$end (0) 0
169'a' (97) 2
170'b' (98) 2
171'c' (99) 4
172error (256)
173
174
175Nonterminals, with rules where they appear
176
177$accept (6)
178 on left: 0
179expr (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
187state 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
199state 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
208state 2
209
210 0 $accept: expr . $end
211
212 $end shift, and go to state 5
213
214
215state 3
216
217 4 expr: @2 . 'c'
218
219 'c' shift, and go to state 6
220
221
222state 4
223
224 2 expr: 'a' @1 . 'b'
225
226 'b' shift, and go to state 7
227
228
229state 5
230
231 0 $accept: expr $end .
232
233 $default accept
234
235
236state 6
237
238 4 expr: @2 'c' .
239
240 $default reduce using rule 4 (expr)
241
242
243state 7
244
245 2 expr: 'a' @1 'b' .
246
247 $default reduce using rule 2 (expr)
248]])
249
250AT_CLEANUP
251
252
253
254## ---------------------- ##
255## Mixing %token styles. ##
256## ---------------------- ##
257
258
259AT_SETUP([Mixing %token styles])
260
261# Taken from the documentation.
262AT_DATA([input.y],
263[[%token <operator> OR "||"
264%token <operator> LE 134 "<="
265%left OR "<="
266%%
267exp: ;
268%%
269]])
270
271AT_CHECK([bison -v -o input.c input.y])
272
273AT_CLEANUP
274
275
276
277## ---------------- ##
278## Invalid inputs. ##
279## ---------------- ##
280
281
282AT_SETUP([Invalid inputs])
283
284AT_DATA([input.y],
285[[%%
286?
287default: 'a' }
288%&
289%a-does-not-exist
290%-
291%{
292]])
293
294AT_CHECK([bison input.y], [1], [],
295[[input.y:2.1: invalid character: `?'
296input.y:3.14: invalid character: `}'
297input.y:4.1: invalid character: `%'
298input.y:4.2: invalid character: `&'
299input.y:5.1-17: invalid directive: `%a-does-not-exist'
300input.y:6.1: invalid character: `%'
301input.y:6.2: invalid character: `-'
302input.y:7.1-8.0: missing `%}' at end of file
303]])
304
305AT_CLEANUP
306
307
308AT_SETUP([Invalid inputs with {}])
309
310AT_DATA([input.y],
311[[
312%destructor
313%initial-action
314%lex-param
315%parse-param
316%printer
317%union
318]])
319
320AT_CHECK([bison input.y], [1], [],
321[[input.y:3.1: missing `{' in "%destructor {...}"
322input.y:4.1: missing `{' in "%initial-action {...}"
323input.y:4.1: syntax error, unexpected %initial-action {...}, expecting string or identifier
324]])
325
326AT_CLEANUP
327
328
329
330## ------------------- ##
331## Token definitions. ##
332## ------------------- ##
333
334
335AT_SETUP([Token definitions])
336
337# Bison managed, when fed with `%token 'f' "f"' to #define 'f'!
338AT_DATA_GRAMMAR([input.y],
339[%{
340#include <stdio.h>
341void yyerror (const char *s);
342int 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%%
352exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!";
353%%
354void
355yyerror (char const *s)
356{
357 fprintf (stderr, "%s\n", s);
358}
359
360int
361yylex (void)
362{
363 return SPECIAL;
364}
365
366int
367main (void)
368{
369 return yyparse ();
370}
371]])
372
373AT_CHECK([bison -o input.c input.y])
374AT_COMPILE([input])
375AT_DATA([experr],
376[[syntax error, unexpected "\\'?\"\a\b\f\n\r\t\v\001\201\001\201?\?!", expecting a
377]])
378AT_PARSER_CHECK([./input], 1, [], [experr])
379AT_CLEANUP
380
381
382
383## -------------------- ##
384## Characters Escapes. ##
385## -------------------- ##
386
387
388AT_SETUP([Characters Escapes])
389
390AT_DATA_GRAMMAR([input.y],
391[%{
392void yyerror (const char *s);
393int yylex (void);
394%}
395[%%
396exp:
397 '\'' "\'"
398| '\"' "\""
399| '"' "'"
400;
401]])
402# Pacify font-lock-mode: "
403
404AT_CHECK([bison -o input.c input.y])
405AT_COMPILE([input.o], [-c input.c])
406AT_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
419AT_SETUP([Web2c Report])
420
421AT_KEYWORDS([report])
422
423AT_DATA([input.y],
424[[%token undef_id_tok const_id_tok
425
426%start CONST_DEC_PART
427\f
428%%
429CONST_DEC_PART:
430 CONST_DEC_LIST
431 ;
432
433CONST_DEC_LIST:
434 CONST_DEC
435 | CONST_DEC_LIST CONST_DEC
436 ;
437
438CONST_DEC:
439 { } undef_id_tok '=' const_id_tok ';'
440 ;
441%%
442]])
443
444AT_CHECK([bison -v input.y])
445AT_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
460Terminals, with rules where they appear
461
462$end (0) 0
463';' (59) 5
464'=' (61) 5
465error (256)
466undef_id_tok (258) 5
467const_id_tok (259) 5
468
469
470Nonterminals, with rules where they appear
471
472$accept (7)
473 on left: 0
474CONST_DEC_PART (8)
475 on left: 1, on right: 0
476CONST_DEC_LIST (9)
477 on left: 2 3, on right: 1 3
478CONST_DEC (10)
479 on left: 5, on right: 2 3
480@1 (11)
481 on left: 4, on right: 5
482
483
484state 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
496state 1
497
498 0 $accept: CONST_DEC_PART . $end
499
500 $end shift, and go to state 5
501
502
503state 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
515state 3
516
517 2 CONST_DEC_LIST: CONST_DEC .
518
519 $default reduce using rule 2 (CONST_DEC_LIST)
520
521
522state 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
529state 5
530
531 0 $accept: CONST_DEC_PART $end .
532
533 $default accept
534
535
536state 6
537
538 3 CONST_DEC_LIST: CONST_DEC_LIST CONST_DEC .
539
540 $default reduce using rule 3 (CONST_DEC_LIST)
541
542
543state 7
544
545 5 CONST_DEC: @1 undef_id_tok . '=' const_id_tok ';'
546
547 '=' shift, and go to state 8
548
549
550state 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
557state 9
558
559 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok . ';'
560
561 ';' shift, and go to state 10
562
563
564state 10
565
566 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';' .
567
568 $default reduce using rule 5 (CONST_DEC)
569]])
570
571AT_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
596AT_SETUP([Web2c Actions])
597
598AT_KEYWORDS([report])
599
600AT_DATA([input.y],
601[[%%
602statement: struct_stat;
603struct_stat: /* empty. */ | if else;
604if: "if" "const" "then" statement;
605else: "else" statement;
606%%
607]])
608
609AT_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
615AT_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};
646static const yytype_uint8 yyprhs[] =
647{
648 0, 0, 3, 5, 6, 9, 14
649};
650static 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};
655static const yytype_uint8 yyrline[] =
656{
657 0, 2, 2, 3, 3, 4, 5
658};
659static const char *const yytname[] =
660{
661 "$end", "error", "$undefined", "\"if\"", "\"const\"", "\"then\"",
662 "\"else\"", "$accept", "statement", "struct_stat", "if", "else", 0
663};
664static const yytype_uint16 yytoknum[] =
665{
666 0, 256, 257, 258, 259, 260, 261
667};
668static const yytype_uint8 yyr1[] =
669{
670 0, 7, 8, 9, 9, 10, 11
671};
672static const yytype_uint8 yyr2[] =
673{
674 0, 2, 1, 0, 2, 4, 2
675};
676static const yytype_uint8 yydefact[] =
677{
678 3, 0, 0, 2, 0, 0, 1, 3, 4, 3,
679 6, 5
680};
681static const yytype_int8 yydefgoto[] =
682{
683 -1, 2, 3, 4, 8
684};
685static const yytype_int8 yypact[] =
686{
687 -2, -1, 4, -8, 0, 2, -8, -2, -8, -2,
688 -8, -8
689};
690static const yytype_int8 yypgoto[] =
691{
692 -8, -7, -8, -8, -8
693};
694static const yytype_uint8 yytable[] =
695{
696 10, 1, 11, 5, 6, 0, 7, 9
697};
698static const yytype_int8 yycheck[] =
699{
700 7, 3, 9, 4, 0, -1, 6, 5
701};
702static const yytype_uint8 yystos[] =
703{
704 0, 3, 8, 9, 10, 4, 0, 6, 11, 5,
705 8, 8
706};
707]])
708
709AT_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.
723m4_define([_AT_DATA_DANCER_Y],
724[AT_DATA_GRAMMAR([dancer.y],
725[%{
726static int yylex (AT_LALR1_CC_IF([int *], [void]));
727AT_LALR1_CC_IF([],
728[#include <stdio.h>
729static 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%%
738line: header body
739 ;
740
741header: '<' from ARROW to '>' type ':'
742 | '<' ARROW to '>' type ':'
743 | ARROW to type ':'
744 | type ':'
745 | '<' '>'
746 ;
747
748from: DATA
749 | STRING
750 | INVALID
751 ;
752
753to: DATA
754 | STRING
755 | INVALID
756 ;
757
758type: DATA
759 | STRING
760 | INVALID
761 ;
762
763body: /* empty */
764 | body member
765 ;
766
767member: STRING
768 | DATA
769 | '+' NUMBER
770 | '-' NUMBER
771 | NUMBER
772 | INVALID
773 ;
774%%
775AT_LALR1_CC_IF(
776[/* A C++ error reporting function. */
777void
778yy::parser::error (const location&, const std::string& m)
779{
780 std::cerr << m << std::endl;
781}
782
783int
784yyparse ()
785{
786 yy::parser parser;
787 parser.set_debug_level (!!YYDEBUG);
788 return parser.parse ();
789}
790],
791[static void
792yyerror (const char *s)
793{
794 fprintf (stderr, "%s\n", s);
795}])
796
797static int
798yylex (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
809int
810main (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.
821m4_define([AT_CHECK_DANCER],
822[AT_SETUP([Dancer $1])
823AT_BISON_OPTION_PUSHDEFS([$1])
824_AT_DATA_DANCER_Y([$1])
825AT_CHECK([bison -o dancer.c dancer.y])
826AT_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])])
831AT_PARSER_CHECK([./dancer], 1, [],
832[syntax error, unexpected ':'
833])
834AT_BISON_OPTION_POPDEFS
835AT_CLEANUP
836])
837
838AT_CHECK_DANCER()
839AT_CHECK_DANCER([%glr-parser])
840AT_CHECK_DANCER([%skeleton "lalr1.cc"])