]> git.saurik.com Git - bison.git/blame - src/scan-skel.l
support $<tag>$ in printers and destructors
[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);
33a1fa4e 75"@`" /* Empty. Used by b4_cat in ../data/bison.m4. */
7dc4a694 76@\n /* Likewise. */
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. */
7dc4a694 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, ']'); }
47fa5747 109 "@`" /* Empty. Useful for starting an argument
08af01c2 110 that begins with whitespace. */
7dc4a694 111 @\n /* Empty. */
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
134 @.? { fail_for_invalid_at (yytext); }
135}
136
137<SC_AT_DIRECTIVE_SKIP_WS>{
3fc65ead 138 [ \t\r\n]
3eb82471 139 . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; }
08af01c2
JD
140}
141
3eb82471 142<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>{
08af01c2 143 <<EOF>> {
3eb82471 144 fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]);
08af01c2
JD
145 }
146}
147
9b3add5b 148%%
536545f3 149
2cdb2a7b
PE
150/*------------------------.
151| Scan a Bison skeleton. |
152`------------------------*/
536545f3 153
536545f3 154void
2cdb2a7b 155scan_skel (FILE *in)
536545f3 156{
08af01c2
JD
157 static bool initialized = false;
158 if (!initialized)
159 {
160 initialized = true;
161 obstack_init (&obstack_for_string);
162 }
2cdb2a7b 163 skel_in = in;
c5e3e510 164 skel__flex_debug = trace_flag & trace_skeleton;
536545f3 165 skel_lex ();
536545f3 166}
bd9d212b 167
3fc65ead
JD
168void
169skel_scanner_free (void)
170{
171 obstack_free (&obstack_for_string, 0);
3eb82471
JD
172 /* Reclaim Flex's buffers. */
173 yylex_destroy ();
3fc65ead
JD
174}
175
47fa5747
JD
176static void
177at_directive_perform (int at_directive_argc,
178 char *at_directive_argv[],
179 char **outnamep, int *out_linenop)
3fc65ead 180{
3eb82471 181 if (0 == strcmp (at_directive_argv[0], "@basename"))
3fc65ead 182 {
3eb82471
JD
183 if (at_directive_argc > 2)
184 fail_for_at_directive_too_many_args (at_directive_argv[0]);
185 fputs (last_component (at_directive_argv[1]), yyout);
3fc65ead 186 }
3eb82471
JD
187 else if (0 == strcmp (at_directive_argv[0], "@warn")
188 || 0 == strcmp (at_directive_argv[0], "@complain")
189 || 0 == strcmp (at_directive_argv[0], "@fatal"))
3fc65ead
JD
190 {
191 void (*func)(char const *, ...);
3eb82471 192 switch (at_directive_argv[0][1])
3fc65ead
JD
193 {
194 case 'w': func = warn; break;
195 case 'c': func = complain; break;
196 case 'f': func = fatal; break;
3eb82471 197 default: aver (false); break;
3fc65ead
JD
198 }
199 switch (at_directive_argc)
200 {
87b0a375 201 case 2:
3eb82471 202 func (_(at_directive_argv[1]));
3fc65ead 203 break;
87b0a375 204 case 3:
3eb82471 205 func (_(at_directive_argv[1]), at_directive_argv[2]);
3fc65ead 206 break;
87b0a375 207 case 4:
3eb82471
JD
208 func (_(at_directive_argv[1]), at_directive_argv[2],
209 at_directive_argv[3]);
3fc65ead 210 break;
87b0a375 211 case 5:
3eb82471
JD
212 func (_(at_directive_argv[1]), at_directive_argv[2],
213 at_directive_argv[3], at_directive_argv[4]);
3fc65ead 214 break;
87b0a375 215 case 6:
3eb82471
JD
216 func (_(at_directive_argv[1]), at_directive_argv[2],
217 at_directive_argv[3], at_directive_argv[4],
218 at_directive_argv[5]);
3fc65ead
JD
219 break;
220 default:
3eb82471 221 fail_for_at_directive_too_many_args (at_directive_argv[0]);
3fc65ead
JD
222 break;
223 }
224 }
3eb82471
JD
225 else if (0 == strcmp (at_directive_argv[0], "@warn_at")
226 || 0 == strcmp (at_directive_argv[0], "@complain_at")
227 || 0 == strcmp (at_directive_argv[0], "@fatal_at"))
3fc65ead
JD
228 {
229 void (*func)(location, char const *, ...);
230 location loc;
3eb82471
JD
231 if (at_directive_argc < 4)
232 fail_for_at_directive_too_few_args (at_directive_argv[0]);
233 switch (at_directive_argv[0][1])
3fc65ead
JD
234 {
235 case 'w': func = warn_at; break;
236 case 'c': func = complain_at; break;
237 case 'f': func = fatal_at; break;
3eb82471 238 default: aver (false); break;
3fc65ead 239 }
3eb82471
JD
240 boundary_set_from_string (&loc.start, at_directive_argv[1]);
241 boundary_set_from_string (&loc.end, at_directive_argv[2]);
3fc65ead
JD
242 switch (at_directive_argc)
243 {
87b0a375 244 case 4:
3eb82471 245 func (loc, _(at_directive_argv[3]));
3fc65ead 246 break;
87b0a375 247 case 5:
3eb82471 248 func (loc, _(at_directive_argv[3]), at_directive_argv[4]);
3fc65ead 249 break;
87b0a375 250 case 6:
3eb82471
JD
251 func (loc, _(at_directive_argv[3]), at_directive_argv[4],
252 at_directive_argv[5]);
3fc65ead 253 break;
87b0a375 254 case 7:
3eb82471
JD
255 func (loc, _(at_directive_argv[3]), at_directive_argv[4],
256 at_directive_argv[5], at_directive_argv[6]);
3fc65ead 257 break;
87b0a375 258 case 8:
3eb82471
JD
259 func (loc, _(at_directive_argv[3]), at_directive_argv[4],
260 at_directive_argv[5], at_directive_argv[6],
261 at_directive_argv[7]);
3fc65ead
JD
262 break;
263 default:
3eb82471 264 fail_for_at_directive_too_many_args (at_directive_argv[0]);
3fc65ead
JD
265 break;
266 }
267 }
3eb82471 268 else if (0 == strcmp (at_directive_argv[0], "@output"))
3fc65ead 269 {
3eb82471
JD
270 if (at_directive_argc > 2)
271 fail_for_at_directive_too_many_args (at_directive_argv[0]);
3fc65ead
JD
272 if (*outnamep)
273 {
274 free (*outnamep);
275 xfclose (yyout);
276 }
3eb82471 277 *outnamep = xstrdup (at_directive_argv[1]);
47fa5747 278 output_file_name_check (outnamep);
3fc65ead
JD
279 yyout = xfopen (*outnamep, "w");
280 *out_linenop = 1;
281 }
282 else
3eb82471 283 fail_for_invalid_at (at_directive_argv[0]);
3fc65ead
JD
284}
285
286static void
3eb82471 287fail_for_at_directive_too_few_args (char const *at_directive_name)
3fc65ead
JD
288{
289 fatal (_("too few arguments for %s directive in skeleton"),
290 at_directive_name);
291}
292
08af01c2 293static void
3eb82471 294fail_for_at_directive_too_many_args (char const *at_directive_name)
bd9d212b 295{
08af01c2
JD
296 fatal (_("too many arguments for %s directive in skeleton"),
297 at_directive_name);
298}
299
300static void
301fail_for_invalid_at (char const *at)
302{
303 fatal ("invalid @ in skeleton: %s", at);
304}