]> git.saurik.com Git - bison.git/blame - src/scan-skel.l
Java: Fix syntax error handling without error token.
[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);
2b81e969 80"@dir_prefix@" QPUTS (dir_prefix);
bd9d212b 81
08af01c2
JD
82@[a-z_]+"(" {
83 yytext[yyleng-1] = '\0';
3eb82471
JD
84 obstack_grow (&obstack_for_string, yytext, yyleng);
85 at_directive_argv[at_directive_argc++] =
86 obstack_finish (&obstack_for_string);
87 BEGIN SC_AT_DIRECTIVE_ARGS;
bd9d212b 88}
e9683cfd 89
3fc16193 90 /* This pattern must not match more than the previous @ patterns. */
7dc4a694 91@[^@{}`(\n]* fail_for_invalid_at (yytext);
3fc65ead 92\n out_lineno++; ECHO;
68e93ad5 93[^@\n]+ ECHO;
e9683cfd 94
08af01c2 95<INITIAL><<EOF>> {
7ec5ab2e
PE
96 if (outname)
97 {
98 free (outname);
99 xfclose (yyout);
100 }
101 return EOF;
102}
08af01c2 103
3eb82471 104<SC_AT_DIRECTIVE_ARGS>{
5f340b48 105 [^@]+ { STRING_GROW; }
08af01c2 106
5f340b48
JD
107 "@@" { obstack_1grow (&obstack_for_string, '@'); }
108 "@{" { obstack_1grow (&obstack_for_string, '['); }
109 "@}" { obstack_1grow (&obstack_for_string, ']'); }
47fa5747 110 "@`" /* Empty. Useful for starting an argument
08af01c2 111 that begins with whitespace. */
7dc4a694 112 @\n /* Empty. */
08af01c2
JD
113
114 @[,)] {
115 if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX)
3eb82471 116 fail_for_at_directive_too_many_args (at_directive_argv[0]);
08af01c2
JD
117
118 obstack_1grow (&obstack_for_string, '\0');
119 at_directive_argv[at_directive_argc++] =
120 obstack_finish (&obstack_for_string);
121
122 /* Like M4, skip whitespace after a comma. */
123 if (yytext[1] == ',')
124 BEGIN SC_AT_DIRECTIVE_SKIP_WS;
125 else
126 {
3eb82471
JD
127 at_directive_perform (at_directive_argc, at_directive_argv,
128 &outname, &out_lineno);
08af01c2
JD
129 obstack_free (&obstack_for_string, at_directive_argv[0]);
130 at_directive_argc = 0;
08af01c2
JD
131 BEGIN INITIAL;
132 }
133 }
134
135 @.? { fail_for_invalid_at (yytext); }
136}
137
138<SC_AT_DIRECTIVE_SKIP_WS>{
3fc65ead 139 [ \t\r\n]
3eb82471 140 . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; }
08af01c2
JD
141}
142
3eb82471 143<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>{
08af01c2 144 <<EOF>> {
3eb82471 145 fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]);
08af01c2
JD
146 }
147}
148
9b3add5b 149%%
536545f3 150
2cdb2a7b
PE
151/*------------------------.
152| Scan a Bison skeleton. |
153`------------------------*/
536545f3 154
536545f3 155void
2cdb2a7b 156scan_skel (FILE *in)
536545f3 157{
08af01c2
JD
158 static bool initialized = false;
159 if (!initialized)
160 {
161 initialized = true;
162 obstack_init (&obstack_for_string);
163 }
2cdb2a7b 164 skel_in = in;
c5e3e510 165 skel__flex_debug = trace_flag & trace_skeleton;
536545f3 166 skel_lex ();
536545f3 167}
bd9d212b 168
3fc65ead
JD
169void
170skel_scanner_free (void)
171{
172 obstack_free (&obstack_for_string, 0);
3eb82471
JD
173 /* Reclaim Flex's buffers. */
174 yylex_destroy ();
3fc65ead
JD
175}
176
47fa5747
JD
177static void
178at_directive_perform (int at_directive_argc,
179 char *at_directive_argv[],
180 char **outnamep, int *out_linenop)
3fc65ead 181{
3eb82471 182 if (0 == strcmp (at_directive_argv[0], "@basename"))
3fc65ead 183 {
3eb82471
JD
184 if (at_directive_argc > 2)
185 fail_for_at_directive_too_many_args (at_directive_argv[0]);
186 fputs (last_component (at_directive_argv[1]), yyout);
3fc65ead 187 }
3eb82471
JD
188 else if (0 == strcmp (at_directive_argv[0], "@warn")
189 || 0 == strcmp (at_directive_argv[0], "@complain")
190 || 0 == strcmp (at_directive_argv[0], "@fatal"))
3fc65ead
JD
191 {
192 void (*func)(char const *, ...);
3eb82471 193 switch (at_directive_argv[0][1])
3fc65ead
JD
194 {
195 case 'w': func = warn; break;
196 case 'c': func = complain; break;
197 case 'f': func = fatal; break;
3eb82471 198 default: aver (false); break;
3fc65ead
JD
199 }
200 switch (at_directive_argc)
201 {
87b0a375 202 case 2:
3eb82471 203 func (_(at_directive_argv[1]));
3fc65ead 204 break;
87b0a375 205 case 3:
3eb82471 206 func (_(at_directive_argv[1]), at_directive_argv[2]);
3fc65ead 207 break;
87b0a375 208 case 4:
3eb82471
JD
209 func (_(at_directive_argv[1]), at_directive_argv[2],
210 at_directive_argv[3]);
3fc65ead 211 break;
87b0a375 212 case 5:
3eb82471
JD
213 func (_(at_directive_argv[1]), at_directive_argv[2],
214 at_directive_argv[3], at_directive_argv[4]);
3fc65ead 215 break;
87b0a375 216 case 6:
3eb82471
JD
217 func (_(at_directive_argv[1]), at_directive_argv[2],
218 at_directive_argv[3], at_directive_argv[4],
219 at_directive_argv[5]);
3fc65ead
JD
220 break;
221 default:
3eb82471 222 fail_for_at_directive_too_many_args (at_directive_argv[0]);
3fc65ead
JD
223 break;
224 }
225 }
3eb82471
JD
226 else if (0 == strcmp (at_directive_argv[0], "@warn_at")
227 || 0 == strcmp (at_directive_argv[0], "@complain_at")
228 || 0 == strcmp (at_directive_argv[0], "@fatal_at"))
3fc65ead
JD
229 {
230 void (*func)(location, char const *, ...);
231 location loc;
3eb82471
JD
232 if (at_directive_argc < 4)
233 fail_for_at_directive_too_few_args (at_directive_argv[0]);
234 switch (at_directive_argv[0][1])
3fc65ead
JD
235 {
236 case 'w': func = warn_at; break;
237 case 'c': func = complain_at; break;
238 case 'f': func = fatal_at; break;
3eb82471 239 default: aver (false); break;
3fc65ead 240 }
3eb82471
JD
241 boundary_set_from_string (&loc.start, at_directive_argv[1]);
242 boundary_set_from_string (&loc.end, at_directive_argv[2]);
3fc65ead
JD
243 switch (at_directive_argc)
244 {
87b0a375 245 case 4:
3eb82471 246 func (loc, _(at_directive_argv[3]));
3fc65ead 247 break;
87b0a375 248 case 5:
3eb82471 249 func (loc, _(at_directive_argv[3]), at_directive_argv[4]);
3fc65ead 250 break;
87b0a375 251 case 6:
3eb82471
JD
252 func (loc, _(at_directive_argv[3]), at_directive_argv[4],
253 at_directive_argv[5]);
3fc65ead 254 break;
87b0a375 255 case 7:
3eb82471
JD
256 func (loc, _(at_directive_argv[3]), at_directive_argv[4],
257 at_directive_argv[5], at_directive_argv[6]);
3fc65ead 258 break;
87b0a375 259 case 8:
3eb82471
JD
260 func (loc, _(at_directive_argv[3]), at_directive_argv[4],
261 at_directive_argv[5], at_directive_argv[6],
262 at_directive_argv[7]);
3fc65ead
JD
263 break;
264 default:
3eb82471 265 fail_for_at_directive_too_many_args (at_directive_argv[0]);
3fc65ead
JD
266 break;
267 }
268 }
3eb82471 269 else if (0 == strcmp (at_directive_argv[0], "@output"))
3fc65ead 270 {
3eb82471
JD
271 if (at_directive_argc > 2)
272 fail_for_at_directive_too_many_args (at_directive_argv[0]);
3fc65ead
JD
273 if (*outnamep)
274 {
275 free (*outnamep);
276 xfclose (yyout);
277 }
3eb82471 278 *outnamep = xstrdup (at_directive_argv[1]);
47fa5747 279 output_file_name_check (outnamep);
3fc65ead
JD
280 yyout = xfopen (*outnamep, "w");
281 *out_linenop = 1;
282 }
283 else
3eb82471 284 fail_for_invalid_at (at_directive_argv[0]);
3fc65ead
JD
285}
286
287static void
3eb82471 288fail_for_at_directive_too_few_args (char const *at_directive_name)
3fc65ead
JD
289{
290 fatal (_("too few arguments for %s directive in skeleton"),
291 at_directive_name);
292}
293
08af01c2 294static void
3eb82471 295fail_for_at_directive_too_many_args (char const *at_directive_name)
bd9d212b 296{
08af01c2
JD
297 fatal (_("too many arguments for %s directive in skeleton"),
298 at_directive_name);
299}
300
301static void
302fail_for_invalid_at (char const *at)
303{
304 fatal ("invalid @ in skeleton: %s", at);
305}