]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/mcparse.y
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / binutils / mcparse.y
CommitLineData
692ed3e7 1%{ /* mcparse.y -- parser for Windows mc files
fd67aa11 2 Copyright (C) 2007-2024 Free Software Foundation, Inc.
3aade688 3
692ed3e7
NC
4 Parser for Windows mc files
5 Written by Kai Tietz, Onevision.
3aade688 6
692ed3e7 7 This file is part of GNU Binutils.
3aade688 8
692ed3e7
NC
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
692ed3e7 12 (at your option) any later version.
3aade688 13
692ed3e7
NC
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
3aade688 18
692ed3e7
NC
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
23
24/* This is a parser for Windows rc files. It is based on the parser
25 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
26
27#include "sysdep.h"
28#include "bfd.h"
29#include "bucomm.h"
30#include "libiberty.h"
31#include "windmc.h"
32#include "safe-ctype.h"
33
34static rc_uint_type mc_last_id = 0;
35static rc_uint_type mc_sefa_val = 0;
36static unichar *mc_last_symbol = NULL;
37static const mc_keyword *mc_cur_severity = NULL;
38static const mc_keyword *mc_cur_facility = NULL;
39static mc_node *cur_node = NULL;
40
41%}
42
43%union
44{
45 rc_uint_type ival;
46 unichar *ustr;
47 const mc_keyword *tok;
48 mc_node *nod;
49};
50
51%start input
52
53%token NL
54%token<ustr> MCIDENT MCFILENAME MCLINE MCCOMMENT
55%token<tok> MCTOKEN
56%token MCENDLINE
57%token MCLANGUAGENAMES MCFACILITYNAMES MCSEVERITYNAMES MCOUTPUTBASE MCMESSAGEIDTYPEDEF
58%token MCLANGUAGE MCMESSAGEID MCSEVERITY MCFACILITY MCSYMBOLICNAME
59%token <ival> MCNUMBER
60
61%type<ival> id vid sefasy_def
62%type<ustr> alias_name token lines comments
63%type<tok> lang
64
65%%
66input: entities
67 ;
68
69entities:
70 /* empty */
71 | entities entity
72 ;
73entity: global_section
74 | message
75 | comments
76 {
77 cur_node = mc_add_node ();
78 cur_node->user_text = $1;
79 }
80 | error { mc_fatal ("syntax error"); }
81;
82
83global_section:
84 MCSEVERITYNAMES '=' '(' severitymaps ')'
85 | MCSEVERITYNAMES '=' '(' severitymaps error { mc_fatal ("missing ')' in SeverityNames"); }
86 | MCSEVERITYNAMES '=' error { mc_fatal ("missing '(' in SeverityNames"); }
87 | MCSEVERITYNAMES error { mc_fatal ("missing '=' for SeverityNames"); }
88 | MCLANGUAGENAMES '=' '(' langmaps ')'
89 | MCLANGUAGENAMES '=' '(' langmaps error { mc_fatal ("missing ')' in LanguageNames"); }
90 | MCLANGUAGENAMES '=' error { mc_fatal ("missing '(' in LanguageNames"); }
91 | MCLANGUAGENAMES error { mc_fatal ("missing '=' for LanguageNames"); }
92 | MCFACILITYNAMES '=' '(' facilitymaps ')'
93 | MCFACILITYNAMES '=' '(' facilitymaps error { mc_fatal ("missing ')' in FacilityNames"); }
94 | MCFACILITYNAMES '=' error { mc_fatal ("missing '(' in FacilityNames"); }
95 | MCFACILITYNAMES error { mc_fatal ("missing '=' for FacilityNames"); }
96 | MCOUTPUTBASE '=' MCNUMBER
97 {
98 if ($3 != 10 && $3 != 16)
99 mc_fatal ("OutputBase allows 10 or 16 as value");
100 mcset_out_values_are_decimal = ($3 == 10 ? 1 : 0);
101 }
102 | MCMESSAGEIDTYPEDEF '=' MCIDENT
103 {
104 mcset_msg_id_typedef = $3;
105 }
106 | MCMESSAGEIDTYPEDEF '=' error
107 {
108 mc_fatal ("MessageIdTypedef expects an identifier");
109 }
110 | MCMESSAGEIDTYPEDEF error
111 {
112 mc_fatal ("missing '=' for MessageIdTypedef");
113 }
114;
115
116severitymaps:
117 severitymap
118 | severitymaps severitymap
119 | error { mc_fatal ("severity ident missing"); }
120;
121
122severitymap:
123 token '=' MCNUMBER alias_name
124 {
125 mc_add_keyword ($1, MCTOKEN, "severity", $3, $4);
126 }
127 | token '=' error { mc_fatal ("severity number missing"); }
128 | token error { mc_fatal ("severity missing '='"); }
129;
130
131facilitymaps:
132 facilitymap
133 | facilitymaps facilitymap
134 | error { mc_fatal ("missing ident in FacilityNames"); }
135;
136
137facilitymap:
138 token '=' MCNUMBER alias_name
139 {
140 mc_add_keyword ($1, MCTOKEN, "facility", $3, $4);
141 }
142 | token '=' error { mc_fatal ("facility number missing"); }
143 | token error { mc_fatal ("facility missing '='"); }
144;
145
146langmaps:
147 langmap
148 | langmaps langmap
149 | error { mc_fatal ("missing ident in LanguageNames"); }
150;
151
152langmap:
153 token '=' MCNUMBER lex_want_filename ':' MCFILENAME
154 {
155 mc_add_keyword ($1, MCTOKEN, "language", $3, $6);
156 }
157 | token '=' MCNUMBER lex_want_filename ':' error { mc_fatal ("missing filename in LanguageNames"); }
158 | token '=' MCNUMBER error { mc_fatal ("missing ':' in LanguageNames"); }
159 | token '=' error { mc_fatal ("missing language code in LanguageNames"); }
160 | token error { mc_fatal ("missing '=' for LanguageNames"); }
161;
162
163alias_name:
164 /* empty */
165 {
166 $$ = NULL;
167 }
168 | ':' MCIDENT
169 {
170 $$ = $2;
171 }
172 | ':' error { mc_fatal ("illegal token in identifier"); $$ = NULL; }
173;
174
175message:
176 id sefasy_def
177 {
178 cur_node = mc_add_node ();
179 cur_node->symbol = mc_last_symbol;
180 cur_node->facility = mc_cur_facility;
181 cur_node->severity = mc_cur_severity;
182 cur_node->id = ($1 & 0xffffUL);
183 cur_node->vid = ($1 & 0xffffUL) | mc_sefa_val;
913e0fd4 184 cur_node->id_typecast = mcset_msg_id_typedef;
692ed3e7
NC
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. */