OLD | NEW |
(Empty) | |
| 1 /* Scan Bison Skeletons. -*- C -*- |
| 2 |
| 3 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software |
| 4 Foundation, Inc. |
| 5 |
| 6 This file is part of Bison, the GNU Compiler Compiler. |
| 7 |
| 8 This program is free software: you can redistribute it and/or modify |
| 9 it under the terms of the GNU General Public License as published by |
| 10 the Free Software Foundation, either version 3 of the License, or |
| 11 (at your option) any later version. |
| 12 |
| 13 This program is distributed in the hope that it will be useful, |
| 14 but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 GNU General Public License for more details. |
| 17 |
| 18 You should have received a copy of the GNU General Public License |
| 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 20 |
| 21 %option nodefault noyywrap nounput never-interactive debug |
| 22 %option prefix="skel_" outfile="lex.yy.c" |
| 23 |
| 24 %{ |
| 25 /* Work around a bug in flex 2.5.31. See Debian bug 333231 |
| 26 <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>. */ |
| 27 #undef skel_wrap |
| 28 #define skel_wrap() 1 |
| 29 |
| 30 #define FLEX_PREFIX(Id) skel_ ## Id |
| 31 #include "flex-scanner.h" |
| 32 |
| 33 #include <dirname.h> |
| 34 #include <error.h> |
| 35 #include <quotearg.h> |
| 36 |
| 37 #include "complain.h" |
| 38 #include "getargs.h" |
| 39 #include "files.h" |
| 40 #include "scan-skel.h" |
| 41 |
| 42 #define YY_DECL static int skel_lex (void) |
| 43 YY_DECL; |
| 44 |
| 45 #define QPUTS(String) \ |
| 46 fputs (quotearg_style (c_quoting_style, String), yyout) |
| 47 |
| 48 static void at_directive_perform (int at_directive_argc, |
| 49 char *at_directive_argv[], |
| 50 char **outnamep, int *out_linenop); |
| 51 static void fail_for_at_directive_too_many_args (char const *at_directive_name); |
| 52 static void fail_for_at_directive_too_few_args (char const *at_directive_name); |
| 53 static void fail_for_invalid_at (char const *at); |
| 54 %} |
| 55 |
| 56 %x SC_AT_DIRECTIVE_ARGS |
| 57 %x SC_AT_DIRECTIVE_SKIP_WS |
| 58 |
| 59 %% |
| 60 |
| 61 %{ |
| 62 int out_lineno IF_LINT (= 0); |
| 63 char *outname = NULL; |
| 64 |
| 65 /* Currently, only the @warn, @complain, @fatal, @warn_at, @complain_at, and |
| 66 @fatal_at directives take multiple arguments, and the last three already |
| 67 can't take more than 7. at_directive_argv[0] is the directive name. */ |
| 68 #define AT_DIRECTIVE_ARGC_MAX 8 |
| 69 int at_directive_argc = 0; |
| 70 char *at_directive_argv[AT_DIRECTIVE_ARGC_MAX]; |
| 71 %} |
| 72 |
| 73 "@@" fputc ('@', yyout); |
| 74 "@{" fputc ('[', yyout); |
| 75 "@}" fputc (']', yyout); |
| 76 "@`" /* Emtpy. Used by b4_cat in ../data/bison.m4. */ |
| 77 @\n /* Likewise. */ |
| 78 |
| 79 "@oline@" fprintf (yyout, "%d", out_lineno + 1); |
| 80 "@ofile@" QPUTS (outname); |
| 81 "@dir_prefix@" QPUTS (dir_prefix); |
| 82 |
| 83 @[a-z_]+"(" { |
| 84 yytext[yyleng-1] = '\0'; |
| 85 obstack_grow (&obstack_for_string, yytext, yyleng); |
| 86 at_directive_argv[at_directive_argc++] = |
| 87 obstack_finish (&obstack_for_string); |
| 88 BEGIN SC_AT_DIRECTIVE_ARGS; |
| 89 } |
| 90 |
| 91 /* This pattern must not match more than the previous @ patterns. */ |
| 92 @[^@{}`(\n]* fail_for_invalid_at (yytext); |
| 93 \n out_lineno++; ECHO; |
| 94 [^@\n]+ ECHO; |
| 95 |
| 96 <INITIAL><<EOF>> { |
| 97 if (outname) |
| 98 { |
| 99 free (outname); |
| 100 xfclose (yyout); |
| 101 } |
| 102 return EOF; |
| 103 } |
| 104 |
| 105 <SC_AT_DIRECTIVE_ARGS>{ |
| 106 [^@]+ { STRING_GROW; } |
| 107 |
| 108 "@@" { obstack_1grow (&obstack_for_string, '@'); } |
| 109 "@{" { obstack_1grow (&obstack_for_string, '['); } |
| 110 "@}" { obstack_1grow (&obstack_for_string, ']'); } |
| 111 "@`" /* Emtpy. Useful for starting an argument |
| 112 that begins with whitespace. */ |
| 113 @\n /* Empty. */ |
| 114 |
| 115 @[,)] { |
| 116 if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX) |
| 117 fail_for_at_directive_too_many_args (at_directive_argv[0]); |
| 118 |
| 119 obstack_1grow (&obstack_for_string, '\0'); |
| 120 at_directive_argv[at_directive_argc++] = |
| 121 obstack_finish (&obstack_for_string); |
| 122 |
| 123 /* Like M4, skip whitespace after a comma. */ |
| 124 if (yytext[1] == ',') |
| 125 BEGIN SC_AT_DIRECTIVE_SKIP_WS; |
| 126 else |
| 127 { |
| 128 at_directive_perform (at_directive_argc, at_directive_argv, |
| 129 &outname, &out_lineno); |
| 130 obstack_free (&obstack_for_string, at_directive_argv[0]); |
| 131 at_directive_argc = 0; |
| 132 BEGIN INITIAL; |
| 133 } |
| 134 } |
| 135 |
| 136 @.? { fail_for_invalid_at (yytext); } |
| 137 } |
| 138 |
| 139 <SC_AT_DIRECTIVE_SKIP_WS>{ |
| 140 [ \t\r\n] |
| 141 . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; } |
| 142 } |
| 143 |
| 144 <SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>{ |
| 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 |
| 179 void 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 } |
OLD | NEW |