]> git.saurik.com Git - bison.git/blame - src/scan-skel.l
maint: more macros
[bison.git] / src / scan-skel.l
CommitLineData
be2a1a68 1/* Scan Bison Skeletons. -*- C -*-
353d3eb6 2
33a1fa4e 3 Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc.
1239777d
AD
4
5 This file is part of Bison, the GNU Compiler Compiler.
6
f16b0819
PE
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.
1239777d 11
f16b0819
PE
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.
9b3add5b 16
1239777d 17 You should have received a copy of the GNU General Public License
f16b0819 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
9b3add5b 19
4521fcdf 20%option nodefault noyywrap noinput nounput never-interactive debug
aed7fd9b 21%option prefix="skel_" outfile="lex.yy.c"
9b3add5b 22
aed7fd9b 23%{
4f6e011e
PE
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
f9bfc42a
JD
29#define FLEX_PREFIX(Id) skel_ ## Id
30#include "flex-scanner.h"
353d3eb6 31
cb48f191 32#include <dirname.h>
353d3eb6
PE
33#include <error.h>
34#include <quotearg.h>
35
db5c43f7 36#include "complain.h"
536545f3 37#include "getargs.h"
be2a1a68 38#include "files.h"
04098407 39#include "scan-skel.h"
dc9701e8 40
08af01c2
JD
41#define YY_DECL static int skel_lex (void)
42YY_DECL;
06f01bc4 43
c5e3e510 44#define QPUTS(String) \
68cae94e 45 fputs (quotearg_style (c_quoting_style, String), yyout)
c5e3e510 46
3eb82471
JD
47static void at_directive_perform (int at_directive_argc,
48 char *at_directive_argv[],
49 char **outnamep, int *out_linenop);
50static void fail_for_at_directive_too_many_args (char const *at_directive_name);
51static void fail_for_at_directive_too_few_args (char const *at_directive_name);
08af01c2 52static void fail_for_invalid_at (char const *at);
aed7fd9b 53%}
08af01c2 54
3eb82471 55%x SC_AT_DIRECTIVE_ARGS
08af01c2
JD
56%x SC_AT_DIRECTIVE_SKIP_WS
57
9b3add5b 58%%
e9683cfd
PE
59
60%{
77bb73e7 61 int out_lineno PACIFY_CC (= 0);
e9683cfd 62 char *outname = NULL;
3eb82471
JD
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];
e9683cfd
PE
70%}
71
7dc4a694
JD
72"@@" fputc ('@', yyout);
73"@{" fputc ('[', yyout);
74"@}" fputc (']', yyout);
4d24ffb7
AD
75"@`" continue; /* Used by b4_cat in ../data/bison.m4. */
76@\n continue;
e9683cfd 77
3fc65ead 78"@oline@" fprintf (yyout, "%d", out_lineno + 1);
c5e3e510 79"@ofile@" QPUTS (outname);
bd9d212b 80
08af01c2
JD
81@[a-z_]+"(" {
82 yytext[yyleng-1] = '\0';
3eb82471
JD
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;
bd9d212b 87}
e9683cfd 88
3fc16193 89 /* This pattern must not match more than the previous @ patterns. */
4d24ffb7
AD
90@[^@{}`(\n]* fail_for_invalid_at (yytext);
91\n out_lineno++; ECHO;
92[^@\n]+ ECHO;
e9683cfd 93
dbfcf7a8 94<INITIAL><<EOF>> {
7ec5ab2e
PE
95 if (outname)
96 {
97 free (outname);
98 xfclose (yyout);
99 }
100 return EOF;
101}
08af01c2 102
4d24ffb7
AD
103<SC_AT_DIRECTIVE_ARGS>
104{
105 [^@]+ STRING_GROW;
08af01c2 106
4d24ffb7
AD
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;
08af01c2
JD
112
113 @[,)] {
114 if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX)
3eb82471 115 fail_for_at_directive_too_many_args (at_directive_argv[0]);
08af01c2
JD
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 {
3eb82471
JD
126 at_directive_perform (at_directive_argc, at_directive_argv,
127 &outname, &out_lineno);
08af01c2
JD
128 obstack_free (&obstack_for_string, at_directive_argv[0]);
129 at_directive_argc = 0;
08af01c2
JD
130 BEGIN INITIAL;
131 }
132 }
133
4d24ffb7 134 @.? fail_for_invalid_at (yytext);
08af01c2
JD
135}
136
4d24ffb7
AD
137<SC_AT_DIRECTIVE_SKIP_WS>
138{
139 [ \t\r\n] continue;
140 . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; }
08af01c2
JD
141}
142
4d24ffb7
AD
143<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>
144{
08af01c2 145 <<EOF>> {
3eb82471 146 fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]);
08af01c2
JD
147 }
148}
149
9b3add5b 150%%
536545f3 151
2cdb2a7b
PE
152/*------------------------.
153| Scan a Bison skeleton. |
154`------------------------*/
536545f3 155
536545f3 156void
2cdb2a7b 157scan_skel (FILE *in)
536545f3 158{
08af01c2
JD
159 static bool initialized = false;
160 if (!initialized)
161 {
162 initialized = true;
163 obstack_init (&obstack_for_string);
164 }
2cdb2a7b 165 skel_in = in;
c5e3e510 166 skel__flex_debug = trace_flag & trace_skeleton;
536545f3 167 skel_lex ();
536545f3 168}
bd9d212b 169
3fc65ead
JD
170void
171skel_scanner_free (void)
172{
173 obstack_free (&obstack_for_string, 0);
3eb82471
JD
174 /* Reclaim Flex's buffers. */
175 yylex_destroy ();
3fc65ead
JD
176}
177
47fa5747
JD
178static void
179at_directive_perform (int at_directive_argc,
180 char *at_directive_argv[],
181 char **outnamep, int *out_linenop)
3fc65ead 182{
3eb82471 183 if (0 == strcmp (at_directive_argv[0], "@basename"))
3fc65ead 184 {
3eb82471
JD
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);
3fc65ead 188 }
3eb82471
JD
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"))
3fc65ead
JD
192 {
193 void (*func)(char const *, ...);
3eb82471 194 switch (at_directive_argv[0][1])
3fc65ead
JD
195 {
196 case 'w': func = warn; break;
197 case 'c': func = complain; break;
198 case 'f': func = fatal; break;
3eb82471 199 default: aver (false); break;
3fc65ead
JD
200 }
201 switch (at_directive_argc)
202 {
87b0a375 203 case 2:
3eb82471 204 func (_(at_directive_argv[1]));
3fc65ead 205 break;
87b0a375 206 case 3:
3eb82471 207 func (_(at_directive_argv[1]), at_directive_argv[2]);
3fc65ead 208 break;
87b0a375 209 case 4:
3eb82471
JD
210 func (_(at_directive_argv[1]), at_directive_argv[2],
211 at_directive_argv[3]);
3fc65ead 212 break;
87b0a375 213 case 5:
3eb82471
JD
214 func (_(at_directive_argv[1]), at_directive_argv[2],
215 at_directive_argv[3], at_directive_argv[4]);
3fc65ead 216 break;
87b0a375 217 case 6:
3eb82471
JD
218 func (_(at_directive_argv[1]), at_directive_argv[2],
219 at_directive_argv[3], at_directive_argv[4],
220 at_directive_argv[5]);
3fc65ead
JD
221 break;
222 default:
3eb82471 223 fail_for_at_directive_too_many_args (at_directive_argv[0]);
3fc65ead
JD
224 break;
225 }
226 }
3eb82471
JD
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"))
3fc65ead
JD
230 {
231 void (*func)(location, char const *, ...);
232 location loc;
3eb82471
JD
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])
3fc65ead
JD
236 {
237 case 'w': func = warn_at; break;
238 case 'c': func = complain_at; break;
239 case 'f': func = fatal_at; break;
3eb82471 240 default: aver (false); break;
3fc65ead 241 }
3eb82471
JD
242 boundary_set_from_string (&loc.start, at_directive_argv[1]);
243 boundary_set_from_string (&loc.end, at_directive_argv[2]);
3fc65ead
JD
244 switch (at_directive_argc)
245 {
87b0a375 246 case 4:
3eb82471 247 func (loc, _(at_directive_argv[3]));
3fc65ead 248 break;
87b0a375 249 case 5:
3eb82471 250 func (loc, _(at_directive_argv[3]), at_directive_argv[4]);
3fc65ead 251 break;
87b0a375 252 case 6:
3eb82471
JD
253 func (loc, _(at_directive_argv[3]), at_directive_argv[4],
254 at_directive_argv[5]);
3fc65ead 255 break;
87b0a375 256 case 7:
3eb82471
JD
257 func (loc, _(at_directive_argv[3]), at_directive_argv[4],
258 at_directive_argv[5], at_directive_argv[6]);
3fc65ead 259 break;
87b0a375 260 case 8:
3eb82471
JD
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]);
3fc65ead
JD
264 break;
265 default:
3eb82471 266 fail_for_at_directive_too_many_args (at_directive_argv[0]);
3fc65ead
JD
267 break;
268 }
269 }
3eb82471 270 else if (0 == strcmp (at_directive_argv[0], "@output"))
3fc65ead 271 {
3eb82471
JD
272 if (at_directive_argc > 2)
273 fail_for_at_directive_too_many_args (at_directive_argv[0]);
3fc65ead
JD
274 if (*outnamep)
275 {
276 free (*outnamep);
277 xfclose (yyout);
278 }
3eb82471 279 *outnamep = xstrdup (at_directive_argv[1]);
47fa5747 280 output_file_name_check (outnamep);
3fc65ead
JD
281 yyout = xfopen (*outnamep, "w");
282 *out_linenop = 1;
283 }
284 else
3eb82471 285 fail_for_invalid_at (at_directive_argv[0]);
3fc65ead
JD
286}
287
288static void
3eb82471 289fail_for_at_directive_too_few_args (char const *at_directive_name)
3fc65ead
JD
290{
291 fatal (_("too few arguments for %s directive in skeleton"),
292 at_directive_name);
293}
294
08af01c2 295static void
3eb82471 296fail_for_at_directive_too_many_args (char const *at_directive_name)
bd9d212b 297{
08af01c2
JD
298 fatal (_("too many arguments for %s directive in skeleton"),
299 at_directive_name);
300}
301
302static void
303fail_for_invalid_at (char const *at)
304{
305 fatal ("invalid @ in skeleton: %s", at);
306}