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