]> git.saurik.com Git - bison.git/blob - src/parse-skel.y
8cf7fcd5d3bd92629b68ffd455b8599e768e4e2a
[bison.git] / src / parse-skel.y
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
24 %verbose
25 %error-verbose
26
27 %{
28 #include "system.h"
29 #include "obstack.h"
30 #include "files.h"
31 #include "output.h"
32 #include "skeleton.h"
33 #include "muscle_tab.h"
34
35 extern FILE* yyin;
36 extern int yylineno;
37
38 char* prefix = NULL;
39 FILE* parser = NULL;
40
41 size_t output_line;
42 size_t skeleton_line;
43
44 static int merror PARAMS ((const char* error));
45 static int yyerror PARAMS ((const char* error));
46
47 %}
48
49 %union
50 {
51 char *muscle;
52 char *string;
53 char *literal;
54 char character;
55 int yacc;
56 }
57
58 /* Name of a muscle. */
59 %token <muscle> MUSCLE
60 /* A string dedicated to Bison (%%"foo"). */
61 %token <string> STRING
62 /* Raw data, to output directly. */
63 %token <literal> RAW
64 /* Spaces. */
65 %token <literal> BLANKS
66 /* Raw data, but char by char. */
67 %token <character> CHARACTER
68
69 %token LINE
70 %token SLINE
71
72 %token YACC
73 %token SECTION
74
75 %token GUARDS
76 %token TOKENS
77 %token ACTIONS
78
79 %type <yacc> section.yacc
80
81 %start skeleton
82
83 %%
84
85 skeleton : /* Empty. */ { }
86 | section skeleton { }
87 ;
88
89 section : section.header section.body { }
90 ;
91
92 section.header : SECTION BLANKS MUSCLE BLANKS STRING BLANKS section.yacc '\n'
93 {
94 char *name = 0;
95 char *limit = 0;
96 char *suffix = $5;
97
98 /* Close the previous parser. */
99 if (parser)
100 parser = (xfclose (parser), NULL);
101
102 /* If the following section should be named with the yacc-style, and it's
103 suffix is of the form 'something.h' or 'something.c', then add '.tab' in
104 the middle of the suffix. */
105 if (tab_extension && $7 && (strsuffix (suffix, ".h") ||
106 strsuffix (suffix, ".c")))
107 {
108 size_t prefix_len = strlen (prefix);
109 size_t suffix_len = strlen (suffix);
110
111 /* Allocate enough space to insert '.tab'. */
112 name = XMALLOC (char, prefix_len + suffix_len + 5);
113 limit = strrchr (suffix, '.');
114 if (!limit)
115 limit = suffix;
116
117 /* Prefix is 'X', suffix is 'Y.Z'. Name will be 'XY.tab.Z'. */
118 {
119 char* cp = 0;
120 cp = stpcpy (name, prefix);
121 cp = stpncpy (cp, suffix, limit - suffix);
122 cp = stpcpy (cp, ".tab");
123 cp = stpcpy (cp, limit);
124 }
125 }
126 else
127 name = stringappend (prefix, suffix);
128
129 /* Prepare the next parser to be output. */
130 parser = xfopen (name, "w");
131 MUSCLE_INSERT_STRING ("parser-file-name", name);
132 XFREE (name);
133
134 ++skeleton_line;
135 }
136 ;
137
138 section.yacc : /* Empty. */ { $$ = 0; }
139 | YACC { $$ = 1; }
140 ;
141
142 section.body
143 : /* Empty. */ { }
144 | section.body '\n' { fputc ('\n', parser); ++output_line; ++skeleton_line; }
145 | section.body LINE { fprintf (parser, "%d", output_line); }
146 | section.body SLINE { fprintf (parser, "%d", skeleton_line); }
147 | section.body GUARDS { guards_output (parser, &output_line); }
148 | section.body TOKENS { token_definitions_output (parser, &output_line); }
149 | section.body ACTIONS { actions_output (parser, &output_line); }
150 | section.body CHARACTER { fputc ($2, parser); }
151 | section.body RAW { fputs ($2, parser); }
152 | section.body BLANKS { fputs ($2, parser); }
153 | section.body MUSCLE {
154 const char* value = muscle_find ($2);
155 if (value)
156 {
157 fputs (value, parser);
158 output_line += get_lines_number (value);
159 }
160 else
161 {
162 fprintf (parser, "%%{%s}", $2);
163 merror ($2);
164 }
165 }
166 ;
167 %%
168
169 static int
170 merror (const char* error)
171 {
172 printf ("line %d: %%{%s} undeclared.\n", skeleton_line, error);
173 return 0;
174 }
175
176 static int
177 yyerror (const char* error)
178 {
179 fprintf (stderr, "%s\n", error);
180 return 0;
181 }
182
183 void
184 process_skeleton (const char* skel)
185 {
186 /* Compute prefix. Actually, it seems that the processing I need here is
187 done in compute_base_names, and the result stored in short_base_name. */
188 prefix = short_base_name;
189
190 /* Prepare a few things. */
191 output_line = 1;
192 skeleton_line = 1;
193
194 /* Output. */
195 yyin = fopen (skel, "r");
196 yydebug = 0;
197 yyparse ();
198
199 /* Close the last parser. */
200 if (parser)
201 parser = (xfclose (parser), NULL);
202 }