]> git.saurik.com Git - bison.git/blame - src/scan-skel.l
scan-skel: recognize the @directives directly in scanner
[bison.git] / src / scan-skel.l
CommitLineData
be2a1a68 1/* Scan Bison Skeletons. -*- C -*-
353d3eb6 2
139c548a 3 Copyright (C) 2001-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
8d90395d 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 29#define FLEX_PREFIX(Id) skel_ ## Id
0305d25e 30#include <src/flex-scanner.h>
353d3eb6 31
cb48f191 32#include <dirname.h>
353d3eb6
PE
33#include <error.h>
34#include <quotearg.h>
35
0305d25e
AD
36#include <src/complain.h>
37#include <src/getargs.h>
38#include <src/files.h>
39#include <src/scan-skel.h>
dc9701e8 40
08af01c2
JD
41#define YY_DECL static int skel_lex (void)
42YY_DECL;
06f01bc4 43
92f39ba6
TR
44typedef void (*at_directive)(int, char**, char **, int*);
45static void at_init (int *argc, char *argv[], at_directive *at_ptr, at_directive fun);
46static void at_basename (int argc, char *argv[], char**, int*);
47static void at_complain (int argc, char *argv[], char**, int*);
896517cd 48static void at_output (int argc, char *argv[], char **name, int *lineno);
3eb82471
JD
49static void fail_for_at_directive_too_many_args (char const *at_directive_name);
50static void fail_for_at_directive_too_few_args (char const *at_directive_name);
08af01c2 51static void fail_for_invalid_at (char const *at);
aed7fd9b 52%}
08af01c2 53
3eb82471 54%x SC_AT_DIRECTIVE_ARGS
08af01c2
JD
55%x SC_AT_DIRECTIVE_SKIP_WS
56
9b3add5b 57%%
e9683cfd
PE
58
59%{
84f6a6ca 60 int out_lineno PACIFY_CC (= 0);
92f39ba6 61 char *out_name = NULL;
3eb82471 62
0505df0c
TR
63 /* Currently, only the @complain directive takes multiple arguments, and
64 never more than 7, with argv[0] being the directive name and argv[1]
65 being the type of complaint to dispatch. */
66#define ARGC_MAX 9
b9c3c10c
AD
67 int argc = 0;
68 char *argv[ARGC_MAX];
92f39ba6 69 at_directive at_ptr = NULL;
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);
92f39ba6 79"@ofile@" fputs (quotearg_style (c_quoting_style, out_name), yyout);
bd9d212b 80
92f39ba6
TR
81@basename"(" at_init (&argc, argv, &at_ptr, &at_basename);
82@complain"(" at_init (&argc, argv, &at_ptr, &at_complain);
83@output"(" at_init (&argc, argv, &at_ptr, &at_output);
84@[a-z_]+"(" at_init (&argc, argv, &at_ptr, NULL);
e9683cfd 85
3fc16193 86 /* This pattern must not match more than the previous @ patterns. */
7dc4a694 87@[^@{}`(\n]* fail_for_invalid_at (yytext);
e9690142
JD
88\n out_lineno++; ECHO;
89[^@\n]+ ECHO;
e9683cfd 90
dbfcf7a8 91<INITIAL><<EOF>> {
92f39ba6 92 if (out_name)
7ec5ab2e 93 {
92f39ba6 94 free (out_name);
7ec5ab2e
PE
95 xfclose (yyout);
96 }
97 return EOF;
98}
08af01c2 99
4d24ffb7
AD
100<SC_AT_DIRECTIVE_ARGS>
101{
102 [^@]+ STRING_GROW;
08af01c2 103
4d24ffb7
AD
104 "@@" obstack_1grow (&obstack_for_string, '@');
105 "@{" obstack_1grow (&obstack_for_string, '[');
106 "@}" obstack_1grow (&obstack_for_string, ']');
107 "@`" continue; /* For starting an argument that begins with whitespace. */
108 @\n continue;
08af01c2
JD
109
110 @[,)] {
b9c3c10c
AD
111 if (argc >= ARGC_MAX)
112 fail_for_at_directive_too_many_args (argv[0]);
08af01c2 113
b9c3c10c 114 argv[argc++] = obstack_finish0 (&obstack_for_string);
08af01c2
JD
115
116 /* Like M4, skip whitespace after a comma. */
117 if (yytext[1] == ',')
118 BEGIN SC_AT_DIRECTIVE_SKIP_WS;
119 else
120 {
92f39ba6
TR
121 if (at_ptr)
122 at_ptr (argc, argv, &out_name, &out_lineno);
896517cd
TR
123 else
124 fail_for_invalid_at (argv[0]);
125
b9c3c10c
AD
126 obstack_free (&obstack_for_string, argv[0]);
127 argc = 0;
08af01c2
JD
128 BEGIN INITIAL;
129 }
130 }
131
4d24ffb7 132 @.? fail_for_invalid_at (yytext);
08af01c2
JD
133}
134
4d24ffb7
AD
135<SC_AT_DIRECTIVE_SKIP_WS>
136{
137 [ \t\r\n] continue;
b9c3c10c 138 . yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS;
08af01c2
JD
139}
140
4d24ffb7
AD
141<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>
142{
bb8e56ff 143 <<EOF>> complain (NULL, fatal, _("unclosed %s directive in skeleton"), argv[0]);
08af01c2
JD
144}
145
9b3add5b 146%%
536545f3 147
92f39ba6
TR
148static void
149at_init (int *argc, char *argv[], at_directive *at_ptr, at_directive fun)
150{
151 *at_ptr = fun;
152 yytext[yyleng-1] = '\0';
153 obstack_grow (&obstack_for_string, yytext, yyleng);
154 argv[(*argc)++] = obstack_finish (&obstack_for_string);
155 BEGIN SC_AT_DIRECTIVE_ARGS;
156}
157
2cdb2a7b
PE
158/*------------------------.
159| Scan a Bison skeleton. |
160`------------------------*/
536545f3 161
536545f3 162void
2cdb2a7b 163scan_skel (FILE *in)
536545f3 164{
08af01c2
JD
165 static bool initialized = false;
166 if (!initialized)
167 {
168 initialized = true;
169 obstack_init (&obstack_for_string);
170 }
2cdb2a7b 171 skel_in = in;
c5e3e510 172 skel__flex_debug = trace_flag & trace_skeleton;
536545f3 173 skel_lex ();
536545f3 174}
bd9d212b 175
3fc65ead
JD
176void
177skel_scanner_free (void)
178{
179 obstack_free (&obstack_for_string, 0);
3eb82471
JD
180 /* Reclaim Flex's buffers. */
181 yylex_destroy ();
3fc65ead
JD
182}
183
b9c3c10c
AD
184static inline warnings
185flag (const char *arg)
186{
0505df0c 187 /* compare with values issued from b4_error */
896517cd 188 if (STREQ (arg, "complain"))
0505df0c
TR
189 return complaint;
190 else if (STREQ (arg, "fatal"))
191 return fatal;
c6c8de16
TR
192 else if (STREQ (arg, "note"))
193 return silent;
896517cd
TR
194 else if (STREQ (arg, "warn"))
195 return Wother;
0505df0c
TR
196 else
197 aver (false);
b9c3c10c
AD
198}
199
f39ab286 200static void
92f39ba6 201at_basename (int argc, char *argv[], char **out_namep, int *out_linenop)
3fc65ead 202{
92f39ba6
TR
203 (void) out_namep;
204 (void) out_linenop;
896517cd
TR
205 if (2 < argc)
206 fail_for_at_directive_too_many_args (argv[0]);
207 fputs (last_component (argv[1]), yyout);
208}
209
210static void
92f39ba6 211at_complain (int argc, char *argv[], char **out_namep, int *out_linenop)
896517cd
TR
212{
213 static unsigned indent;
214 warnings w = flag (argv[1]);
215 location loc;
216 location *locp = NULL;
217
92f39ba6
TR
218 (void) out_namep;
219 (void) out_linenop;
220
896517cd 221 if (argc < 4)
92f39ba6 222 fail_for_at_directive_too_few_args (argv[0]);
896517cd 223 if (argv[2] && argv[2][0])
3fc65ead 224 {
896517cd
TR
225 boundary_set_from_string (&loc.start, argv[2]);
226 boundary_set_from_string (&loc.end, argv[3]);
227 locp = &loc;
3fc65ead 228 }
896517cd
TR
229 if (w & silent)
230 indent += SUB_INDENT;
3fc65ead 231 else
896517cd
TR
232 indent = 0;
233 complain_args (locp, w, &indent, argc - 3, argv + 3);
234 if (w & silent)
235 indent -= SUB_INDENT;
3fc65ead
JD
236}
237
238static void
92f39ba6 239at_output (int argc, char *argv[], char **out_namep, int *out_linenop)
896517cd
TR
240{
241 if (2 < argc)
242 fail_for_at_directive_too_many_args (argv[0]);
92f39ba6 243 if (*out_namep)
896517cd 244 {
92f39ba6 245 free (*out_namep);
896517cd
TR
246 xfclose (yyout);
247 }
92f39ba6
TR
248 *out_namep = xstrdup (argv[1]);
249 output_file_name_check (out_namep);
250 yyout = xfopen (*out_namep, "w");
896517cd
TR
251 *out_linenop = 1;
252}
253
254 static void
3eb82471 255fail_for_at_directive_too_few_args (char const *at_directive_name)
3fc65ead 256{
bb8e56ff 257 complain (NULL, fatal, _("too few arguments for %s directive in skeleton"),
b9c3c10c 258 at_directive_name);
3fc65ead
JD
259}
260
08af01c2 261static void
3eb82471 262fail_for_at_directive_too_many_args (char const *at_directive_name)
bd9d212b 263{
bb8e56ff 264 complain (NULL, fatal, _("too many arguments for %s directive in skeleton"),
6fb8b256 265 at_directive_name);
08af01c2
JD
266}
267
268static void
269fail_for_invalid_at (char const *at)
270{
bb8e56ff 271 complain (NULL, fatal, "invalid @ in skeleton: %s", at);
08af01c2 272}