]> git.saurik.com Git - bison.git/blame - src/scan-skel.l
errors: support indented context info in m4 macros
[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
b9c3c10c 44static void at_directive_perform (int argc, char *argv[],
3eb82471
JD
45 char **outnamep, int *out_linenop);
46static void fail_for_at_directive_too_many_args (char const *at_directive_name);
47static void fail_for_at_directive_too_few_args (char const *at_directive_name);
08af01c2 48static void fail_for_invalid_at (char const *at);
aed7fd9b 49%}
08af01c2 50
3eb82471 51%x SC_AT_DIRECTIVE_ARGS
08af01c2
JD
52%x SC_AT_DIRECTIVE_SKIP_WS
53
9b3add5b 54%%
e9683cfd
PE
55
56%{
84f6a6ca 57 int out_lineno PACIFY_CC (= 0);
e9683cfd 58 char *outname = NULL;
3eb82471 59
0505df0c
TR
60 /* Currently, only the @complain directive takes multiple arguments, and
61 never more than 7, with argv[0] being the directive name and argv[1]
62 being the type of complaint to dispatch. */
63#define ARGC_MAX 9
b9c3c10c
AD
64 int argc = 0;
65 char *argv[ARGC_MAX];
e9683cfd
PE
66%}
67
7dc4a694
JD
68"@@" fputc ('@', yyout);
69"@{" fputc ('[', yyout);
70"@}" fputc (']', yyout);
4d24ffb7
AD
71"@`" continue; /* Used by b4_cat in ../data/bison.m4. */
72@\n continue;
e9683cfd 73
3fc65ead 74"@oline@" fprintf (yyout, "%d", out_lineno + 1);
b9c3c10c 75"@ofile@" fputs (quotearg_style (c_quoting_style, outname), yyout);
bd9d212b 76
08af01c2
JD
77@[a-z_]+"(" {
78 yytext[yyleng-1] = '\0';
3eb82471 79 obstack_grow (&obstack_for_string, yytext, yyleng);
b9c3c10c 80 argv[argc++] = obstack_finish (&obstack_for_string);
3eb82471 81 BEGIN SC_AT_DIRECTIVE_ARGS;
bd9d212b 82}
e9683cfd 83
3fc16193 84 /* This pattern must not match more than the previous @ patterns. */
7dc4a694 85@[^@{}`(\n]* fail_for_invalid_at (yytext);
e9690142
JD
86\n out_lineno++; ECHO;
87[^@\n]+ ECHO;
e9683cfd 88
dbfcf7a8 89<INITIAL><<EOF>> {
7ec5ab2e
PE
90 if (outname)
91 {
92 free (outname);
93 xfclose (yyout);
94 }
95 return EOF;
96}
08af01c2 97
4d24ffb7
AD
98<SC_AT_DIRECTIVE_ARGS>
99{
100 [^@]+ STRING_GROW;
08af01c2 101
4d24ffb7
AD
102 "@@" obstack_1grow (&obstack_for_string, '@');
103 "@{" obstack_1grow (&obstack_for_string, '[');
104 "@}" obstack_1grow (&obstack_for_string, ']');
105 "@`" continue; /* For starting an argument that begins with whitespace. */
106 @\n continue;
08af01c2
JD
107
108 @[,)] {
b9c3c10c
AD
109 if (argc >= ARGC_MAX)
110 fail_for_at_directive_too_many_args (argv[0]);
08af01c2 111
b9c3c10c 112 argv[argc++] = obstack_finish0 (&obstack_for_string);
08af01c2
JD
113
114 /* Like M4, skip whitespace after a comma. */
115 if (yytext[1] == ',')
116 BEGIN SC_AT_DIRECTIVE_SKIP_WS;
117 else
118 {
b9c3c10c
AD
119 at_directive_perform (argc, argv, &outname, &out_lineno);
120 obstack_free (&obstack_for_string, argv[0]);
121 argc = 0;
08af01c2
JD
122 BEGIN INITIAL;
123 }
124 }
125
4d24ffb7 126 @.? fail_for_invalid_at (yytext);
08af01c2
JD
127}
128
4d24ffb7
AD
129<SC_AT_DIRECTIVE_SKIP_WS>
130{
131 [ \t\r\n] continue;
b9c3c10c 132 . yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS;
08af01c2
JD
133}
134
4d24ffb7
AD
135<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>
136{
bb8e56ff 137 <<EOF>> complain (NULL, fatal, _("unclosed %s directive in skeleton"), argv[0]);
08af01c2
JD
138}
139
9b3add5b 140%%
536545f3 141
2cdb2a7b
PE
142/*------------------------.
143| Scan a Bison skeleton. |
144`------------------------*/
536545f3 145
536545f3 146void
2cdb2a7b 147scan_skel (FILE *in)
536545f3 148{
08af01c2
JD
149 static bool initialized = false;
150 if (!initialized)
151 {
152 initialized = true;
153 obstack_init (&obstack_for_string);
154 }
2cdb2a7b 155 skel_in = in;
c5e3e510 156 skel__flex_debug = trace_flag & trace_skeleton;
536545f3 157 skel_lex ();
536545f3 158}
bd9d212b 159
3fc65ead
JD
160void
161skel_scanner_free (void)
162{
163 obstack_free (&obstack_for_string, 0);
3eb82471
JD
164 /* Reclaim Flex's buffers. */
165 yylex_destroy ();
3fc65ead
JD
166}
167
b9c3c10c
AD
168static inline warnings
169flag (const char *arg)
170{
0505df0c
TR
171 /* compare with values issued from b4_error */
172 if (STREQ (arg, "warn"))
173 return Wother;
174 else if (STREQ (arg, "complain"))
175 return complaint;
176 else if (STREQ (arg, "fatal"))
177 return fatal;
c6c8de16
TR
178 else if (STREQ (arg, "note"))
179 return silent;
0505df0c
TR
180 else
181 aver (false);
b9c3c10c
AD
182}
183
f39ab286 184static void
b9c3c10c 185at_directive_perform (int argc, char *argv[], char **outnamep, int *out_linenop)
3fc65ead 186{
b9c3c10c 187 if (STREQ (argv[0], "@basename"))
3fc65ead 188 {
b9c3c10c
AD
189 if (argc > 2)
190 fail_for_at_directive_too_many_args (argv[0]);
191 fputs (last_component (argv[1]), yyout);
3fc65ead 192 }
0505df0c 193 else if (STREQ (argv[0], "@complain"))
3fc65ead 194 {
c6c8de16 195 static unsigned indent;
c4e3a162
AD
196 if (argc < 4)
197 fail_for_at_directive_too_few_args (argv[0]);
0505df0c 198 warnings w = flag (argv[1]);
c6c8de16
TR
199 if ((w & silent) != silent)
200 indent = 0;
0505df0c
TR
201 location loc;
202 location *locp = NULL;
203 if (argv[2] && argv[2][0])
3fc65ead 204 {
0505df0c
TR
205 boundary_set_from_string (&loc.start, argv[2]);
206 boundary_set_from_string (&loc.end, argv[3]);
782e8187 207 locp = &loc;
3fc65ead 208 }
c6c8de16
TR
209 if (w & silent)
210 indent += SUB_INDENT;
211 complain_args (locp, w, &indent, argc - 3, argv + 3);
212 if (w & silent)
213 indent -= SUB_INDENT;
214 }
b9c3c10c 215 else if (STREQ (argv[0], "@output"))
3fc65ead 216 {
b9c3c10c
AD
217 if (argc > 2)
218 fail_for_at_directive_too_many_args (argv[0]);
3fc65ead
JD
219 if (*outnamep)
220 {
221 free (*outnamep);
222 xfclose (yyout);
223 }
b9c3c10c 224 *outnamep = xstrdup (argv[1]);
f39ab286 225 output_file_name_check (outnamep);
3fc65ead
JD
226 yyout = xfopen (*outnamep, "w");
227 *out_linenop = 1;
228 }
229 else
b9c3c10c 230 fail_for_invalid_at (argv[0]);
3fc65ead
JD
231}
232
233static void
3eb82471 234fail_for_at_directive_too_few_args (char const *at_directive_name)
3fc65ead 235{
bb8e56ff 236 complain (NULL, fatal, _("too few arguments for %s directive in skeleton"),
b9c3c10c 237 at_directive_name);
3fc65ead
JD
238}
239
08af01c2 240static void
3eb82471 241fail_for_at_directive_too_many_args (char const *at_directive_name)
bd9d212b 242{
bb8e56ff 243 complain (NULL, fatal, _("too many arguments for %s directive in skeleton"),
6fb8b256 244 at_directive_name);
08af01c2
JD
245}
246
247static void
248fail_for_invalid_at (char const *at)
249{
bb8e56ff 250 complain (NULL, fatal, "invalid @ in skeleton: %s", at);
08af01c2 251}