1 /* Scan Bison Skeletons. -*- C -*- 2 3 Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc. 4 5 This file is part of Bison, the GNU Compiler Compiler. 6 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 %option nodefault noyywrap noinput nounput never-interactive debug 21 %option prefix="skel_" outfile="lex.yy.c" 22 23 %{ 24 /* Work around a bug in flex 2.5.31. See Debian bug 333231 25 <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>. */ 26 #undef skel_wrap 27 #define skel_wrap() 1 28 29 #define FLEX_PREFIX(Id) skel_ ## Id 30 #include "flex-scanner.h" 31 32 #include <dirname.h> 33 #include <error.h> 34 #include <quotearg.h> 35 36 #include "complain.h" 37 #include "getargs.h" 38 #include "files.h" 39 #include "scan-skel.h" 40 41 #define YY_DECL static int skel_lex (void) 42 YY_DECL; 43 44 #define QPUTS(String) \ 45 fputs (quotearg_style (c_quoting_style, String), yyout) 46 47 static void at_directive_perform (int at_directive_argc, 48 char *at_directive_argv[], 49 char **outnamep, int *out_linenop); 50 static void fail_for_at_directive_too_many_args (char const *at_directive_name); 51 static void fail_for_at_directive_too_few_args (char const *at_directive_name); 52 static void fail_for_invalid_at (char const *at); 53 %} 54 55 %x SC_AT_DIRECTIVE_ARGS 56 %x SC_AT_DIRECTIVE_SKIP_WS 57 58 %% 59 60 %{ 61 int out_lineno PACIFY_CC (= 0); 62 char *outname = NULL; 63 64 /* Currently, only the @warn, @complain, @fatal, @warn_at, @complain_at, and 65 @fatal_at directives take multiple arguments, and the last three already 66 can't take more than 7. at_directive_argv[0] is the directive name. */ 67 #define AT_DIRECTIVE_ARGC_MAX 8 68 int at_directive_argc = 0; 69 char *at_directive_argv[AT_DIRECTIVE_ARGC_MAX]; 70 %} 71 72 "@@" fputc ('@', yyout); 73 "@{" fputc ('[', yyout); 74 "@}" fputc (']', yyout); 75 "@`" continue; /* Used by b4_cat in ../data/bison.m4. */ 76 @\n continue; 77 78 "@oline@" fprintf (yyout, "%d", out_lineno + 1); 79 "@ofile@" QPUTS (outname); 80 81 @[a-z_]+"(" { 82 yytext[yyleng-1] = '\0'; 83 obstack_grow (&obstack_for_string, yytext, yyleng); 84 at_directive_argv[at_directive_argc++] = 85 obstack_finish (&obstack_for_string); 86 BEGIN SC_AT_DIRECTIVE_ARGS; 87 } 88 89 /* This pattern must not match more than the previous @ patterns. */ 90 @[^@{}`(\n]* fail_for_invalid_at (yytext); 91 \n out_lineno++; ECHO; 92 [^@\n]+ ECHO; 93 94 <INITIAL><<EOF>> { 95 if (outname) 96 { 97 free (outname); 98 xfclose (yyout); 99 } 100 return EOF; 101 } 102 103 <SC_AT_DIRECTIVE_ARGS> 104 { 105 [^@]+ STRING_GROW; 106 107 "@@" obstack_1grow (&obstack_for_string, '@'); 108 "@{" obstack_1grow (&obstack_for_string, '['); 109 "@}" obstack_1grow (&obstack_for_string, ']'); 110 "@`" continue; /* For starting an argument that begins with whitespace. */ 111 @\n continue; 112 113 @[,)] { 114 if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX) 115 fail_for_at_directive_too_many_args (at_directive_argv[0]); 116 117 obstack_1grow (&obstack_for_string, '\0'); 118 at_directive_argv[at_directive_argc++] = 119 obstack_finish (&obstack_for_string); 120 121 /* Like M4, skip whitespace after a comma. */ 122 if (yytext[1] == ',') 123 BEGIN SC_AT_DIRECTIVE_SKIP_WS; 124 else 125 { 126 at_directive_perform (at_directive_argc, at_directive_argv, 127 &outname, &out_lineno); 128 obstack_free (&obstack_for_string, at_directive_argv[0]); 129 at_directive_argc = 0; 130 BEGIN INITIAL; 131 } 132 } 133 134 @.? fail_for_invalid_at (yytext); 135 } 136 137 <SC_AT_DIRECTIVE_SKIP_WS> 138 { 139 [ \t\r\n] continue; 140 . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; } 141 } 142 143 <SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS> 144 { 145 <<EOF>> { 146 fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]); 147 } 148 } 149 150 %% 151 152 /*------------------------. 153 | Scan a Bison skeleton. | 154 `------------------------*/ 155 156 void 157 scan_skel (FILE *in) 158 { 159 static bool initialized = false; 160 if (!initialized) 161 { 162 initialized = true; 163 obstack_init (&obstack_for_string); 164 } 165 skel_in = in; 166 skel__flex_debug = trace_flag & trace_skeleton; 167 skel_lex (); 168 } 169 170 void 171 skel_scanner_free (void) 172 { 173 obstack_free (&obstack_for_string, 0); 174 /* Reclaim Flex's buffers. */ 175 yylex_destroy (); 176 } 177 178 static void 179 at_directive_perform (int at_directive_argc, 180 char *at_directive_argv[], 181 char **outnamep, int *out_linenop) 182 { 183 if (0 == strcmp (at_directive_argv[0], "@basename")) 184 { 185 if (at_directive_argc > 2) 186 fail_for_at_directive_too_many_args (at_directive_argv[0]); 187 fputs (last_component (at_directive_argv[1]), yyout); 188 } 189 else if (0 == strcmp (at_directive_argv[0], "@warn") 190 || 0 == strcmp (at_directive_argv[0], "@complain") 191 || 0 == strcmp (at_directive_argv[0], "@fatal")) 192 { 193 void (*func)(char const *, ...); 194 switch (at_directive_argv[0][1]) 195 { 196 case 'w': func = warn; break; 197 case 'c': func = complain; break; 198 case 'f': func = fatal; break; 199 default: aver (false); break; 200 } 201 switch (at_directive_argc) 202 { 203 case 2: 204 func (_(at_directive_argv[1])); 205 break; 206 case 3: 207 func (_(at_directive_argv[1]), at_directive_argv[2]); 208 break; 209 case 4: 210 func (_(at_directive_argv[1]), at_directive_argv[2], 211 at_directive_argv[3]); 212 break; 213 case 5: 214 func (_(at_directive_argv[1]), at_directive_argv[2], 215 at_directive_argv[3], at_directive_argv[4]); 216 break; 217 case 6: 218 func (_(at_directive_argv[1]), at_directive_argv[2], 219 at_directive_argv[3], at_directive_argv[4], 220 at_directive_argv[5]); 221 break; 222 default: 223 fail_for_at_directive_too_many_args (at_directive_argv[0]); 224 break; 225 } 226 } 227 else if (0 == strcmp (at_directive_argv[0], "@warn_at") 228 || 0 == strcmp (at_directive_argv[0], "@complain_at") 229 || 0 == strcmp (at_directive_argv[0], "@fatal_at")) 230 { 231 void (*func)(location, char const *, ...); 232 location loc; 233 if (at_directive_argc < 4) 234 fail_for_at_directive_too_few_args (at_directive_argv[0]); 235 switch (at_directive_argv[0][1]) 236 { 237 case 'w': func = warn_at; break; 238 case 'c': func = complain_at; break; 239 case 'f': func = fatal_at; break; 240 default: aver (false); break; 241 } 242 boundary_set_from_string (&loc.start, at_directive_argv[1]); 243 boundary_set_from_string (&loc.end, at_directive_argv[2]); 244 switch (at_directive_argc) 245 { 246 case 4: 247 func (loc, _(at_directive_argv[3])); 248 break; 249 case 5: 250 func (loc, _(at_directive_argv[3]), at_directive_argv[4]); 251 break; 252 case 6: 253 func (loc, _(at_directive_argv[3]), at_directive_argv[4], 254 at_directive_argv[5]); 255 break; 256 case 7: 257 func (loc, _(at_directive_argv[3]), at_directive_argv[4], 258 at_directive_argv[5], at_directive_argv[6]); 259 break; 260 case 8: 261 func (loc, _(at_directive_argv[3]), at_directive_argv[4], 262 at_directive_argv[5], at_directive_argv[6], 263 at_directive_argv[7]); 264 break; 265 default: 266 fail_for_at_directive_too_many_args (at_directive_argv[0]); 267 break; 268 } 269 } 270 else if (0 == strcmp (at_directive_argv[0], "@output")) 271 { 272 if (at_directive_argc > 2) 273 fail_for_at_directive_too_many_args (at_directive_argv[0]); 274 if (*outnamep) 275 { 276 free (*outnamep); 277 xfclose (yyout); 278 } 279 *outnamep = xstrdup (at_directive_argv[1]); 280 output_file_name_check (outnamep); 281 yyout = xfopen (*outnamep, "w"); 282 *out_linenop = 1; 283 } 284 else 285 fail_for_invalid_at (at_directive_argv[0]); 286 } 287 288 static void 289 fail_for_at_directive_too_few_args (char const *at_directive_name) 290 { 291 fatal (_("too few arguments for %s directive in skeleton"), 292 at_directive_name); 293 } 294 295 static void 296 fail_for_at_directive_too_many_args (char const *at_directive_name) 297 { 298 fatal (_("too many arguments for %s directive in skeleton"), 299 at_directive_name); 300 } 301 302 static void 303 fail_for_invalid_at (char const *at) 304 { 305 fatal ("invalid @ in skeleton: %s", at); 306 } 307