Home | History | Annotate | Download | only in tests
      1 # Checking the Bison scanner.                    -*- Autotest -*-
      2 # Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
      3 
      4 # This program is free software; you can redistribute it and/or modify
      5 # it under the terms of the GNU General Public License as published by
      6 # the Free Software Foundation; either version 2, or (at your option)
      7 # any later version.
      8 
      9 # This program is distributed in the hope that it will be useful,
     10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 # GNU General Public License for more details.
     13 
     14 # You should have received a copy of the GNU General Public License
     15 # along with this program; if not, write to the Free Software
     16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     17 # 02110-1301, USA.
     18 
     19 AT_BANNER([[Input Processing.]])
     20 
     21 # Mostly test that we are robust to mistakes.
     22 
     23 
     24 ## ------------ ##
     25 ## Invalid $n.  ##
     26 ## ------------ ##
     27 
     28 AT_SETUP([Invalid dollar-n])
     29 
     30 AT_DATA([input.y],
     31 [[%%
     32 exp: { $$ = $1 ; };
     33 ]])
     34 
     35 AT_CHECK([bison input.y], [1], [],
     36 [[input.y:2.13-14: integer out of range: `$1'
     37 ]])
     38 
     39 AT_CLEANUP
     40 
     41 
     42 ## ------------ ##
     43 ## Invalid @n.  ##
     44 ## ------------ ##
     45 
     46 AT_SETUP([Invalid @n])
     47 
     48 AT_DATA([input.y],
     49 [[%%
     50 exp: { @$ = @1 ; };
     51 ]])
     52 
     53 AT_CHECK([bison input.y], [1], [],
     54 [[input.y:2.13-14: integer out of range: `@1'
     55 ]])
     56 
     57 AT_CLEANUP
     58 
     59 
     60 ## -------------- ##
     61 ## Type Clashes.  ##
     62 ## -------------- ##
     63 
     64 AT_SETUP([Type Clashes])
     65 
     66 AT_DATA([input.y],
     67 [[%token foo
     68 %type <bar> exp
     69 %%
     70 exp: foo {} foo
     71    | foo
     72    | /* Empty. */
     73    ;
     74 ]])
     75 
     76 AT_CHECK([bison input.y], [], [],
     77 [[input.y:4.6-15: warning: type clash on default action: <bar> != <>
     78 input.y:5.6-8: warning: type clash on default action: <bar> != <>
     79 input.y:6.5: warning: empty rule for typed nonterminal, and no action
     80 ]])
     81 
     82 AT_CLEANUP
     83 
     84 
     85 ## --------------- ##
     86 ## Unused values.  ##
     87 ## --------------- ##
     88 
     89 AT_SETUP([Unused values])
     90 
     91 AT_DATA([input.y],
     92 [[%token <integer> INT
     93 %type <integer> a b c d e f g h i j k l
     94 %destructor { destroy ($$); } INT a b c d e f g h i j k l
     95 %%
     96 start:
     97   'a' a { $2 } | 'b' b { $2 } | 'c' c { $2 } | 'd' d { $2 } | 'e' e { $2 }
     98 | 'f' f { $2 } | 'g' g { $2 } | 'h' h { $2 } | 'i' i { $2 } | 'j' j { $2 }
     99 | 'k' k { $2 } | 'l' l { $2 }
    100 ;
    101 
    102 a: INT | INT { } INT { } INT { };
    103 b: INT | /* empty */;
    104 c: INT | INT { $1 } INT { } INT { };
    105 d: INT | INT { } INT { $1 } INT { };
    106 e: INT | INT { } INT {  } INT { $1 };
    107 f: INT | INT { } INT {  } INT { $$ = $1 + $3 + $5; };
    108 g: INT | INT { $$ } INT { $$ } INT { };
    109 h: INT | INT { $$ } INT { $$ = $2 } INT { };
    110 i: INT | INT INT { } { $$ = $1 + $2; };
    111 j: INT | INT INT { $<integer>$ = 1; } { $$ = $1 + $2; };
    112 k: INT | INT INT { $$; } { $$ = $3; } { };
    113 l: INT | INT { $$ = $1; } INT { $$ = $2 + $3; } INT { $$ = $4 + $5; };
    114 
    115 ]])
    116 
    117 AT_CHECK([bison input.y], [], [],
    118 [[input.y:11.10-32: warning: unset value: $$
    119 input.y:11.10-32: warning: unused value: $1
    120 input.y:11.10-32: warning: unused value: $3
    121 input.y:11.10-32: warning: unused value: $5
    122 input.y:12.9: warning: empty rule for typed nonterminal, and no action
    123 input.y:13.10-35: warning: unset value: $$
    124 input.y:13.10-35: warning: unused value: $3
    125 input.y:13.10-35: warning: unused value: $5
    126 input.y:14.10-35: warning: unset value: $$
    127 input.y:14.10-35: warning: unused value: $3
    128 input.y:14.10-35: warning: unused value: $5
    129 input.y:15.10-36: warning: unset value: $$
    130 input.y:15.10-36: warning: unused value: $3
    131 input.y:15.10-36: warning: unused value: $5
    132 input.y:17.10-38: warning: unset value: $$
    133 input.y:17.10-38: warning: unused value: $1
    134 input.y:17.10-38: warning: unused value: $2
    135 input.y:17.10-38: warning: unused value: $3
    136 input.y:17.10-38: warning: unused value: $4
    137 input.y:17.10-38: warning: unused value: $5
    138 input.y:18.10-43: warning: unset value: $$
    139 input.y:18.10-43: warning: unused value: $1
    140 input.y:18.10-43: warning: unused value: $3
    141 input.y:18.10-43: warning: unused value: $4
    142 input.y:18.10-43: warning: unused value: $5
    143 input.y:20.10-55: warning: unused value: $3
    144 input.y:21.10-41: warning: unset value: $$
    145 input.y:21.10-41: warning: unused value: $1
    146 input.y:21.10-41: warning: unused value: $2
    147 input.y:21.10-41: warning: unused value: $4
    148 ]])
    149 
    150 AT_CLEANUP
    151 
    152 
    153 ## ---------------------- ##
    154 ## Incompatible Aliases.  ##
    155 ## ---------------------- ##
    156 
    157 AT_SETUP([Incompatible Aliases])
    158 
    159 AT_DATA([input.y],
    160 [[%token foo "foo"
    161 
    162 %type <bar>       foo
    163 %printer {bar}    foo
    164 %destructor {bar} foo
    165 %left             foo
    166 
    167 %type <baz>       "foo"
    168 %printer {baz}    "foo"
    169 %destructor {baz} "foo"
    170 %left             "foo"
    171 
    172 %%
    173 exp: foo;
    174 ]])
    175 
    176 AT_CHECK([bison input.y], [1], [],
    177 [[input.y:8.7-11: %type redeclaration for foo
    178 input.y:3.7-11: first declaration
    179 input.y:10.13-17: %destructor redeclaration for foo
    180 input.y:5.13-17: first declaration
    181 input.y:9.10-14: %printer redeclaration for foo
    182 input.y:10.13-17: first declaration
    183 input.y:11.1-5: %left redeclaration for foo
    184 input.y:6.1-5: first declaration
    185 ]])
    186 
    187 AT_CLEANUP
    188 
    189 
    190 
    191 ## ----------------------- ##
    192 ## Torturing the Scanner.  ##
    193 ## ----------------------- ##
    194 
    195 # Be sure to compile and run, so that the C compiler checks what
    196 # we do.
    197 
    198 AT_SETUP([Torturing the Scanner])
    199 
    200 
    201 AT_DATA([input.y], [])
    202 AT_CHECK([bison input.y], [1], [],
    203 [[input.y:1.1: syntax error, unexpected end of file
    204 ]])
    205 
    206 
    207 AT_DATA([input.y], 
    208 [{}
    209 ])
    210 AT_CHECK([bison input.y], [1], [],
    211 [[input.y:1.1-2: syntax error, unexpected {...}
    212 ]])
    213 
    214 
    215 AT_DATA_GRAMMAR([input.y],
    216 [[%{
    217 /* This is seen in GCC: a %{ and %} in middle of a comment. */
    218 const char *foo = "So %{ and %} can be here too.";
    219 
    220 #if 0
    221 /* These examples test Bison while not stressing C compilers too much.
    222    Many C compilers mishandle backslash-newlines, so this part of the
    223    test is inside "#if 0".  The comment and string are written so that
    224    the "#endif" will be seen regardless of the C compiler bugs that we
    225    know about, namely:
    226 
    227      HP C (as of late 2002) mishandles *\[newline]\[newline]/ within a
    228      comment.
    229 
    230      The Apple Darwin compiler (as of late 2002) mishandles
    231      \\[newline]' within a character constant.
    232 
    233    */
    234 
    235 /\
    236 * A comment with backslash-newlines in it. %} *\
    237 \
    238 /
    239 /* { Close the above comment, if the C compiler mishandled it.  */
    240 
    241 char str[] = "\\
    242 " A string with backslash-newlines in it %{ %} \\
    243 \
    244 "";
    245 
    246 char apostrophe = '\'';
    247 #endif
    248 
    249 #include <stdio.h>
    250 %}
    251 /* %{ and %} can be here too. */
    252 
    253 %{
    254 /* Exercise pre-prologue dependency to %union.  */
    255 typedef int value;
    256 %}
    257 
    258 /* Exercise M4 quoting: '@:>@@:>@', 0.  */
    259 
    260 /* Also exercise %union. */
    261 %union
    262 {
    263   value ival; /* A comment to exercise an old bug. */
    264 };
    265 
    266 
    267 /* Exercise post-prologue dependency to %union.  */
    268 %{
    269 static YYSTYPE value_as_yystype (value val);
    270 
    271 /* Exercise quotes in declarations.  */
    272 char quote[] = "@:>@@:>@,";
    273 %}
    274 
    275 %{
    276 static void yyerror (const char *s);
    277 static int yylex (void);
    278 %}
    279 
    280 %type <ival> '@<:@'
    281 
    282 /* Exercise quotes in strings.  */
    283 %token FAKE "fake @<:@@:>@ \a\b\f\n\r\t\v\"\'\?\\\u005B\U0000005c ??!??'??(??)??-??/??<??=??> \x1\1"
    284 
    285 %%
    286 /* Exercise M4 quoting: '@:>@@:>@', @<:@, 1.  */
    287 exp: '@<:@' '\1' two '$' '@' '{' oline output.or.oline.opt
    288   {
    289     /* Exercise quotes in braces.  */
    290     char tmp[] = "@<:@%c@:>@,\n";
    291     printf (tmp, $1);
    292   }
    293 ;
    294 
    295 two: '\x000000000000000000000000000000000000000000000000000000000000000000002';
    296 oline: '@' 'o' 'l' 'i' 'n' 'e' '@' '_' '_' 'o' 'l' 'i' 'n' 'e' '_' '_';
    297 output.or.oline.opt: ;|oline;;|output;;;
    298 output: '#' 'o' 'u' 't' 'p' 'u' 't' ' ';
    299 %%
    300 /* Exercise M4 quoting: '@:>@@:>@', @<:@, 2.  */
    301 
    302 static YYSTYPE
    303 value_as_yystype (value val)
    304 {
    305   YYSTYPE res;
    306   res.ival = val;
    307   return res;
    308 }
    309 
    310 static int
    311 yylex (void)
    312 {
    313   static const char *input = "@<:@\1\2$@{@oline@__@&t@oline__\
    314 #output "; /* "
    315   */
    316   yylval = value_as_yystype (*input);
    317   return *input++;
    318 }
    319 
    320 static void
    321 yyerror (const char *msg)
    322 {
    323   fprintf (stderr, "%s\n", msg);
    324 }
    325 ]])
    326 
    327 # Pacify Emacs'font-lock-mode: "
    328 
    329 AT_DATA([main.c],
    330 [[typedef int value;
    331 #include "input.h"
    332 
    333 int yyparse (void);
    334 
    335 int
    336 main (void)
    337 {
    338   return yyparse ();
    339 }
    340 ]])
    341 
    342 AT_CHECK([bison -d -v -o input.c input.y])
    343 AT_COMPILE([input.o], [-c input.c])
    344 AT_COMPILE([main.o], [-c main.c])
    345 AT_COMPILE([input], [input.o main.o])
    346 AT_PARSER_CHECK([./input], 0,
    347 [[[@<:@],
    348 ]])
    349 
    350 AT_CLEANUP
    351 
    352 
    353 ## ---------------------- ##
    354 ## Typed symbol aliases.  ##
    355 ## ---------------------- ##
    356 
    357 AT_SETUP([Typed symbol aliases])
    358 
    359 # Bison 2.0 broke typed symbol aliases - ensure they work.
    360 
    361 AT_DATA_GRAMMAR([input.y],
    362 [[%union
    363 {
    364   int val;
    365 };
    366 %token <val> MY_TOKEN "MY TOKEN"
    367 %type <val> exp
    368 %%
    369 exp: "MY TOKEN";
    370 %%
    371 ]])
    372 
    373 AT_CHECK([bison -o input.c input.y])
    374 
    375 AT_CLEANUP
    376 
    377 
    378 ## --------- ##
    379 ## Require.  ##
    380 ## --------- ##
    381 
    382 m4_define([AT_CHECK_REQUIRE],
    383 [AT_SETUP([Require $1])
    384 AT_DATA_GRAMMAR([input.y],
    385 [[%require "$1";
    386 %%
    387 empty_file:;
    388 ]])
    389 AT_CHECK([bison -o input.c input.y], $2, [], ignore)
    390 AT_CLEANUP
    391 ])
    392 
    393 AT_CHECK_REQUIRE(1.0, 0)
    394 AT_CHECK_REQUIRE(AT_PACKAGE_VERSION, 0)
    395 ## FIXME: Some day augment this version number.
    396 AT_CHECK_REQUIRE(100.0, 63)
    397