]> git.saurik.com Git - bison.git/blame_incremental - tests/regression.at
(xsl:template match="terminal"): Use new attribute names.
[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 3 of the License, or
9# (at your option) 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, see <http://www.gnu.org/licenses/>.
18
19AT_BANNER([[Regression tests.]])
20
21
22## ------------------ ##
23## Trivial grammars. ##
24## ------------------ ##
25
26AT_SETUP([Trivial grammars])
27
28AT_DATA_GRAMMAR([input.y],
29[[%{
30void yyerror (char const *);
31int yylex (void);
32#define YYSTYPE int *
33%}
34
35%error-verbose
36
37%%
38
39program: 'x';
40]])
41
42AT_CHECK([bison -o input.c input.y])
43AT_COMPILE([input.o], [-c input.c])
44AT_COMPILE([input.o], [-DYYDEBUG -c input.c])
45
46AT_CLEANUP
47
48
49
50## ----------------- ##
51## YYSTYPE typedef. ##
52## ----------------- ##
53
54AT_SETUP([YYSTYPE typedef])
55
56AT_DATA_GRAMMAR([input.y],
57[[%{
58void yyerror (char const *);
59int yylex (void);
60typedef union { char const *val; } YYSTYPE;
61%}
62
63%type <val> program
64
65%%
66
67program: { $$ = ""; };
68]])
69
70AT_CHECK([bison -o input.c input.y])
71AT_COMPILE([input.o], [-c input.c])
72
73AT_CLEANUP
74
75
76
77## ------------------------------------- ##
78## Early token definitions with --yacc. ##
79## ------------------------------------- ##
80
81
82AT_SETUP([Early token definitions with --yacc])
83
84# Found in GCJ: they expect the tokens to be defined before the user
85# prologue, so that they can use the token definitions in it.
86
87AT_DATA_GRAMMAR([input.y],
88[[%{
89void yyerror (const char *s);
90int yylex (void);
91%}
92
93%union
94{
95 int val;
96};
97%{
98#ifndef MY_TOKEN
99# error "MY_TOKEN not defined."
100#endif
101%}
102%token MY_TOKEN
103%%
104exp: MY_TOKEN;
105%%
106]])
107
108AT_CHECK([bison -y -o input.c input.y])
109AT_COMPILE([input.o], [-c input.c])
110
111AT_CLEANUP
112
113
114
115## ---------------------------------------- ##
116## Early token definitions without --yacc. ##
117## ---------------------------------------- ##
118
119
120AT_SETUP([Early token definitions without --yacc])
121
122# Found in GCJ: they expect the tokens to be defined before the user
123# prologue, so that they can use the token definitions in it.
124
125AT_DATA_GRAMMAR([input.y],
126[[%{
127#include <stdio.h>
128void yyerror (const char *s);
129int yylex (void);
130void print_my_token (void);
131%}
132
133%union
134{
135 int val;
136};
137%{
138void
139print_my_token (void)
140{
141 enum yytokentype my_token = MY_TOKEN;
142 printf ("%d\n", my_token);
143}
144%}
145%token MY_TOKEN
146%%
147exp: MY_TOKEN;
148%%
149]])
150
151AT_CHECK([bison -o input.c input.y])
152AT_COMPILE([input.o], [-c input.c])
153
154AT_CLEANUP
155
156
157
158## ---------------- ##
159## Braces parsing. ##
160## ---------------- ##
161
162
163AT_SETUP([Braces parsing])
164
165AT_DATA([input.y],
166[[/* Bison used to swallow the character after `}'. */
167
168%%
169exp: { tests = {{{{{{{{{{}}}}}}}}}}; };
170%%
171]])
172
173AT_CHECK([bison -v -o input.c input.y])
174
175AT_CHECK([grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c], 0, [ignore])
176
177AT_CLEANUP
178
179
180## ------------------ ##
181## Duplicate string. ##
182## ------------------ ##
183
184
185AT_SETUP([Duplicate string])
186
187AT_DATA([input.y],
188[[/* `Bison -v' used to dump core when two tokens are defined with the same
189 string, as LE and GE below. */
190
191%token NUM
192%token LE "<="
193%token GE "<="
194
195%%
196exp: '(' exp ')' | NUM ;
197%%
198]])
199
200AT_CHECK([bison -v -o input.c input.y], 0, [],
201[[input.y:6.8-14: warning: symbol `"<="' used more than once as a literal string
202]])
203
204AT_CLEANUP
205
206
207## ------------------- ##
208## Rule Line Numbers. ##
209## ------------------- ##
210
211AT_SETUP([Rule Line Numbers])
212
213AT_KEYWORDS([report])
214
215AT_DATA([input.y],
216[[%%
217expr:
218'a'
219
220{
221
222}
223
224'b'
225
226{
227
228}
229
230|
231
232
233{
234
235
236}
237
238'c'
239
240{
241
242};
243]])
244
245AT_CHECK([bison -o input.c -v input.y])
246
247# Check the contents of the report.
248AT_CHECK([cat input.output], [],
249[[Grammar
250
251 0 $accept: expr $end
252
253 1 $@1: /* empty */
254
255 2 expr: 'a' $@1 'b'
256
257 3 $@2: /* empty */
258
259 4 expr: $@2 'c'
260
261
262Terminals, with rules where they appear
263
264$end (0) 0
265'a' (97) 2
266'b' (98) 2
267'c' (99) 4
268error (256)
269
270
271Nonterminals, with rules where they appear
272
273$accept (6)
274 on left: 0
275expr (7)
276 on left: 2 4, on right: 0
277$@1 (8)
278 on left: 1, on right: 2
279$@2 (9)
280 on left: 3, on right: 4
281
282
283state 0
284
285 0 $accept: . expr $end
286
287 'a' shift, and go to state 1
288
289 $default reduce using rule 3 ($@2)
290
291 expr go to state 2
292 $@2 go to state 3
293
294
295state 1
296
297 2 expr: 'a' . $@1 'b'
298
299 $default reduce using rule 1 ($@1)
300
301 $@1 go to state 4
302
303
304state 2
305
306 0 $accept: expr . $end
307
308 $end shift, and go to state 5
309
310
311state 3
312
313 4 expr: $@2 . 'c'
314
315 'c' shift, and go to state 6
316
317
318state 4
319
320 2 expr: 'a' $@1 . 'b'
321
322 'b' shift, and go to state 7
323
324
325state 5
326
327 0 $accept: expr $end .
328
329 $default accept
330
331
332state 6
333
334 4 expr: $@2 'c' .
335
336 $default reduce using rule 4 (expr)
337
338
339state 7
340
341 2 expr: 'a' $@1 'b' .
342
343 $default reduce using rule 2 (expr)
344]])
345
346AT_CLEANUP
347
348
349
350## ---------------------- ##
351## Mixing %token styles. ##
352## ---------------------- ##
353
354
355AT_SETUP([Mixing %token styles])
356
357# Taken from the documentation.
358AT_DATA([input.y],
359[[%token <operator> OR "||"
360%token <operator> LE 134 "<="
361%left OR "<="
362%%
363exp: ;
364%%
365]])
366
367AT_CHECK([bison -v -o input.c input.y])
368
369AT_CLEANUP
370
371
372
373## ---------------- ##
374## Invalid inputs. ##
375## ---------------- ##
376
377
378AT_SETUP([Invalid inputs])
379
380AT_DATA([input.y],
381[[%%
382?
383default: 'a' }
384%&
385%a-does-not-exist
386%-
387%{
388]])
389
390AT_CHECK([bison input.y], [1], [],
391[[input.y:2.1: invalid character: `?'
392input.y:3.14: invalid character: `}'
393input.y:4.1: invalid character: `%'
394input.y:4.2: invalid character: `&'
395input.y:5.1-17: invalid directive: `%a-does-not-exist'
396input.y:6.1: invalid character: `%'
397input.y:6.2: invalid character: `-'
398input.y:7.1-8.0: missing `%}' at end of file
399input.y:7.1-8.0: syntax error, unexpected %{...%}
400]])
401
402AT_CLEANUP
403
404
405AT_SETUP([Invalid inputs with {}])
406
407AT_DATA([input.y],
408[[
409%destructor
410%initial-action
411%lex-param
412%parse-param
413%printer
414%union
415]])
416
417AT_CHECK([bison input.y], [1], [],
418[[input.y:3.1-15: syntax error, unexpected %initial-action, expecting {...}
419]])
420
421AT_CLEANUP
422
423
424
425## ------------------- ##
426## Token definitions. ##
427## ------------------- ##
428
429
430AT_SETUP([Token definitions])
431
432# Bison managed, when fed with `%token 'f' "f"' to #define 'f'!
433AT_DATA_GRAMMAR([input.y],
434[%{
435#include <stdlib.h>
436#include <stdio.h>
437void yyerror (const char *s);
438int yylex (void);
439%}
440[%error-verbose
441%token MYEOF 0 "end of file"
442%token 'a' "a"
443%token B_TOKEN "b"
444%token C_TOKEN 'c'
445%token 'd' D_TOKEN
446%token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
447%%
448exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!";
449%%
450void
451yyerror (char const *s)
452{
453 fprintf (stderr, "%s\n", s);
454}
455
456int
457yylex (void)
458{
459 static int called;
460 if (called++)
461 abort ();
462 return SPECIAL;
463}
464
465int
466main (void)
467{
468 return yyparse ();
469}
470]])
471
472AT_CHECK([bison -o input.c input.y])
473AT_COMPILE([input])
474AT_DATA([experr],
475[[syntax error, unexpected "\\'?\"\a\b\f\n\r\t\v\001\201\001\201?\?!", expecting a
476]])
477AT_PARSER_CHECK([./input], 1, [], [experr])
478AT_CLEANUP
479
480
481
482## -------------------- ##
483## Characters Escapes. ##
484## -------------------- ##
485
486
487AT_SETUP([Characters Escapes])
488
489AT_DATA_GRAMMAR([input.y],
490[%{
491void yyerror (const char *s);
492int yylex (void);
493%}
494[%%
495exp:
496 '\'' "\'"
497| '\"' "\""
498| '"' "'"
499;
500]])
501# Pacify font-lock-mode: "
502
503AT_CHECK([bison -o input.c input.y])
504AT_COMPILE([input.o], [-c input.c])
505AT_CLEANUP
506
507
508
509## -------------- ##
510## Web2c Report. ##
511## -------------- ##
512
513# The generation of the reduction was once wrong in Bison, and made it
514# miss some reductions. In the following test case, the reduction on
515# `undef_id_tok' in state 1 was missing. This is stripped down from
516# the actual web2c.y.
517
518AT_SETUP([Web2c Report])
519
520AT_KEYWORDS([report])
521
522AT_DATA([input.y],
523[[%token undef_id_tok const_id_tok
524
525%start CONST_DEC_PART
526\f
527%%
528CONST_DEC_PART:
529 CONST_DEC_LIST
530 ;
531
532CONST_DEC_LIST:
533 CONST_DEC
534 | CONST_DEC_LIST CONST_DEC
535 ;
536
537CONST_DEC:
538 { } undef_id_tok '=' const_id_tok ';'
539 ;
540%%
541]])
542
543AT_CHECK([bison -v input.y])
544AT_CHECK([cat input.output], 0,
545[[Grammar
546
547 0 $accept: CONST_DEC_PART $end
548
549 1 CONST_DEC_PART: CONST_DEC_LIST
550
551 2 CONST_DEC_LIST: CONST_DEC
552 3 | CONST_DEC_LIST CONST_DEC
553
554 4 $@1: /* empty */
555
556 5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok ';'
557
558
559Terminals, with rules where they appear
560
561$end (0) 0
562';' (59) 5
563'=' (61) 5
564error (256)
565undef_id_tok (258) 5
566const_id_tok (259) 5
567
568
569Nonterminals, with rules where they appear
570
571$accept (7)
572 on left: 0
573CONST_DEC_PART (8)
574 on left: 1, on right: 0
575CONST_DEC_LIST (9)
576 on left: 2 3, on right: 1 3
577CONST_DEC (10)
578 on left: 5, on right: 2 3
579$@1 (11)
580 on left: 4, on right: 5
581
582
583state 0
584
585 0 $accept: . CONST_DEC_PART $end
586
587 $default reduce using rule 4 ($@1)
588
589 CONST_DEC_PART go to state 1
590 CONST_DEC_LIST go to state 2
591 CONST_DEC go to state 3
592 $@1 go to state 4
593
594
595state 1
596
597 0 $accept: CONST_DEC_PART . $end
598
599 $end shift, and go to state 5
600
601
602state 2
603
604 1 CONST_DEC_PART: CONST_DEC_LIST .
605 3 CONST_DEC_LIST: CONST_DEC_LIST . CONST_DEC
606
607 undef_id_tok reduce using rule 4 ($@1)
608 $default reduce using rule 1 (CONST_DEC_PART)
609
610 CONST_DEC go to state 6
611 $@1 go to state 4
612
613
614state 3
615
616 2 CONST_DEC_LIST: CONST_DEC .
617
618 $default reduce using rule 2 (CONST_DEC_LIST)
619
620
621state 4
622
623 5 CONST_DEC: $@1 . undef_id_tok '=' const_id_tok ';'
624
625 undef_id_tok shift, and go to state 7
626
627
628state 5
629
630 0 $accept: CONST_DEC_PART $end .
631
632 $default accept
633
634
635state 6
636
637 3 CONST_DEC_LIST: CONST_DEC_LIST CONST_DEC .
638
639 $default reduce using rule 3 (CONST_DEC_LIST)
640
641
642state 7
643
644 5 CONST_DEC: $@1 undef_id_tok . '=' const_id_tok ';'
645
646 '=' shift, and go to state 8
647
648
649state 8
650
651 5 CONST_DEC: $@1 undef_id_tok '=' . const_id_tok ';'
652
653 const_id_tok shift, and go to state 9
654
655
656state 9
657
658 5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok . ';'
659
660 ';' shift, and go to state 10
661
662
663state 10
664
665 5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok ';' .
666
667 $default reduce using rule 5 (CONST_DEC)
668]])
669
670AT_CLEANUP
671
672
673## --------------- ##
674## Web2c Actions. ##
675## --------------- ##
676
677# The generation of the mapping `state -> action' was once wrong in
678# extremely specific situations. web2c.y exhibits this situation.
679# Below is a stripped version of the grammar. It looks like one can
680# simplify it further, but just don't: it is tuned to exhibit a bug,
681# which disapears when applying sane grammar transformations.
682#
683# It used to be wrong on yydefact only:
684#
685# static const yytype_uint8 yydefact[] =
686# {
687# - 2, 0, 1, 0, 0, 2, 3, 2, 5, 4,
688# + 2, 0, 1, 0, 0, 0, 3, 2, 5, 4,
689# 0, 0
690# };
691#
692# but let's check all the tables.
693
694
695AT_SETUP([Web2c Actions])
696
697AT_KEYWORDS([report])
698
699AT_DATA([input.y],
700[[%%
701statement: struct_stat;
702struct_stat: /* empty. */ | if else;
703if: "if" "const" "then" statement;
704else: "else" statement;
705%%
706]])
707
708AT_CHECK([bison -v -o input.c input.y])
709
710# Check only the tables.
711[sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c >tables.c]
712
713AT_CHECK([[cat tables.c]], 0,
714[[static const yytype_uint8 yytranslate[] =
715{
716 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
717 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
718 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
719 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
720 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
721 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
722 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
723 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
724 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
725 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
726 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
727 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
728 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
729 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
730 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
731 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
732 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
733 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
734 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
735 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
736 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
737 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
738 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
739 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
740 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
741 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
742 5, 6
743};
744static const yytype_uint8 yyprhs[] =
745{
746 0, 0, 3, 5, 6, 9, 14
747};
748static const yytype_int8 yyrhs[] =
749{
750 8, 0, -1, 9, -1, -1, 10, 11, -1, 3,
751 4, 5, 8, -1, 6, 8, -1
752};
753static const yytype_uint8 yyrline[] =
754{
755 0, 2, 2, 3, 3, 4, 5
756};
757static const char *const yytname[] =
758{
759 "$end", "error", "$undefined", "\"if\"", "\"const\"", "\"then\"",
760 "\"else\"", "$accept", "statement", "struct_stat", "if", "else", 0
761};
762static const yytype_uint16 yytoknum[] =
763{
764 0, 256, 257, 258, 259, 260, 261
765};
766static const yytype_uint8 yyr1[] =
767{
768 0, 7, 8, 9, 9, 10, 11
769};
770static const yytype_uint8 yyr2[] =
771{
772 0, 2, 1, 0, 2, 4, 2
773};
774static const yytype_uint8 yydefact[] =
775{
776 3, 0, 0, 2, 0, 0, 1, 3, 4, 3,
777 6, 5
778};
779static const yytype_int8 yydefgoto[] =
780{
781 -1, 2, 3, 4, 8
782};
783static const yytype_int8 yypact[] =
784{
785 -2, -1, 4, -8, 0, 2, -8, -2, -8, -2,
786 -8, -8
787};
788static const yytype_int8 yypgoto[] =
789{
790 -8, -7, -8, -8, -8
791};
792static const yytype_uint8 yytable[] =
793{
794 10, 1, 11, 5, 6, 0, 7, 9
795};
796static const yytype_int8 yycheck[] =
797{
798 7, 3, 9, 4, 0, -1, 6, 5
799};
800static const yytype_uint8 yystos[] =
801{
802 0, 3, 8, 9, 10, 4, 0, 6, 11, 5,
803 8, 8
804};
805]])
806
807AT_CLEANUP
808
809
810## ------------------------- ##
811## yycheck Bound Violation. ##
812## ------------------------- ##
813
814
815# _AT_DATA_DANCER_Y(BISON-OPTIONS)
816# --------------------------------
817# The following grammar, taken from Andrew Suffield's GPL'd implementation
818# of DGMTP, the Dancer Generic Message Transport Protocol, used to violate
819# yycheck's bounds where issuing a verbose error message. Keep this test
820# so that possible bound checking compilers could check all the skeletons.
821m4_define([_AT_DATA_DANCER_Y],
822[AT_DATA_GRAMMAR([dancer.y],
823[%{
824static int yylex (AT_LALR1_CC_IF([int *], [void]));
825AT_LALR1_CC_IF([],
826[#include <stdlib.h>
827#include <stdio.h>
828static void yyerror (const char *);])
829%}
830$1
831%token ARROW INVALID NUMBER STRING DATA
832%defines
833%verbose
834%error-verbose
835/* Grammar follows */
836%%
837line: header body
838 ;
839
840header: '<' from ARROW to '>' type ':'
841 | '<' ARROW to '>' type ':'
842 | ARROW to type ':'
843 | type ':'
844 | '<' '>'
845 ;
846
847from: DATA
848 | STRING
849 | INVALID
850 ;
851
852to: DATA
853 | STRING
854 | INVALID
855 ;
856
857type: DATA
858 | STRING
859 | INVALID
860 ;
861
862body: /* empty */
863 | body member
864 ;
865
866member: STRING
867 | DATA
868 | '+' NUMBER
869 | '-' NUMBER
870 | NUMBER
871 | INVALID
872 ;
873%%
874AT_LALR1_CC_IF(
875[/* A C++ error reporting function. */
876void
877yy::parser::error (const location&, const std::string& m)
878{
879 std::cerr << m << std::endl;
880}
881
882int
883yyparse ()
884{
885 yy::parser parser;
886#if YYDEBUG
887 parser.set_debug_level (YYDEBUG);
888#endif
889 return parser.parse ();
890}
891],
892[static void
893yyerror (const char *s)
894{
895 fprintf (stderr, "%s\n", s);
896}])
897
898static int
899yylex (AT_LALR1_CC_IF([int *lval], [void]))
900[{
901 static int const tokens[] =
902 {
903 ':', -1
904 };
905 static size_t toknum;
906 ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[
907 if (! (toknum < sizeof tokens / sizeof *tokens))
908 abort ();
909 return tokens[toknum++];
910}]
911
912int
913main (void)
914{
915 return yyparse ();
916}
917])
918])# _AT_DATA_DANCER_Y
919
920
921# AT_CHECK_DANCER(BISON-OPTIONS)
922# ------------------------------
923# Generate the grammar, compile it, run it.
924m4_define([AT_CHECK_DANCER],
925[AT_SETUP([Dancer $1])
926AT_BISON_OPTION_PUSHDEFS([$1])
927_AT_DATA_DANCER_Y([$1])
928AT_CHECK([bison -o dancer.c dancer.y])
929AT_LALR1_CC_IF(
930 [AT_CHECK([bison -o dancer.cc dancer.y])
931 AT_COMPILE_CXX([dancer])],
932 [AT_CHECK([bison -o dancer.c dancer.y])
933 AT_COMPILE([dancer])])
934AT_PARSER_CHECK([./dancer], 1, [],
935[syntax error, unexpected ':'
936])
937AT_BISON_OPTION_POPDEFS
938AT_CLEANUP
939])
940
941AT_CHECK_DANCER()
942AT_CHECK_DANCER([%glr-parser])
943AT_CHECK_DANCER([%skeleton "lalr1.cc"])
944
945
946## ------------------------------------------ ##
947## Diagnostic that expects two alternatives. ##
948## ------------------------------------------ ##
949
950
951# _AT_DATA_EXPECT2_Y(BISON-OPTIONS)
952# --------------------------------
953m4_define([_AT_DATA_EXPECT2_Y],
954[AT_DATA_GRAMMAR([expect2.y],
955[%{
956static int yylex (AT_LALR1_CC_IF([int *], [void]));
957AT_LALR1_CC_IF([],
958[#include <stdio.h>
959#include <stdlib.h>
960static void yyerror (const char *);])
961%}
962$1
963%defines
964%error-verbose
965%token A 1000
966%token B
967
968%%
969program: /* empty */
970 | program e ';'
971 | program error ';';
972
973e: e '+' t | t;
974t: A | B;
975
976%%
977AT_LALR1_CC_IF(
978[/* A C++ error reporting function. */
979void
980yy::parser::error (const location&, const std::string& m)
981{
982 std::cerr << m << std::endl;
983}
984
985int
986yyparse ()
987{
988 yy::parser parser;
989 return parser.parse ();
990}
991],
992[static void
993yyerror (const char *s)
994{
995 fprintf (stderr, "%s\n", s);
996}])
997
998static int
999yylex (AT_LALR1_CC_IF([int *lval], [void]))
1000[{
1001 static int const tokens[] =
1002 {
1003 1000, '+', '+', -1
1004 };
1005 static size_t toknum;
1006 ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[
1007 if (! (toknum < sizeof tokens / sizeof *tokens))
1008 abort ();
1009 return tokens[toknum++];
1010}]
1011
1012int
1013main (void)
1014{
1015 return yyparse ();
1016}
1017])
1018])# _AT_DATA_EXPECT2_Y
1019
1020
1021# AT_CHECK_EXPECT2(BISON-OPTIONS)
1022# ------------------------------
1023# Generate the grammar, compile it, run it.
1024m4_define([AT_CHECK_EXPECT2],
1025[AT_SETUP([Expecting two tokens $1])
1026AT_BISON_OPTION_PUSHDEFS([$1])
1027_AT_DATA_EXPECT2_Y([$1])
1028AT_CHECK([bison -o expect2.c expect2.y])
1029AT_LALR1_CC_IF(
1030 [AT_CHECK([bison -o expect2.cc expect2.y])
1031 AT_COMPILE_CXX([expect2])],
1032 [AT_CHECK([bison -o expect2.c expect2.y])
1033 AT_COMPILE([expect2])])
1034AT_PARSER_CHECK([./expect2], 1, [],
1035[syntax error, unexpected '+', expecting A or B
1036])
1037AT_BISON_OPTION_POPDEFS
1038AT_CLEANUP
1039])
1040
1041AT_CHECK_EXPECT2()
1042AT_CHECK_EXPECT2([%glr-parser])
1043AT_CHECK_EXPECT2([%skeleton "lalr1.cc"])
1044
1045
1046
1047## --------------------------------------------- ##
1048## Braced code in declaration in rules section. ##
1049## --------------------------------------------- ##
1050
1051AT_SETUP([Braced code in declaration in rules section])
1052
1053# Bison once mistook braced code in a declaration in the rules section to be a
1054# rule action.
1055
1056AT_DATA_GRAMMAR([input.y],
1057[[%{
1058#include <stdio.h>
1059static void yyerror (char const *msg);
1060static int yylex (void);
1061%}
1062
1063%error-verbose
1064
1065%%
1066
1067start:
1068 {
1069 printf ("Bison would once convert this action to a midrule because of the"
1070 " subsequent braced code.\n");
1071 }
1072 ;
1073
1074%destructor { fprintf (stderr, "DESTRUCTOR\n"); } 'a';
1075%printer { fprintf (yyoutput, "PRINTER"); } 'a';
1076
1077%%
1078
1079static void
1080yyerror (char const *msg)
1081{
1082 fprintf (stderr, "%s\n", msg);
1083}
1084
1085static int
1086yylex (void)
1087{
1088 return 'a';
1089}
1090
1091int
1092main (void)
1093{
1094 yydebug = 1;
1095 return !yyparse ();
1096}
1097]])
1098
1099AT_CHECK([bison -t -o input.c input.y])
1100AT_COMPILE([input])
1101AT_PARSER_CHECK([./input], 0,
1102[[Bison would once convert this action to a midrule because of the subsequent braced code.
1103]],
1104[[Starting parse
1105Entering state 0
1106Reducing stack by rule 1 (line 20):
1107-> $$ = nterm start ()
1108Stack now 0
1109Entering state 1
1110Reading a token: Next token is token 'a' (PRINTER)
1111syntax error, unexpected 'a', expecting $end
1112Error: popping nterm start ()
1113Stack now 0
1114Cleanup: discarding lookahead token 'a' (PRINTER)
1115DESTRUCTOR
1116Stack now 0
1117]])
1118
1119AT_CLEANUP
1120
1121
1122
1123## --------------------------------- ##
1124## String alias declared after use. ##
1125## --------------------------------- ##
1126
1127AT_SETUP([String alias declared after use])
1128
1129# Bison once incorrectly asserted that the symbol number for either a token or
1130# its alias was the highest symbol number so far at the point of the alias
1131# declaration. That was true unless the declaration appeared after their first
1132# uses and other tokens appeared in between.
1133
1134AT_DATA([input.y],
1135[[%%
1136start: 'a' "A" 'b';
1137%token 'a' "A";
1138]])
1139
1140AT_CHECK([bison -t -o input.c input.y])
1141
1142AT_CLEANUP
1143
1144
1145
1146## -------------------------------- ##
1147## Extra lookahead sets in report. ##
1148## -------------------------------- ##
1149
1150AT_SETUP([[Extra lookahead sets in report]])
1151
1152# Within a single state, Bison used to print a reduction's lookahead set next
1153# to all items of the associated rule. Instead, it should only print it next
1154# to the item that is of the associated rule and whose dot is at the end of the
1155# RHS. Printing it next to items whose dot is not at the end of the RHS is
1156# sometimes redundant and, as in this test case, is sometimes incorrect.
1157
1158AT_DATA([[input.y]],
1159[[%%
1160start: a | 'a' a 'a' ;
1161a: 'a' ;
1162]])
1163
1164AT_CHECK([[bison --report=all input.y]])
1165AT_CHECK([[sed -n '/^state 1$/,/^state 2$/p' input.output]], [[0]],
1166[[state 1
1167
1168 2 start: 'a' . a 'a'
1169 3 a: . 'a'
1170 3 | 'a' . [$end]
1171
1172 'a' shift, and go to state 4
1173
1174 $default reduce using rule 3 (a)
1175
1176 a go to state 5
1177
1178
1179state 2
1180]])
1181
1182AT_CLEANUP