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