]> git.saurik.com Git - bison.git/blame - src/scan-skel.l
* src/getargs.c (version): Update copyright year.
[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
7dc4a694
JD
73"@@" fputc ('@', yyout);
74"@{" fputc ('[', yyout);
75"@}" fputc (']', yyout);
76"@`" /* Emtpy. Used by b4_cat in ../data/bison.m4. */
77@\n /* Likewise. */
e9683cfd 78
3fc65ead 79"@oline@" fprintf (yyout, "%d", out_lineno + 1);
c5e3e510 80"@ofile@" QPUTS (outname);
2b81e969 81"@dir_prefix@" QPUTS (dir_prefix);
bd9d212b 82
08af01c2
JD
83@[a-z_]+"(" {
84 yytext[yyleng-1] = '\0';
3eb82471
JD
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;
bd9d212b 89}
e9683cfd 90
3fc16193 91 /* This pattern must not match more than the previous @ patterns. */
7dc4a694 92@[^@{}`(\n]* fail_for_invalid_at (yytext);
3fc65ead 93\n out_lineno++; ECHO;
68e93ad5 94[^@\n]+ ECHO;
e9683cfd 95
08af01c2 96<INITIAL><<EOF>> {
7ec5ab2e
PE
97 if (outname)
98 {
99 free (outname);
100 xfclose (yyout);
101 }
102 return EOF;
103}
08af01c2 104
3eb82471 105<SC_AT_DIRECTIVE_ARGS>{
5f340b48 106 [^@]+ { STRING_GROW; }
08af01c2 107
5f340b48
JD
108 "@@" { obstack_1grow (&obstack_for_string, '@'); }
109 "@{" { obstack_1grow (&obstack_for_string, '['); }
110 "@}" { obstack_1grow (&obstack_for_string, ']'); }
08af01c2
JD
111 "@`" /* Emtpy. Useful for starting an argument
112 that begins with whitespace. */
7dc4a694 113 @\n /* Empty. */
08af01c2
JD
114
115 @[,)] {
116 if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX)
3eb82471 117 fail_for_at_directive_too_many_args (at_directive_argv[0]);
08af01c2
JD
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 {
3eb82471
JD
128 at_directive_perform (at_directive_argc, at_directive_argv,
129 &outname, &out_lineno);
08af01c2
JD
130 obstack_free (&obstack_for_string, at_directive_argv[0]);
131 at_directive_argc = 0;
08af01c2
JD
132 BEGIN INITIAL;
133 }
134 }
135
136 @.? { fail_for_invalid_at (yytext); }
137}
138
139<SC_AT_DIRECTIVE_SKIP_WS>{
3fc65ead 140 [ \t\r\n]
3eb82471 141 . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; }
08af01c2
JD
142}
143
3eb82471 144<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>{
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
178static
3eb82471
JD
179void at_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]);
3fc65ead
JD
280 output_file_name_check (*outnamep);
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}