2005-01-19 Fred Fish <fnf@specifixinc.com>
[deliverable/binutils-gdb.git] / binutils / rcparse.y
1 %{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005
3 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor, Cygnus Support.
5
6 This file is part of GNU Binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
22
23 /* This is a parser for Windows rc files. It is based on the parser
24 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
25
26 #include "bfd.h"
27 #include "bucomm.h"
28 #include "libiberty.h"
29 #include "windres.h"
30 #include "safe-ctype.h"
31
32 /* The current language. */
33
34 static unsigned short language;
35
36 /* The resource information during a sub statement. */
37
38 static struct res_res_info sub_res_info;
39
40 /* Dialog information. This is built by the nonterminals styles and
41 controls. */
42
43 static struct dialog dialog;
44
45 /* This is used when building a style. It is modified by the
46 nonterminal styleexpr. */
47
48 static unsigned long style;
49
50 /* These are used when building a control. They are set before using
51 control_params. */
52
53 static unsigned long base_style;
54 static unsigned long default_style;
55 static unsigned long class;
56 static struct res_id res_text_field;
57
58 /* This is used for COMBOBOX, LISTBOX and EDITTEXT which
59 do not allow resource 'text' field in control definition. */
60 static const struct res_id res_null_text = { 1, {{0, L""}}};
61
62 %}
63
64 %union
65 {
66 struct accelerator acc;
67 struct accelerator *pacc;
68 struct dialog_control *dialog_control;
69 struct menuitem *menuitem;
70 struct
71 {
72 struct rcdata_item *first;
73 struct rcdata_item *last;
74 } rcdata;
75 struct rcdata_item *rcdata_item;
76 struct stringtable_data *stringtable;
77 struct fixed_versioninfo *fixver;
78 struct ver_info *verinfo;
79 struct ver_stringinfo *verstring;
80 struct ver_varinfo *vervar;
81 struct res_id id;
82 struct res_res_info res_info;
83 struct
84 {
85 unsigned short on;
86 unsigned short off;
87 } memflags;
88 struct
89 {
90 unsigned long val;
91 /* Nonzero if this number was explicitly specified as long. */
92 int dword;
93 } i;
94 unsigned long il;
95 unsigned short is;
96 const char *s;
97 struct
98 {
99 unsigned long length;
100 const char *s;
101 } ss;
102 };
103
104 %token BEG END
105 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
106 %token BITMAP
107 %token CURSOR
108 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
109 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
110 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
111 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
112 %token BEDIT HEDIT IEDIT
113 %token FONT
114 %token ICON
115 %token LANGUAGE CHARACTERISTICS VERSIONK
116 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
117 %token MENUBARBREAK MENUBREAK
118 %token MESSAGETABLE
119 %token RCDATA
120 %token STRINGTABLE
121 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
122 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
123 %token VALUE
124 %token <s> BLOCK
125 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
126 %token NOT
127 %token <s> QUOTEDSTRING STRING
128 %token <i> NUMBER
129 %token <ss> SIZEDSTRING
130 %token IGNORED_TOKEN
131
132 %type <pacc> acc_entries
133 %type <acc> acc_entry acc_event
134 %type <dialog_control> control control_params
135 %type <menuitem> menuitems menuitem menuexitems menuexitem
136 %type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
137 %type <rcdata_item> opt_control_data
138 %type <fixver> fixedverinfo
139 %type <verinfo> verblocks
140 %type <verstring> vervals
141 %type <vervar> vertrans
142 %type <res_info> suboptions memflags_move_discard memflags_move
143 %type <memflags> memflag
144 %type <id> id optresidc resref
145 %type <il> exstyle parennumber
146 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
147 %type <is> acc_options acc_option menuitem_flags menuitem_flag
148 %type <s> file_name resname
149 %type <i> sizednumexpr sizedposnumexpr
150
151 %left '|'
152 %left '^'
153 %left '&'
154 %left '+' '-'
155 %left '*' '/' '%'
156 %right '~' NEG
157
158 %%
159
160 input:
161 /* empty */
162 | input accelerator
163 | input bitmap
164 | input cursor
165 | input dialog
166 | input font
167 | input icon
168 | input language
169 | input menu
170 | input menuex
171 | input messagetable
172 | input rcdata
173 | input stringtable
174 | input user
175 | input versioninfo
176 | input IGNORED_TOKEN
177 ;
178
179 /* Accelerator resources. */
180
181 accelerator:
182 id ACCELERATORS suboptions BEG acc_entries END
183 {
184 define_accelerator ($1, &$3, $5);
185 if (yychar != YYEMPTY)
186 YYERROR;
187 rcparse_discard_strings ();
188 }
189 ;
190
191 acc_entries:
192 /* empty */
193 {
194 $$ = NULL;
195 }
196 | acc_entries acc_entry
197 {
198 struct accelerator *a;
199
200 a = (struct accelerator *) res_alloc (sizeof *a);
201 *a = $2;
202 if ($1 == NULL)
203 $$ = a;
204 else
205 {
206 struct accelerator **pp;
207
208 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
209 ;
210 *pp = a;
211 $$ = $1;
212 }
213 }
214 ;
215
216 acc_entry:
217 acc_event cposnumexpr
218 {
219 $$ = $1;
220 $$.id = $2;
221 }
222 | acc_event cposnumexpr ',' acc_options
223 {
224 $$ = $1;
225 $$.id = $2;
226 $$.flags |= $4;
227 if (($$.flags & ACC_VIRTKEY) == 0
228 && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
229 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
230 }
231 ;
232
233 acc_event:
234 QUOTEDSTRING
235 {
236 const char *s = $1;
237 char ch;
238
239 $$.next = NULL;
240 $$.id = 0;
241 ch = *s;
242 if (ch != '^')
243 $$.flags = 0;
244 else
245 {
246 $$.flags = ACC_CONTROL | ACC_VIRTKEY;
247 ++s;
248 ch = *s;
249 ch = TOUPPER (ch);
250 }
251 $$.key = ch;
252 if (s[1] != '\0')
253 rcparse_warning (_("accelerator should only be one character"));
254 }
255 | posnumexpr
256 {
257 $$.next = NULL;
258 $$.flags = 0;
259 $$.id = 0;
260 $$.key = $1;
261 }
262 ;
263
264 acc_options:
265 acc_option
266 {
267 $$ = $1;
268 }
269 | acc_options ',' acc_option
270 {
271 $$ = $1 | $3;
272 }
273 /* I've had one report that the comma is optional. */
274 | acc_options acc_option
275 {
276 $$ = $1 | $2;
277 }
278 ;
279
280 acc_option:
281 VIRTKEY
282 {
283 $$ = ACC_VIRTKEY;
284 }
285 | ASCII
286 {
287 /* This is just the absence of VIRTKEY. */
288 $$ = 0;
289 }
290 | NOINVERT
291 {
292 $$ = ACC_NOINVERT;
293 }
294 | SHIFT
295 {
296 $$ = ACC_SHIFT;
297 }
298 | CONTROL
299 {
300 $$ = ACC_CONTROL;
301 }
302 | ALT
303 {
304 $$ = ACC_ALT;
305 }
306 ;
307
308 /* Bitmap resources. */
309
310 bitmap:
311 id BITMAP memflags_move file_name
312 {
313 define_bitmap ($1, &$3, $4);
314 if (yychar != YYEMPTY)
315 YYERROR;
316 rcparse_discard_strings ();
317 }
318 ;
319
320 /* Cursor resources. */
321
322 cursor:
323 id CURSOR memflags_move_discard file_name
324 {
325 define_cursor ($1, &$3, $4);
326 if (yychar != YYEMPTY)
327 YYERROR;
328 rcparse_discard_strings ();
329 }
330 ;
331
332 /* Dialog resources. */
333
334 dialog:
335 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
336 cnumexpr
337 {
338 memset (&dialog, 0, sizeof dialog);
339 dialog.x = $5;
340 dialog.y = $6;
341 dialog.width = $7;
342 dialog.height = $8;
343 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
344 dialog.exstyle = $4;
345 dialog.menu.named = 1;
346 dialog.class.named = 1;
347 dialog.font = NULL;
348 dialog.ex = NULL;
349 dialog.controls = NULL;
350 sub_res_info = $3;
351 style = 0;
352 }
353 styles BEG controls END
354 {
355 define_dialog ($1, &sub_res_info, &dialog);
356 if (yychar != YYEMPTY)
357 YYERROR;
358 rcparse_discard_strings ();
359 }
360 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
361 cnumexpr
362 {
363 memset (&dialog, 0, sizeof dialog);
364 dialog.x = $5;
365 dialog.y = $6;
366 dialog.width = $7;
367 dialog.height = $8;
368 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
369 dialog.exstyle = $4;
370 dialog.menu.named = 1;
371 dialog.class.named = 1;
372 dialog.font = NULL;
373 dialog.ex = ((struct dialog_ex *)
374 res_alloc (sizeof (struct dialog_ex)));
375 memset (dialog.ex, 0, sizeof (struct dialog_ex));
376 dialog.controls = NULL;
377 sub_res_info = $3;
378 style = 0;
379 }
380 styles BEG controls END
381 {
382 define_dialog ($1, &sub_res_info, &dialog);
383 if (yychar != YYEMPTY)
384 YYERROR;
385 rcparse_discard_strings ();
386 }
387 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
388 cnumexpr cnumexpr
389 {
390 memset (&dialog, 0, sizeof dialog);
391 dialog.x = $5;
392 dialog.y = $6;
393 dialog.width = $7;
394 dialog.height = $8;
395 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
396 dialog.exstyle = $4;
397 dialog.menu.named = 1;
398 dialog.class.named = 1;
399 dialog.font = NULL;
400 dialog.ex = ((struct dialog_ex *)
401 res_alloc (sizeof (struct dialog_ex)));
402 memset (dialog.ex, 0, sizeof (struct dialog_ex));
403 dialog.ex->help = $9;
404 dialog.controls = NULL;
405 sub_res_info = $3;
406 style = 0;
407 }
408 styles BEG controls END
409 {
410 define_dialog ($1, &sub_res_info, &dialog);
411 if (yychar != YYEMPTY)
412 YYERROR;
413 rcparse_discard_strings ();
414 }
415 ;
416
417 exstyle:
418 /* empty */
419 {
420 $$ = 0;
421 }
422 | EXSTYLE '=' numexpr
423 {
424 $$ = $3;
425 }
426 ;
427
428 styles:
429 /* empty */
430 | styles CAPTION QUOTEDSTRING
431 {
432 dialog.style |= WS_CAPTION;
433 style |= WS_CAPTION;
434 unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
435 }
436 | styles CLASS id
437 {
438 dialog.class = $3;
439 }
440 | styles STYLE
441 styleexpr
442 {
443 dialog.style = style;
444 }
445 | styles EXSTYLE numexpr
446 {
447 dialog.exstyle = $3;
448 }
449 | styles CLASS QUOTEDSTRING
450 {
451 res_string_to_id (& dialog.class, $3);
452 }
453 | styles FONT numexpr ',' QUOTEDSTRING
454 {
455 dialog.style |= DS_SETFONT;
456 style |= DS_SETFONT;
457 dialog.pointsize = $3;
458 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
459 if (dialog.ex != NULL)
460 {
461 dialog.ex->weight = 0;
462 dialog.ex->italic = 0;
463 dialog.ex->charset = 1;
464 }
465 }
466 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr
467 {
468 dialog.style |= DS_SETFONT;
469 style |= DS_SETFONT;
470 dialog.pointsize = $3;
471 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
472 if (dialog.ex == NULL)
473 rcparse_warning (_("extended FONT requires DIALOGEX"));
474 else
475 {
476 dialog.ex->weight = $6;
477 dialog.ex->italic = 0;
478 dialog.ex->charset = 1;
479 }
480 }
481 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
482 {
483 dialog.style |= DS_SETFONT;
484 style |= DS_SETFONT;
485 dialog.pointsize = $3;
486 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
487 if (dialog.ex == NULL)
488 rcparse_warning (_("extended FONT requires DIALOGEX"));
489 else
490 {
491 dialog.ex->weight = $6;
492 dialog.ex->italic = $7;
493 dialog.ex->charset = 1;
494 }
495 }
496 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr cnumexpr
497 {
498 dialog.style |= DS_SETFONT;
499 style |= DS_SETFONT;
500 dialog.pointsize = $3;
501 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
502 if (dialog.ex == NULL)
503 rcparse_warning (_("extended FONT requires DIALOGEX"));
504 else
505 {
506 dialog.ex->weight = $6;
507 dialog.ex->italic = $7;
508 dialog.ex->charset = $8;
509 }
510 }
511 | styles MENU id
512 {
513 dialog.menu = $3;
514 }
515 | styles CHARACTERISTICS numexpr
516 {
517 sub_res_info.characteristics = $3;
518 }
519 | styles LANGUAGE numexpr cnumexpr
520 {
521 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
522 }
523 | styles VERSIONK numexpr
524 {
525 sub_res_info.version = $3;
526 }
527 ;
528
529 controls:
530 /* empty */
531 | controls control
532 {
533 struct dialog_control **pp;
534
535 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
536 ;
537 *pp = $2;
538 }
539 ;
540
541 control:
542 AUTO3STATE optresidc
543 {
544 default_style = BS_AUTO3STATE | WS_TABSTOP;
545 base_style = BS_AUTO3STATE;
546 class = CTL_BUTTON;
547 res_text_field = $2;
548 }
549 control_params
550 {
551 $$ = $4;
552 }
553 | AUTOCHECKBOX optresidc
554 {
555 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
556 base_style = BS_AUTOCHECKBOX;
557 class = CTL_BUTTON;
558 res_text_field = $2;
559 }
560 control_params
561 {
562 $$ = $4;
563 }
564 | AUTORADIOBUTTON optresidc
565 {
566 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
567 base_style = BS_AUTORADIOBUTTON;
568 class = CTL_BUTTON;
569 res_text_field = $2;
570 }
571 control_params
572 {
573 $$ = $4;
574 }
575 | BEDIT optresidc
576 {
577 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
578 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
579 class = CTL_EDIT;
580 res_text_field = $2;
581 }
582 control_params
583 {
584 $$ = $4;
585 if (dialog.ex == NULL)
586 rcparse_warning (_("BEDIT requires DIALOGEX"));
587 res_string_to_id (&$$->class, "BEDIT");
588 }
589 | CHECKBOX optresidc
590 {
591 default_style = BS_CHECKBOX | WS_TABSTOP;
592 base_style = BS_CHECKBOX | WS_TABSTOP;
593 class = CTL_BUTTON;
594 res_text_field = $2;
595 }
596 control_params
597 {
598 $$ = $4;
599 }
600 | COMBOBOX
601 {
602 /* This is as per MSDN documentation. With some (???)
603 versions of MS rc.exe their is no default style. */
604 default_style = CBS_SIMPLE | WS_TABSTOP;
605 base_style = 0;
606 class = CTL_COMBOBOX;
607 res_text_field = res_null_text;
608 }
609 control_params
610 {
611 $$ = $3;
612 }
613 | CONTROL optresidc numexpr cnumexpr control_styleexpr cnumexpr
614 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
615 {
616 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
617 if ($11 != NULL)
618 {
619 if (dialog.ex == NULL)
620 rcparse_warning (_("control data requires DIALOGEX"));
621 $$->data = $11;
622 }
623 }
624 | CONTROL optresidc numexpr cnumexpr control_styleexpr cnumexpr
625 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
626 {
627 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
628 if (dialog.ex == NULL)
629 rcparse_warning (_("help ID requires DIALOGEX"));
630 $$->help = $11;
631 $$->data = $12;
632 }
633 | CONTROL optresidc numexpr ',' QUOTEDSTRING control_styleexpr
634 cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
635 {
636 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
637 if ($12 != NULL)
638 {
639 if (dialog.ex == NULL)
640 rcparse_warning ("control data requires DIALOGEX");
641 $$->data = $12;
642 }
643 $$->class.named = 1;
644 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
645 }
646 | CONTROL optresidc numexpr ',' QUOTEDSTRING control_styleexpr
647 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
648 {
649 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
650 if (dialog.ex == NULL)
651 rcparse_warning ("help ID requires DIALOGEX");
652 $$->help = $12;
653 $$->data = $13;
654 $$->class.named = 1;
655 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
656 }
657 | CTEXT optresidc
658 {
659 default_style = SS_CENTER | WS_GROUP;
660 base_style = SS_CENTER;
661 class = CTL_STATIC;
662 res_text_field = $2;
663 }
664 control_params
665 {
666 $$ = $4;
667 }
668 | DEFPUSHBUTTON optresidc
669 {
670 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
671 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
672 class = CTL_BUTTON;
673 res_text_field = $2;
674 }
675 control_params
676 {
677 $$ = $4;
678 }
679 | EDITTEXT
680 {
681 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
682 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
683 class = CTL_EDIT;
684 res_text_field = res_null_text;
685 }
686 control_params
687 {
688 $$ = $3;
689 }
690 | GROUPBOX optresidc
691 {
692 default_style = BS_GROUPBOX;
693 base_style = BS_GROUPBOX;
694 class = CTL_BUTTON;
695 res_text_field = $2;
696 }
697 control_params
698 {
699 $$ = $4;
700 }
701 | HEDIT optresidc
702 {
703 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
704 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
705 class = CTL_EDIT;
706 res_text_field = $2;
707 }
708 control_params
709 {
710 $$ = $4;
711 if (dialog.ex == NULL)
712 rcparse_warning (_("IEDIT requires DIALOGEX"));
713 res_string_to_id (&$$->class, "HEDIT");
714 }
715 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
716 {
717 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
718 dialog.ex);
719 }
720 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
721 opt_control_data
722 {
723 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
724 dialog.ex);
725 }
726 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
727 icon_styleexpr optcnumexpr opt_control_data
728 {
729 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
730 dialog.ex);
731 }
732 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
733 icon_styleexpr cnumexpr cnumexpr opt_control_data
734 {
735 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
736 dialog.ex);
737 }
738 | IEDIT optresidc
739 {
740 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
741 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
742 class = CTL_EDIT;
743 res_text_field = $2;
744 }
745 control_params
746 {
747 $$ = $4;
748 if (dialog.ex == NULL)
749 rcparse_warning (_("IEDIT requires DIALOGEX"));
750 res_string_to_id (&$$->class, "IEDIT");
751 }
752 | LISTBOX
753 {
754 default_style = LBS_NOTIFY | WS_BORDER;
755 base_style = LBS_NOTIFY | WS_BORDER;
756 class = CTL_LISTBOX;
757 res_text_field = res_null_text;
758 }
759 control_params
760 {
761 $$ = $3;
762 }
763 | LTEXT optresidc
764 {
765 default_style = SS_LEFT | WS_GROUP;
766 base_style = SS_LEFT;
767 class = CTL_STATIC;
768 res_text_field = $2;
769 }
770 control_params
771 {
772 $$ = $4;
773 }
774 | PUSHBOX optresidc
775 {
776 default_style = BS_PUSHBOX | WS_TABSTOP;
777 base_style = BS_PUSHBOX;
778 class = CTL_BUTTON;
779 }
780 control_params
781 {
782 $$ = $4;
783 }
784 | PUSHBUTTON optresidc
785 {
786 default_style = BS_PUSHBUTTON | WS_TABSTOP;
787 base_style = BS_PUSHBUTTON | WS_TABSTOP;
788 class = CTL_BUTTON;
789 res_text_field = $2;
790 }
791 control_params
792 {
793 $$ = $4;
794 }
795 | RADIOBUTTON optresidc
796 {
797 default_style = BS_RADIOBUTTON | WS_TABSTOP;
798 base_style = BS_RADIOBUTTON;
799 class = CTL_BUTTON;
800 res_text_field = $2;
801 }
802 control_params
803 {
804 $$ = $4;
805 }
806 | RTEXT optresidc
807 {
808 default_style = SS_RIGHT | WS_GROUP;
809 base_style = SS_RIGHT;
810 class = CTL_STATIC;
811 res_text_field = $2;
812 }
813 control_params
814 {
815 $$ = $4;
816 }
817 | SCROLLBAR
818 {
819 default_style = SBS_HORZ;
820 base_style = 0;
821 class = CTL_SCROLLBAR;
822 res_text_field = res_null_text;
823 }
824 control_params
825 {
826 $$ = $3;
827 }
828 | STATE3 optresidc
829 {
830 default_style = BS_3STATE | WS_TABSTOP;
831 base_style = BS_3STATE;
832 class = CTL_BUTTON;
833 res_text_field = $2;
834 }
835 control_params
836 {
837 $$ = $4;
838 }
839 | USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
840 numexpr ',' numexpr ','
841 { style = WS_CHILD | WS_VISIBLE; }
842 styleexpr optcnumexpr
843 {
844 $$ = define_control ($2, $3, $5, $7, $9, $11, CTL_BUTTON,
845 style, $15);
846 }
847 ;
848
849 /* Parameters for a control. The static variables DEFAULT_STYLE,
850 BASE_STYLE, and CLASS must be initialized before this nonterminal
851 is used. DEFAULT_STYLE is the style to use if no style expression
852 is specified. BASE_STYLE is the base style to use if a style
853 expression is specified; the style expression modifies the base
854 style. CLASS is the class of the control. */
855
856 control_params:
857 numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
858 {
859 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class,
860 default_style | WS_CHILD | WS_VISIBLE, 0);
861 if ($6 != NULL)
862 {
863 if (dialog.ex == NULL)
864 rcparse_warning (_("control data requires DIALOGEX"));
865 $$->data = $6;
866 }
867 }
868 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
869 control_params_styleexpr optcnumexpr opt_control_data
870 {
871 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
872 if ($8 != NULL)
873 {
874 if (dialog.ex == NULL)
875 rcparse_warning (_("control data requires DIALOGEX"));
876 $$->data = $8;
877 }
878 }
879 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
880 control_params_styleexpr cnumexpr cnumexpr opt_control_data
881 {
882 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
883 if (dialog.ex == NULL)
884 rcparse_warning (_("help ID requires DIALOGEX"));
885 $$->help = $8;
886 $$->data = $9;
887 }
888 ;
889
890 optresidc:
891 /* empty */
892 {
893 res_string_to_id (&$$, "");
894 }
895 | posnumexpr ','
896 {
897 $$.named = 0;
898 $$.u.id = $1;
899 }
900 | QUOTEDSTRING
901 {
902 res_string_to_id (&$$, $1);
903 }
904 | QUOTEDSTRING ','
905 {
906 res_string_to_id (&$$, $1);
907 }
908 ;
909
910 opt_control_data:
911 /* empty */
912 {
913 $$ = NULL;
914 }
915 | BEG optrcdata_data END
916 {
917 $$ = $2.first;
918 }
919 ;
920
921 /* These only exist to parse a reduction out of a common case. */
922
923 control_styleexpr:
924 ','
925 { style = WS_CHILD | WS_VISIBLE; }
926 styleexpr
927 ;
928
929 icon_styleexpr:
930 ','
931 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
932 styleexpr
933 ;
934
935 control_params_styleexpr:
936 ','
937 { style = base_style | WS_CHILD | WS_VISIBLE; }
938 styleexpr
939 ;
940
941 /* Font resources. */
942
943 font:
944 id FONT memflags_move_discard file_name
945 {
946 define_font ($1, &$3, $4);
947 if (yychar != YYEMPTY)
948 YYERROR;
949 rcparse_discard_strings ();
950 }
951 ;
952
953 /* Icon resources. */
954
955 icon:
956 id ICON memflags_move_discard file_name
957 {
958 define_icon ($1, &$3, $4);
959 if (yychar != YYEMPTY)
960 YYERROR;
961 rcparse_discard_strings ();
962 }
963 ;
964
965 /* Language command. This changes the static variable language, which
966 affects all subsequent resources. */
967
968 language:
969 LANGUAGE numexpr cnumexpr
970 {
971 language = $2 | ($3 << SUBLANG_SHIFT);
972 }
973 ;
974
975 /* Menu resources. */
976
977 menu:
978 id MENU suboptions BEG menuitems END
979 {
980 define_menu ($1, &$3, $5);
981 if (yychar != YYEMPTY)
982 YYERROR;
983 rcparse_discard_strings ();
984 }
985 ;
986
987 menuitems:
988 /* empty */
989 {
990 $$ = NULL;
991 }
992 | menuitems menuitem
993 {
994 if ($1 == NULL)
995 $$ = $2;
996 else
997 {
998 struct menuitem **pp;
999
1000 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1001 ;
1002 *pp = $2;
1003 $$ = $1;
1004 }
1005 }
1006 ;
1007
1008 menuitem:
1009 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
1010 {
1011 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
1012 }
1013 | MENUITEM SEPARATOR
1014 {
1015 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1016 }
1017 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
1018 {
1019 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
1020 }
1021 ;
1022
1023 menuitem_flags:
1024 /* empty */
1025 {
1026 $$ = 0;
1027 }
1028 | menuitem_flags ',' menuitem_flag
1029 {
1030 $$ = $1 | $3;
1031 }
1032 | menuitem_flags menuitem_flag
1033 {
1034 $$ = $1 | $2;
1035 }
1036 ;
1037
1038 menuitem_flag:
1039 CHECKED
1040 {
1041 $$ = MENUITEM_CHECKED;
1042 }
1043 | GRAYED
1044 {
1045 $$ = MENUITEM_GRAYED;
1046 }
1047 | HELP
1048 {
1049 $$ = MENUITEM_HELP;
1050 }
1051 | INACTIVE
1052 {
1053 $$ = MENUITEM_INACTIVE;
1054 }
1055 | MENUBARBREAK
1056 {
1057 $$ = MENUITEM_MENUBARBREAK;
1058 }
1059 | MENUBREAK
1060 {
1061 $$ = MENUITEM_MENUBREAK;
1062 }
1063 ;
1064
1065 /* Menuex resources. */
1066
1067 menuex:
1068 id MENUEX suboptions BEG menuexitems END
1069 {
1070 define_menu ($1, &$3, $5);
1071 if (yychar != YYEMPTY)
1072 YYERROR;
1073 rcparse_discard_strings ();
1074 }
1075 ;
1076
1077 menuexitems:
1078 /* empty */
1079 {
1080 $$ = NULL;
1081 }
1082 | menuexitems menuexitem
1083 {
1084 if ($1 == NULL)
1085 $$ = $2;
1086 else
1087 {
1088 struct menuitem **pp;
1089
1090 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1091 ;
1092 *pp = $2;
1093 $$ = $1;
1094 }
1095 }
1096 ;
1097
1098 menuexitem:
1099 MENUITEM QUOTEDSTRING
1100 {
1101 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1102 }
1103 | MENUITEM QUOTEDSTRING cnumexpr
1104 {
1105 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1106 }
1107 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
1108 {
1109 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
1110 }
1111 | MENUITEM SEPARATOR
1112 {
1113 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1114 }
1115 | POPUP QUOTEDSTRING BEG menuexitems END
1116 {
1117 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1118 }
1119 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
1120 {
1121 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1122 }
1123 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
1124 {
1125 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1126 }
1127 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
1128 BEG menuexitems END
1129 {
1130 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1131 }
1132 ;
1133
1134 /* Messagetable resources. */
1135
1136 messagetable:
1137 id MESSAGETABLE memflags_move file_name
1138 {
1139 define_messagetable ($1, &$3, $4);
1140 if (yychar != YYEMPTY)
1141 YYERROR;
1142 rcparse_discard_strings ();
1143 }
1144 ;
1145
1146 /* Rcdata resources. */
1147
1148 rcdata:
1149 id RCDATA suboptions BEG optrcdata_data END
1150 {
1151 define_rcdata ($1, &$3, $5.first);
1152 if (yychar != YYEMPTY)
1153 YYERROR;
1154 rcparse_discard_strings ();
1155 }
1156 | id RCDATA suboptions file_name
1157 {
1158 define_rcdata_file ($1, &$3, $4);
1159 if (yychar != YYEMPTY)
1160 YYERROR;
1161 rcparse_discard_strings ();
1162 }
1163 ;
1164
1165 /* We use a different lexing algorithm, because rcdata strings may
1166 contain embedded null bytes, and we need to know the length to use. */
1167
1168 optrcdata_data:
1169 {
1170 rcparse_rcdata ();
1171 }
1172 optrcdata_data_int
1173 {
1174 rcparse_normal ();
1175 $$ = $2;
1176 }
1177 ;
1178
1179 optrcdata_data_int:
1180 /* empty */
1181 {
1182 $$.first = NULL;
1183 $$.last = NULL;
1184 }
1185 | rcdata_data
1186 {
1187 $$ = $1;
1188 }
1189 ;
1190
1191 rcdata_data:
1192 SIZEDSTRING
1193 {
1194 struct rcdata_item *ri;
1195
1196 ri = define_rcdata_string ($1.s, $1.length);
1197 $$.first = ri;
1198 $$.last = ri;
1199 }
1200 | sizednumexpr
1201 {
1202 struct rcdata_item *ri;
1203
1204 ri = define_rcdata_number ($1.val, $1.dword);
1205 $$.first = ri;
1206 $$.last = ri;
1207 }
1208 | rcdata_data ',' SIZEDSTRING
1209 {
1210 struct rcdata_item *ri;
1211
1212 ri = define_rcdata_string ($3.s, $3.length);
1213 $$.first = $1.first;
1214 $1.last->next = ri;
1215 $$.last = ri;
1216 }
1217 | rcdata_data ',' sizednumexpr
1218 {
1219 struct rcdata_item *ri;
1220
1221 ri = define_rcdata_number ($3.val, $3.dword);
1222 $$.first = $1.first;
1223 $1.last->next = ri;
1224 $$.last = ri;
1225 }
1226 ;
1227
1228 /* Stringtable resources. */
1229
1230 stringtable:
1231 STRINGTABLE suboptions BEG
1232 { sub_res_info = $2; }
1233 string_data END
1234 ;
1235
1236 string_data:
1237 /* empty */
1238 | string_data numexpr QUOTEDSTRING
1239 {
1240 define_stringtable (&sub_res_info, $2, $3);
1241 if (yychar != YYEMPTY)
1242 YYERROR;
1243 rcparse_discard_strings ();
1244 }
1245 | string_data numexpr ',' QUOTEDSTRING
1246 {
1247 define_stringtable (&sub_res_info, $2, $4);
1248 if (yychar != YYEMPTY)
1249 YYERROR;
1250 rcparse_discard_strings ();
1251 }
1252 ;
1253
1254 /* User defined resources. We accept general suboptions in the
1255 file_name case to keep the parser happy. */
1256
1257 user:
1258 id id suboptions BEG optrcdata_data END
1259 {
1260 define_user_data ($1, $2, &$3, $5.first);
1261 if (yychar != YYEMPTY)
1262 YYERROR;
1263 rcparse_discard_strings ();
1264 }
1265 | id id suboptions file_name
1266 {
1267 define_user_file ($1, $2, &$3, $4);
1268 if (yychar != YYEMPTY)
1269 YYERROR;
1270 rcparse_discard_strings ();
1271 }
1272 ;
1273
1274 /* Versioninfo resources. */
1275
1276 versioninfo:
1277 id VERSIONINFO fixedverinfo BEG verblocks END
1278 {
1279 define_versioninfo ($1, language, $3, $5);
1280 if (yychar != YYEMPTY)
1281 YYERROR;
1282 rcparse_discard_strings ();
1283 }
1284 ;
1285
1286 fixedverinfo:
1287 /* empty */
1288 {
1289 $$ = ((struct fixed_versioninfo *)
1290 res_alloc (sizeof (struct fixed_versioninfo)));
1291 memset ($$, 0, sizeof (struct fixed_versioninfo));
1292 }
1293 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1294 {
1295 $1->file_version_ms = ($3 << 16) | $4;
1296 $1->file_version_ls = ($5 << 16) | $6;
1297 $$ = $1;
1298 }
1299 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1300 {
1301 $1->product_version_ms = ($3 << 16) | $4;
1302 $1->product_version_ls = ($5 << 16) | $6;
1303 $$ = $1;
1304 }
1305 | fixedverinfo FILEFLAGSMASK numexpr
1306 {
1307 $1->file_flags_mask = $3;
1308 $$ = $1;
1309 }
1310 | fixedverinfo FILEFLAGS numexpr
1311 {
1312 $1->file_flags = $3;
1313 $$ = $1;
1314 }
1315 | fixedverinfo FILEOS numexpr
1316 {
1317 $1->file_os = $3;
1318 $$ = $1;
1319 }
1320 | fixedverinfo FILETYPE numexpr
1321 {
1322 $1->file_type = $3;
1323 $$ = $1;
1324 }
1325 | fixedverinfo FILESUBTYPE numexpr
1326 {
1327 $1->file_subtype = $3;
1328 $$ = $1;
1329 }
1330 ;
1331
1332 /* To handle verblocks successfully, the lexer handles BLOCK
1333 specially. A BLOCK "StringFileInfo" is returned as
1334 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1335 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1336 with the string as the value. */
1337
1338 verblocks:
1339 /* empty */
1340 {
1341 $$ = NULL;
1342 }
1343 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1344 {
1345 $$ = append_ver_stringfileinfo ($1, $4, $6);
1346 }
1347 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
1348 {
1349 $$ = append_ver_varfileinfo ($1, $5, $6);
1350 }
1351 ;
1352
1353 vervals:
1354 /* empty */
1355 {
1356 $$ = NULL;
1357 }
1358 | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
1359 {
1360 $$ = append_verval ($1, $3, $5);
1361 }
1362 ;
1363
1364 vertrans:
1365 /* empty */
1366 {
1367 $$ = NULL;
1368 }
1369 | vertrans cnumexpr cnumexpr
1370 {
1371 $$ = append_vertrans ($1, $2, $3);
1372 }
1373 ;
1374
1375 /* A resource ID. */
1376
1377 id:
1378 posnumexpr
1379 {
1380 $$.named = 0;
1381 $$.u.id = $1;
1382 }
1383 | STRING
1384 {
1385 char *copy, *s;
1386
1387 /* It seems that resource ID's are forced to upper case. */
1388 copy = xstrdup ($1);
1389 for (s = copy; *s != '\0'; s++)
1390 *s = TOUPPER (*s);
1391 res_string_to_id (&$$, copy);
1392 free (copy);
1393 }
1394 ;
1395
1396 /* A resource reference. */
1397
1398 resname:
1399 QUOTEDSTRING
1400 {
1401 $$ = $1;
1402 }
1403 | QUOTEDSTRING ','
1404 {
1405 $$ = $1;
1406 }
1407 | STRING ','
1408 {
1409 $$ = $1;
1410 }
1411 ;
1412
1413
1414 resref:
1415 posnumexpr ','
1416 {
1417 $$.named = 0;
1418 $$.u.id = $1;
1419 }
1420 | resname
1421 {
1422 char *copy, *s;
1423
1424 /* It seems that resource ID's are forced to upper case. */
1425 copy = xstrdup ($1);
1426 for (s = copy; *s != '\0'; s++)
1427 *s = TOUPPER (*s);
1428 res_string_to_id (&$$, copy);
1429 free (copy);
1430 }
1431 ;
1432
1433 /* Generic suboptions. These may appear before the BEGIN in any
1434 multiline statement. */
1435
1436 suboptions:
1437 /* empty */
1438 {
1439 memset (&$$, 0, sizeof (struct res_res_info));
1440 $$.language = language;
1441 /* FIXME: Is this the right default? */
1442 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1443 }
1444 | suboptions memflag
1445 {
1446 $$ = $1;
1447 $$.memflags |= $2.on;
1448 $$.memflags &=~ $2.off;
1449 }
1450 | suboptions CHARACTERISTICS numexpr
1451 {
1452 $$ = $1;
1453 $$.characteristics = $3;
1454 }
1455 | suboptions LANGUAGE numexpr cnumexpr
1456 {
1457 $$ = $1;
1458 $$.language = $3 | ($4 << SUBLANG_SHIFT);
1459 }
1460 | suboptions VERSIONK numexpr
1461 {
1462 $$ = $1;
1463 $$.version = $3;
1464 }
1465 ;
1466
1467 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1468
1469 memflags_move_discard:
1470 /* empty */
1471 {
1472 memset (&$$, 0, sizeof (struct res_res_info));
1473 $$.language = language;
1474 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1475 }
1476 | memflags_move_discard memflag
1477 {
1478 $$ = $1;
1479 $$.memflags |= $2.on;
1480 $$.memflags &=~ $2.off;
1481 }
1482 ;
1483
1484 /* Memory flags which default to MOVEABLE. */
1485
1486 memflags_move:
1487 /* empty */
1488 {
1489 memset (&$$, 0, sizeof (struct res_res_info));
1490 $$.language = language;
1491 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1492 }
1493 | memflags_move memflag
1494 {
1495 $$ = $1;
1496 $$.memflags |= $2.on;
1497 $$.memflags &=~ $2.off;
1498 }
1499 ;
1500
1501 /* Memory flags. This returns a struct with two integers, because we
1502 sometimes want to set bits and we sometimes want to clear them. */
1503
1504 memflag:
1505 MOVEABLE
1506 {
1507 $$.on = MEMFLAG_MOVEABLE;
1508 $$.off = 0;
1509 }
1510 | FIXED
1511 {
1512 $$.on = 0;
1513 $$.off = MEMFLAG_MOVEABLE;
1514 }
1515 | PURE
1516 {
1517 $$.on = MEMFLAG_PURE;
1518 $$.off = 0;
1519 }
1520 | IMPURE
1521 {
1522 $$.on = 0;
1523 $$.off = MEMFLAG_PURE;
1524 }
1525 | PRELOAD
1526 {
1527 $$.on = MEMFLAG_PRELOAD;
1528 $$.off = 0;
1529 }
1530 | LOADONCALL
1531 {
1532 $$.on = 0;
1533 $$.off = MEMFLAG_PRELOAD;
1534 }
1535 | DISCARDABLE
1536 {
1537 $$.on = MEMFLAG_DISCARDABLE;
1538 $$.off = 0;
1539 }
1540 ;
1541
1542 /* A file name. */
1543
1544 file_name:
1545 QUOTEDSTRING
1546 {
1547 $$ = $1;
1548 }
1549 | STRING
1550 {
1551 $$ = $1;
1552 }
1553 ;
1554
1555 /* A style expression. This changes the static variable STYLE. We do
1556 it this way because rc appears to permit a style to be set to
1557 something like
1558 WS_GROUP | NOT WS_TABSTOP
1559 to mean that a default of WS_TABSTOP should be removed. Anything
1560 which wants to accept a style must first set STYLE to the default
1561 value. The styleexpr nonterminal will change STYLE as specified by
1562 the user. Note that we do not accept arbitrary expressions here,
1563 just numbers separated by '|'. */
1564
1565 styleexpr:
1566 parennumber
1567 {
1568 style |= $1;
1569 }
1570 | NOT parennumber
1571 {
1572 style &=~ $2;
1573 }
1574 | styleexpr '|' parennumber
1575 {
1576 style |= $3;
1577 }
1578 | styleexpr '|' NOT parennumber
1579 {
1580 style &=~ $4;
1581 }
1582 ;
1583
1584 parennumber:
1585 NUMBER
1586 {
1587 $$ = $1.val;
1588 }
1589 | '(' numexpr ')'
1590 {
1591 $$ = $2;
1592 }
1593 ;
1594
1595 /* An optional expression with a leading comma. */
1596
1597 optcnumexpr:
1598 /* empty */
1599 {
1600 $$ = 0;
1601 }
1602 | cnumexpr
1603 {
1604 $$ = $1;
1605 }
1606 ;
1607
1608 /* An expression with a leading comma. */
1609
1610 cnumexpr:
1611 ',' numexpr
1612 {
1613 $$ = $2;
1614 }
1615 ;
1616
1617 /* A possibly negated numeric expression. */
1618
1619 numexpr:
1620 sizednumexpr
1621 {
1622 $$ = $1.val;
1623 }
1624 ;
1625
1626 /* A possibly negated expression with a size. */
1627
1628 sizednumexpr:
1629 NUMBER
1630 {
1631 $$ = $1;
1632 }
1633 | '(' sizednumexpr ')'
1634 {
1635 $$ = $2;
1636 }
1637 | '~' sizednumexpr %prec '~'
1638 {
1639 $$.val = ~ $2.val;
1640 $$.dword = $2.dword;
1641 }
1642 | '-' sizednumexpr %prec NEG
1643 {
1644 $$.val = - $2.val;
1645 $$.dword = $2.dword;
1646 }
1647 | sizednumexpr '*' sizednumexpr
1648 {
1649 $$.val = $1.val * $3.val;
1650 $$.dword = $1.dword || $3.dword;
1651 }
1652 | sizednumexpr '/' sizednumexpr
1653 {
1654 $$.val = $1.val / $3.val;
1655 $$.dword = $1.dword || $3.dword;
1656 }
1657 | sizednumexpr '%' sizednumexpr
1658 {
1659 $$.val = $1.val % $3.val;
1660 $$.dword = $1.dword || $3.dword;
1661 }
1662 | sizednumexpr '+' sizednumexpr
1663 {
1664 $$.val = $1.val + $3.val;
1665 $$.dword = $1.dword || $3.dword;
1666 }
1667 | sizednumexpr '-' sizednumexpr
1668 {
1669 $$.val = $1.val - $3.val;
1670 $$.dword = $1.dword || $3.dword;
1671 }
1672 | sizednumexpr '&' sizednumexpr
1673 {
1674 $$.val = $1.val & $3.val;
1675 $$.dword = $1.dword || $3.dword;
1676 }
1677 | sizednumexpr '^' sizednumexpr
1678 {
1679 $$.val = $1.val ^ $3.val;
1680 $$.dword = $1.dword || $3.dword;
1681 }
1682 | sizednumexpr '|' sizednumexpr
1683 {
1684 $$.val = $1.val | $3.val;
1685 $$.dword = $1.dword || $3.dword;
1686 }
1687 ;
1688
1689 /* An expression with a leading comma which does not use unary
1690 negation. */
1691
1692 cposnumexpr:
1693 ',' posnumexpr
1694 {
1695 $$ = $2;
1696 }
1697 ;
1698
1699 /* An expression which does not use unary negation. */
1700
1701 posnumexpr:
1702 sizedposnumexpr
1703 {
1704 $$ = $1.val;
1705 }
1706 ;
1707
1708 /* An expression which does not use unary negation. We separate unary
1709 negation to avoid parsing conflicts when two numeric expressions
1710 appear consecutively. */
1711
1712 sizedposnumexpr:
1713 NUMBER
1714 {
1715 $$ = $1;
1716 }
1717 | '(' sizednumexpr ')'
1718 {
1719 $$ = $2;
1720 }
1721 | '~' sizednumexpr %prec '~'
1722 {
1723 $$.val = ~ $2.val;
1724 $$.dword = $2.dword;
1725 }
1726 | sizedposnumexpr '*' sizednumexpr
1727 {
1728 $$.val = $1.val * $3.val;
1729 $$.dword = $1.dword || $3.dword;
1730 }
1731 | sizedposnumexpr '/' sizednumexpr
1732 {
1733 $$.val = $1.val / $3.val;
1734 $$.dword = $1.dword || $3.dword;
1735 }
1736 | sizedposnumexpr '%' sizednumexpr
1737 {
1738 $$.val = $1.val % $3.val;
1739 $$.dword = $1.dword || $3.dword;
1740 }
1741 | sizedposnumexpr '+' sizednumexpr
1742 {
1743 $$.val = $1.val + $3.val;
1744 $$.dword = $1.dword || $3.dword;
1745 }
1746 | sizedposnumexpr '-' sizednumexpr
1747 {
1748 $$.val = $1.val - $3.val;
1749 $$.dword = $1.dword || $3.dword;
1750 }
1751 | sizedposnumexpr '&' sizednumexpr
1752 {
1753 $$.val = $1.val & $3.val;
1754 $$.dword = $1.dword || $3.dword;
1755 }
1756 | sizedposnumexpr '^' sizednumexpr
1757 {
1758 $$.val = $1.val ^ $3.val;
1759 $$.dword = $1.dword || $3.dword;
1760 }
1761 | sizedposnumexpr '|' sizednumexpr
1762 {
1763 $$.val = $1.val | $3.val;
1764 $$.dword = $1.dword || $3.dword;
1765 }
1766 ;
1767
1768 %%
1769
1770 /* Set the language from the command line. */
1771
1772 void
1773 rcparse_set_language (int lang)
1774 {
1775 language = lang;
1776 }
This page took 0.090738 seconds and 4 git commands to generate.