]> git.saurik.com Git - bison.git/blame - src/parse-skel.y
* src/getargs.c (AS_FILE_NAME): New.
[bison.git] / src / parse-skel.y
CommitLineData
1239777d
AD
1 /* -*- C -*- */
2/* Parse Bison Skeletons.
3 Copyright (C) 2001 Free Software Foundation, Inc.
4
5 This file is part of Bison, the GNU Compiler Compiler.
6
7 Bison is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 Bison is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bison; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22%debug
23%defines
a4b36db4 24%verbose
aed7fd9b
AD
25%locations
26%name-prefix="skel_"
27%pure-parser
9b3add5b 28
1239777d 29%{
9b3add5b
RA
30#include "system.h"
31#include "obstack.h"
aed7fd9b 32#include "quotearg.h"
9b3add5b 33#include "files.h"
aed7fd9b 34#include "getargs.h"
1239777d
AD
35#include "output.h"
36#include "skeleton.h"
9b3add5b
RA
37#include "muscle_tab.h"
38
a67cef01
TVH
39#define YYERROR_VERBOSE 1
40
aed7fd9b
AD
41/* Pass the control structure to YYPARSE but not YYLEX (yet?). */
42#define YYPARSE_PARAM skel_control
43/* YYPARSE receives SKEL_CONTROL as a void *. Provide a correctly
44 typed access to it. */
45#define yycontrol ((skel_control_t *) skel_control)
9b3add5b
RA
46
47char* prefix = NULL;
48FILE* parser = NULL;
49
50size_t output_line;
51size_t skeleton_line;
52
aed7fd9b 53static void merror PARAMS ((const char* error));
9b3add5b 54
aed7fd9b
AD
55/* Request detailed parse error messages, and pass them to
56 YLEVAL_ERROR. */
57#undef yyerror
58#define yyerror(Msg) \
59 skel_error (yycontrol, &yylloc, Msg)
60
61/* When debugging our pure parser, we want to see values and locations
62 of the tokens. */
63#define YYPRINT(File, Type, Value) \
64 yyprint (File, &yylloc, Type, &Value)
65static void yyprint (FILE *file, const yyltype *loc,
66 int type, const yystype *value);
9b3add5b
RA
67%}
68
69%union
70{
a4b36db4 71 char *string;
9b3add5b 72 char character;
aed7fd9b 73 int boolean;
9b3add5b
RA
74}
75
24fad99e 76/* Name of a muscle. */
aed7fd9b 77%token <string> MUSCLE
24fad99e 78/* A string dedicated to Bison (%%"foo"). */
1239777d 79%token <string> STRING
24fad99e 80/* Raw data, to output directly. */
aed7fd9b 81%token <string> RAW
24fad99e 82/* Spaces. */
aed7fd9b 83%token <string> BLANKS
24fad99e 84/* Raw data, but char by char. */
1239777d 85%token <character> CHARACTER
9b3add5b
RA
86
87%token LINE
88%token SLINE
89
90%token YACC
91%token SECTION
92
93%token GUARDS
94%token TOKENS
95%token ACTIONS
96
aed7fd9b 97%type <boolean> section.yacc
9b3add5b 98
aed7fd9b 99%start input
9b3add5b
RA
100
101%%
aed7fd9b
AD
102input:
103 { LOCATION_RESET (yylloc) } skeleton
104 ;
9b3add5b
RA
105
106skeleton : /* Empty. */ { }
107 | section skeleton { }
108;
109
110section : section.header section.body { }
111;
112
24fad99e 113section.header : SECTION BLANKS MUSCLE BLANKS STRING BLANKS section.yacc '\n'
9b3add5b 114{
1239777d
AD
115 char *name = 0;
116 char *limit = 0;
117 char *suffix = $5;
9b3add5b
RA
118
119 /* Close the previous parser. */
120 if (parser)
121 parser = (xfclose (parser), NULL);
122
123 /* If the following section should be named with the yacc-style, and it's
124 suffix is of the form 'something.h' or 'something.c', then add '.tab' in
125 the middle of the suffix. */
1239777d 126 if (tab_extension && $7 && (strsuffix (suffix, ".h") ||
9b3add5b
RA
127 strsuffix (suffix, ".c")))
128 {
129 size_t prefix_len = strlen (prefix);
130 size_t suffix_len = strlen (suffix);
131
132 /* Allocate enough space to insert '.tab'. */
133 name = XMALLOC (char, prefix_len + suffix_len + 5);
134 limit = strrchr (suffix, '.');
135 if (!limit)
136 limit = suffix;
137
138 /* Prefix is 'X', suffix is 'Y.Z'. Name will be 'XY.tab.Z'. */
139 {
140 char* cp = 0;
141 cp = stpcpy (name, prefix);
142 cp = stpncpy (cp, suffix, limit - suffix);
143 cp = stpcpy (cp, ".tab");
144 cp = stpcpy (cp, limit);
145 }
146 }
147 else
148 name = stringappend (prefix, suffix);
1239777d 149
9b3add5b
RA
150 /* Prepare the next parser to be output. */
151 parser = xfopen (name, "w");
152 MUSCLE_INSERT_STRING ("parser-file-name", name);
153 XFREE (name);
154
155 ++skeleton_line;
156}
157;
158
159section.yacc : /* Empty. */ { $$ = 0; }
160 | YACC { $$ = 1; }
161;
162
1239777d 163section.body
9b3add5b
RA
164: /* Empty. */ { }
165| section.body '\n' { fputc ('\n', parser); ++output_line; ++skeleton_line; }
166| section.body LINE { fprintf (parser, "%d", output_line); }
167| section.body SLINE { fprintf (parser, "%d", skeleton_line); }
168| section.body GUARDS { guards_output (parser, &output_line); }
169| section.body TOKENS { token_definitions_output (parser, &output_line); }
170| section.body ACTIONS { actions_output (parser, &output_line); }
171| section.body CHARACTER { fputc ($2, parser); }
24fad99e
AD
172| section.body RAW { fputs ($2, parser); }
173| section.body BLANKS { fputs ($2, parser); }
1239777d 174| section.body MUSCLE {
9b3add5b
RA
175 const char* value = muscle_find ($2);
176 if (value)
177 {
178 fputs (value, parser);
179 output_line += get_lines_number (value);
180 }
181 else
182 {
183 fprintf (parser, "%%{%s}", $2);
184 merror ($2);
185 }
186}
187;
9b3add5b 188%%
aed7fd9b
AD
189/*------------------------------------------------------------------.
190| When debugging the parser, display tokens' locations and values. |
191`------------------------------------------------------------------*/
192
193static void
194yyprint (FILE *file,
195 const yyltype *loc, int type, const yystype *value)
196{
197 fputs (" (", file);
198 LOCATION_PRINT (file, *loc);
199 fputs (")", file);
200 switch (type)
201 {
202 case MUSCLE:
203 case STRING:
204 case RAW:
205 case BLANKS:
206 fprintf (file, " = %s", quotearg_style (c_quoting_style,
207 value->string));
208 break;
209
210 case CHARACTER:
211 fprintf (file, " = '%c'", value->character);
212 break;
213
214 case YACC:
215 fprintf (file, " = %s", value->boolean ? "true" : "false");
216 break;
217 }
218}
9b3add5b 219
aed7fd9b
AD
220
221static void
9b3add5b
RA
222merror (const char* error)
223{
224 printf ("line %d: %%{%s} undeclared.\n", skeleton_line, error);
9b3add5b
RA
225}
226
aed7fd9b
AD
227void
228skel_error (skel_control_t *control,
229 const yyltype *loc, const char *msg)
9b3add5b 230{
aed7fd9b
AD
231 /* Neutralize GCC warnings for unused parameters. */
232 skel_control_t *c = control;
233 c++;
234 LOCATION_PRINT (stderr, *loc);
235 fprintf (stderr, "%s\n", msg);
9b3add5b
RA
236}
237
1239777d
AD
238void
239process_skeleton (const char* skel)
9b3add5b 240{
9b3add5b
RA
241 /* Compute prefix. Actually, it seems that the processing I need here is
242 done in compute_base_names, and the result stored in short_base_name. */
243 prefix = short_base_name;
244
245 /* Prepare a few things. */
246 output_line = 1;
247 skeleton_line = 1;
248
249 /* Output. */
aed7fd9b 250 skel_in = fopen (skel, "r");
1109455c
AD
251 /* FIXME: This is not acceptable for a release. */
252 skel__flex_debug = getenv ("BISON_TRACE_SCAN") ? 1 : 0;
253 skel_debug = getenv ("BISON_TRACE_PARSE") ? 1 : 0;
aed7fd9b 254 skel_parse (NULL);
9b3add5b
RA
255
256 /* Close the last parser. */
257 if (parser)
258 parser = (xfclose (parser), NULL);
259}