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