]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/mcparse.y
* objcopy.c (copy_main): Initialize context variable.
[thirdparty/binutils-gdb.git] / binutils / mcparse.y
CommitLineData
692ed3e7
NC
1%{ /* mcparse.y -- parser for Windows mc files
2 Copyright 2007
3 Free Software Foundation, Inc.
4
5 Parser for Windows mc files
6 Written by Kai Tietz, Onevision.
7
8 This file is part of GNU Binutils.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
32866df7 12 the Free Software Foundation; either version 3 of the License, or
692ed3e7
NC
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
23 02110-1301, USA. */
24
25/* This is a parser for Windows rc files. It is based on the parser
26 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
27
28#include "sysdep.h"
29#include "bfd.h"
30#include "bucomm.h"
31#include "libiberty.h"
32#include "windmc.h"
33#include "safe-ctype.h"
34
35static rc_uint_type mc_last_id = 0;
36static rc_uint_type mc_sefa_val = 0;
37static unichar *mc_last_symbol = NULL;
38static const mc_keyword *mc_cur_severity = NULL;
39static const mc_keyword *mc_cur_facility = NULL;
40static mc_node *cur_node = NULL;
41
42%}
43
44%union
45{
46 rc_uint_type ival;
47 unichar *ustr;
48 const mc_keyword *tok;
49 mc_node *nod;
50};
51
52%start input
53
54%token NL
55%token<ustr> MCIDENT MCFILENAME MCLINE MCCOMMENT
56%token<tok> MCTOKEN
57%token MCENDLINE
58%token MCLANGUAGENAMES MCFACILITYNAMES MCSEVERITYNAMES MCOUTPUTBASE MCMESSAGEIDTYPEDEF
59%token MCLANGUAGE MCMESSAGEID MCSEVERITY MCFACILITY MCSYMBOLICNAME
60%token <ival> MCNUMBER
61
62%type<ival> id vid sefasy_def
63%type<ustr> alias_name token lines comments
64%type<tok> lang
65
66%%
67input: entities
68 ;
69
70entities:
71 /* empty */
72 | entities entity
73 ;
74entity: global_section
75 | message
76 | comments
77 {
78 cur_node = mc_add_node ();
79 cur_node->user_text = $1;
80 }
81 | error { mc_fatal ("syntax error"); }
82;
83
84global_section:
85 MCSEVERITYNAMES '=' '(' severitymaps ')'
86 | MCSEVERITYNAMES '=' '(' severitymaps error { mc_fatal ("missing ')' in SeverityNames"); }
87 | MCSEVERITYNAMES '=' error { mc_fatal ("missing '(' in SeverityNames"); }
88 | MCSEVERITYNAMES error { mc_fatal ("missing '=' for SeverityNames"); }
89 | MCLANGUAGENAMES '=' '(' langmaps ')'
90 | MCLANGUAGENAMES '=' '(' langmaps error { mc_fatal ("missing ')' in LanguageNames"); }
91 | MCLANGUAGENAMES '=' error { mc_fatal ("missing '(' in LanguageNames"); }
92 | MCLANGUAGENAMES error { mc_fatal ("missing '=' for LanguageNames"); }
93 | MCFACILITYNAMES '=' '(' facilitymaps ')'
94 | MCFACILITYNAMES '=' '(' facilitymaps error { mc_fatal ("missing ')' in FacilityNames"); }
95 | MCFACILITYNAMES '=' error { mc_fatal ("missing '(' in FacilityNames"); }
96 | MCFACILITYNAMES error { mc_fatal ("missing '=' for FacilityNames"); }
97 | MCOUTPUTBASE '=' MCNUMBER
98 {
99 if ($3 != 10 && $3 != 16)
100 mc_fatal ("OutputBase allows 10 or 16 as value");
101 mcset_out_values_are_decimal = ($3 == 10 ? 1 : 0);
102 }
103 | MCMESSAGEIDTYPEDEF '=' MCIDENT
104 {
105 mcset_msg_id_typedef = $3;
106 }
107 | MCMESSAGEIDTYPEDEF '=' error
108 {
109 mc_fatal ("MessageIdTypedef expects an identifier");
110 }
111 | MCMESSAGEIDTYPEDEF error
112 {
113 mc_fatal ("missing '=' for MessageIdTypedef");
114 }
115;
116
117severitymaps:
118 severitymap
119 | severitymaps severitymap
120 | error { mc_fatal ("severity ident missing"); }
121;
122
123severitymap:
124 token '=' MCNUMBER alias_name
125 {
126 mc_add_keyword ($1, MCTOKEN, "severity", $3, $4);
127 }
128 | token '=' error { mc_fatal ("severity number missing"); }
129 | token error { mc_fatal ("severity missing '='"); }
130;
131
132facilitymaps:
133 facilitymap
134 | facilitymaps facilitymap
135 | error { mc_fatal ("missing ident in FacilityNames"); }
136;
137
138facilitymap:
139 token '=' MCNUMBER alias_name
140 {
141 mc_add_keyword ($1, MCTOKEN, "facility", $3, $4);
142 }
143 | token '=' error { mc_fatal ("facility number missing"); }
144 | token error { mc_fatal ("facility missing '='"); }
145;
146
147langmaps:
148 langmap
149 | langmaps langmap
150 | error { mc_fatal ("missing ident in LanguageNames"); }
151;
152
153langmap:
154 token '=' MCNUMBER lex_want_filename ':' MCFILENAME
155 {
156 mc_add_keyword ($1, MCTOKEN, "language", $3, $6);
157 }
158 | token '=' MCNUMBER lex_want_filename ':' error { mc_fatal ("missing filename in LanguageNames"); }
159 | token '=' MCNUMBER error { mc_fatal ("missing ':' in LanguageNames"); }
160 | token '=' error { mc_fatal ("missing language code in LanguageNames"); }
161 | token error { mc_fatal ("missing '=' for LanguageNames"); }
162;
163
164alias_name:
165 /* empty */
166 {
167 $$ = NULL;
168 }
169 | ':' MCIDENT
170 {
171 $$ = $2;
172 }
173 | ':' error { mc_fatal ("illegal token in identifier"); $$ = NULL; }
174;
175
176message:
177 id sefasy_def
178 {
179 cur_node = mc_add_node ();
180 cur_node->symbol = mc_last_symbol;
181 cur_node->facility = mc_cur_facility;
182 cur_node->severity = mc_cur_severity;
183 cur_node->id = ($1 & 0xffffUL);
184 cur_node->vid = ($1 & 0xffffUL) | mc_sefa_val;
185 mc_last_id = $1;
186 }
187 lang_entities
188;
189
190id: MCMESSAGEID '=' vid { $$ = $3; }
191 | MCMESSAGEID '=' error { mc_fatal ("missing number in MessageId"); $$ = 0; }
192 | MCMESSAGEID error { mc_fatal ("missing '=' for MessageId"); $$ = 0; }
193;
194
195vid: /* empty */
196 {
197 $$ = ++mc_last_id;
198 }
199 | MCNUMBER
200 {
201 $$ = $1;
202 }
203 | '+' MCNUMBER
204 {
205 $$ = mc_last_id + $2;
206 }
207 | '+' error { mc_fatal ("missing number after MessageId '+'"); }
208;
209
210sefasy_def:
211 /* empty */
212 {
213 $$ = 0;
214 mc_sefa_val = (mcset_custom_bit ? 1 : 0) << 29;
215 mc_last_symbol = NULL;
216 mc_cur_severity = NULL;
217 mc_cur_facility = NULL;
218 }
219 | sefasy_def severity
220 {
221 if ($1 & 1)
222 mc_warn (_("duplicate definition of Severity"));
223 $$ = $1 | 1;
224 }
225 | sefasy_def facility
226 {
227 if ($1 & 2)
228 mc_warn (_("duplicate definition of Facility"));
229 $$ = $1 | 2;
230 }
231 | sefasy_def symbol
232 {
233 if ($1 & 4)
234 mc_warn (_("duplicate definition of SymbolicName"));
235 $$ = $1 | 4;
236 }
237;
238
239severity: MCSEVERITY '=' MCTOKEN
240 {
241 mc_sefa_val &= ~ (0x3UL << 30);
242 mc_sefa_val |= (($3->nval & 0x3UL) << 30);
243 mc_cur_severity = $3;
244 }
245;
246
247facility: MCFACILITY '=' MCTOKEN
248 {
249 mc_sefa_val &= ~ (0xfffUL << 16);
250 mc_sefa_val |= (($3->nval & 0xfffUL) << 16);
251 mc_cur_facility = $3;
252 }
253;
254
255symbol: MCSYMBOLICNAME '=' MCIDENT
256 {
257 mc_last_symbol = $3;
258 }
259;
260
261lang_entities:
262 lang_entity
263 | lang_entities lang_entity
264;
265
266lang_entity:
267 lang lex_want_line lines MCENDLINE
268 {
269 mc_node_lang *h;
270 h = mc_add_node_lang (cur_node, $1, cur_node->vid);
271 h->message = $3;
272 if (mcset_max_message_length != 0 && unichar_len (h->message) > mcset_max_message_length)
273 mc_warn ("message length to long");
274 }
275;
276
277lines: MCLINE
278 {
279 $$ = $1;
280 }
281 | lines MCLINE
282 {
283 unichar *h;
284 rc_uint_type l1,l2;
285 l1 = unichar_len ($1);
286 l2 = unichar_len ($2);
287 h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
288 if (l1) memcpy (h, $1, l1 * sizeof (unichar));
289 if (l2) memcpy (&h[l1], $2, l2 * sizeof (unichar));
290 h[l1 + l2] = 0;
291 $$ = h;
292 }
293 | error { mc_fatal ("missing end of message text"); $$ = NULL; }
294 | lines error { mc_fatal ("missing end of message text"); $$ = $1; }
295;
296
297comments: MCCOMMENT { $$ = $1; }
298 | comments MCCOMMENT
299 {
300 unichar *h;
301 rc_uint_type l1,l2;
302 l1 = unichar_len ($1);
303 l2 = unichar_len ($2);
304 h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
305 if (l1) memcpy (h, $1, l1 * sizeof (unichar));
306 if (l2) memcpy (&h[l1], $2, l2 * sizeof (unichar));
307 h[l1 + l2] = 0;
308 $$ = h;
309 }
310;
311
312lang: MCLANGUAGE lex_want_nl '=' MCTOKEN NL
313 {
314 $$ = $4;
315 }
316 | MCLANGUAGE lex_want_nl '=' MCIDENT NL
317 {
318 $$ = NULL;
319 mc_fatal (_("undeclared language identifier"));
320 }
321 | MCLANGUAGE lex_want_nl '=' token error
322 {
323 $$ = NULL;
324 mc_fatal ("missing newline after Language");
325 }
326 | MCLANGUAGE lex_want_nl '=' error
327 {
328 $$ = NULL;
329 mc_fatal ("missing ident for Language");
330 }
331 | MCLANGUAGE error
332 {
333 $$ = NULL;
334 mc_fatal ("missing '=' for Language");
335 }
336;
337
338token: MCIDENT { $$ = $1; }
339 | MCTOKEN { $$ = $1->usz; }
340;
341
342lex_want_nl:
343 /* Empty */ { mclex_want_nl = 1; }
344;
345
346lex_want_line:
347 /* Empty */ { mclex_want_line = 1; }
348;
349
350lex_want_filename:
351 /* Empty */ { mclex_want_filename = 1; }
352;
353
354%%
355
356/* Something else. */