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