daily update
[deliverable/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
12 the Free Software Foundation; either version 2 of the License, or
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. */
This page took 0.036275 seconds and 4 git commands to generate.