]> git.saurik.com Git - bison.git/blob - tests/regression.at
* data/glr.c (yyreportSyntaxError): Fix off-by-one error in
[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 %}
35
36 %error-verbose
37
38 %%
39
40 program: 'x';
41 ]])
42
43 AT_CHECK([bison -o input.c input.y])
44 AT_COMPILE([input.o], [-c input.c])
45
46 AT_CLEANUP
47
48
49
50 ## ------------------------- ##
51 ## Early token definitions. ##
52 ## ------------------------- ##
53
54
55 AT_SETUP([Early token definitions])
56
57 # Found in GCJ: they expect the tokens to be defined before the user
58 # prologue, so that they can use the token definitions in it.
59
60 AT_DATA_GRAMMAR([input.y],
61 [[%{
62 void yyerror (const char *s);
63 int yylex (void);
64 %}
65
66 %union
67 {
68 int val;
69 };
70 %{
71 #ifndef MY_TOKEN
72 # error "MY_TOKEN not defined."
73 #endif
74 %}
75 %token MY_TOKEN
76 %%
77 exp: MY_TOKEN;
78 %%
79 ]])
80
81 AT_CHECK([bison -o input.c input.y])
82 AT_COMPILE([input.o], [-c input.c])
83
84 AT_CLEANUP
85
86
87
88 ## ---------------- ##
89 ## Braces parsing. ##
90 ## ---------------- ##
91
92
93 AT_SETUP([Braces parsing])
94
95 AT_DATA([input.y],
96 [[/* Bison used to swallow the character after `}'. */
97
98 %%
99 exp: { tests = {{{{{{{{{{}}}}}}}}}}; };
100 %%
101 ]])
102
103 AT_CHECK([bison -v -o input.c input.y])
104
105 AT_CHECK([grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c], 0, [ignore])
106
107 AT_CLEANUP
108
109
110 ## ------------------ ##
111 ## Duplicate string. ##
112 ## ------------------ ##
113
114
115 AT_SETUP([Duplicate string])
116
117 AT_DATA([input.y],
118 [[/* `Bison -v' used to dump core when two tokens are defined with the same
119 string, as LE and GE below. */
120
121 %token NUM
122 %token LE "<="
123 %token GE "<="
124
125 %%
126 exp: '(' exp ')' | NUM ;
127 %%
128 ]])
129
130 AT_CHECK([bison -v -o input.c input.y], 0, [],
131 [[input.y:6.8-14: warning: symbol `"<="' used more than once as a literal string
132 ]])
133
134 AT_CLEANUP
135
136
137 ## ------------------- ##
138 ## Rule Line Numbers. ##
139 ## ------------------- ##
140
141 AT_SETUP([Rule Line Numbers])
142
143 AT_KEYWORDS([report])
144
145 AT_DATA([input.y],
146 [[%%
147 expr:
148 'a'
149
150 {
151
152 }
153
154 'b'
155
156 {
157
158 }
159
160 |
161
162
163 {
164
165
166 }
167
168 'c'
169
170 {
171
172 };
173 ]])
174
175 AT_CHECK([bison -o input.c -v input.y])
176
177 # Check the contents of the report.
178 AT_CHECK([cat input.output], [],
179 [[Grammar
180
181 0 $accept: expr $end
182
183 1 @1: /* empty */
184
185 2 expr: 'a' @1 'b'
186
187 3 @2: /* empty */
188
189 4 expr: @2 'c'
190
191
192 Terminals, with rules where they appear
193
194 $end (0) 0
195 'a' (97) 2
196 'b' (98) 2
197 'c' (99) 4
198 error (256)
199
200
201 Nonterminals, with rules where they appear
202
203 $accept (6)
204 on left: 0
205 expr (7)
206 on left: 2 4, on right: 0
207 @1 (8)
208 on left: 1, on right: 2
209 @2 (9)
210 on left: 3, on right: 4
211
212
213 state 0
214
215 0 $accept: . expr $end
216
217 'a' shift, and go to state 1
218
219 $default reduce using rule 3 (@2)
220
221 expr go to state 2
222 @2 go to state 3
223
224
225 state 1
226
227 2 expr: 'a' . @1 'b'
228
229 $default reduce using rule 1 (@1)
230
231 @1 go to state 4
232
233
234 state 2
235
236 0 $accept: expr . $end
237
238 $end shift, and go to state 5
239
240
241 state 3
242
243 4 expr: @2 . 'c'
244
245 'c' shift, and go to state 6
246
247
248 state 4
249
250 2 expr: 'a' @1 . 'b'
251
252 'b' shift, and go to state 7
253
254
255 state 5
256
257 0 $accept: expr $end .
258
259 $default accept
260
261
262 state 6
263
264 4 expr: @2 'c' .
265
266 $default reduce using rule 4 (expr)
267
268
269 state 7
270
271 2 expr: 'a' @1 'b' .
272
273 $default reduce using rule 2 (expr)
274 ]])
275
276 AT_CLEANUP
277
278
279
280 ## ---------------------- ##
281 ## Mixing %token styles. ##
282 ## ---------------------- ##
283
284
285 AT_SETUP([Mixing %token styles])
286
287 # Taken from the documentation.
288 AT_DATA([input.y],
289 [[%token <operator> OR "||"
290 %token <operator> LE 134 "<="
291 %left OR "<="
292 %%
293 exp: ;
294 %%
295 ]])
296
297 AT_CHECK([bison -v -o input.c input.y])
298
299 AT_CLEANUP
300
301
302
303 ## ---------------- ##
304 ## Invalid inputs. ##
305 ## ---------------- ##
306
307
308 AT_SETUP([Invalid inputs])
309
310 AT_DATA([input.y],
311 [[%%
312 ?
313 default: 'a' }
314 %&
315 %a-does-not-exist
316 %-
317 %{
318 ]])
319
320 AT_CHECK([bison input.y], [1], [],
321 [[input.y:2.1: invalid character: `?'
322 input.y:3.14: invalid character: `}'
323 input.y:4.1: invalid character: `%'
324 input.y:4.2: invalid character: `&'
325 input.y:5.1-17: invalid directive: `%a-does-not-exist'
326 input.y:6.1: invalid character: `%'
327 input.y:6.2: invalid character: `-'
328 input.y:7.1-8.0: missing `%}' at end of file
329 ]])
330
331 AT_CLEANUP
332
333
334 AT_SETUP([Invalid inputs with {}])
335
336 AT_DATA([input.y],
337 [[
338 %destructor
339 %initial-action
340 %lex-param
341 %parse-param
342 %printer
343 %union
344 ]])
345
346 AT_CHECK([bison input.y], [1], [],
347 [[input.y:3.1: missing `{' in "%destructor {...}"
348 input.y:4.1: missing `{' in "%initial-action {...}"
349 input.y:4.1: syntax error, unexpected %initial-action {...}, expecting string or identifier
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"])