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