1 /***************************************************************************
2
3 parser.y (IDL yacc parser and tree generation)
4
5 Copyright (C) 1998, 1999 Andrew T. Veliath
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library 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 GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public
18 License along with this library; if not, write to the Free
19 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 $Id: parser.y,v 1.163 2004/11/12 15:37:11 michael Exp $
22
23 ***************************************************************************/
24 %{
25 #include <assert.h>
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 #include <errno.h>
32 #include "rename.h"
33 #include "util.h"
34
35 #define REF_IDENTS
36
37 #define do_binop(rv,op,a,b) do { \
38 if (IDL_binop_chktypes (op, a, b)) \
39 YYABORT; \
40 if (!(__IDL_flags & IDLF_NO_EVAL_CONST)) { \
41 rv = IDL_binop_eval (op, a, b); \
42 IDL_tree_free (a); \
43 IDL_tree_free (b); \
44 if (!rv) YYABORT; \
45 } else { \
46 rv = IDL_binop_new (op, a, b); \
47 } \
48 } while (0)
49
50 #define do_unaryop(rv,op,a) do { \
51 if (IDL_unaryop_chktypes (op, a)) \
52 YYABORT; \
53 if (!(__IDL_flags & IDLF_NO_EVAL_CONST)) { \
54 rv = IDL_unaryop_eval (op, a); \
55 IDL_tree_free (a); \
56 if (!rv) YYABORT; \
57 } else { \
58 rv = IDL_unaryop_new (op, a); \
59 } \
60 } while (0)
61
62 #define IS_INHIBIT_STATE() \
63 (__IDL_inhibits > 0 || \
64 ((__IDL_flags & IDLF_INHIBIT_INCLUDES) && \
65 (__IDL_flagsi & IDLFP_IN_INCLUDES) ) )
66
67
68 #define assign_declspec(tree,declspec) do { \
69 IDL_NODE_DECLSPEC (tree) = declspec; \
70 if ( IS_INHIBIT_STATE() ) { \
71 IDL_NODE_DECLSPEC (tree) |= \
72 IDLF_DECLSPEC_EXIST | \
73 IDLF_DECLSPEC_INHIBIT; \
74 } \
75 if ( __IDL_pidl > 0 ) { \
76 IDL_NODE_DECLSPEC (tree) |= \
77 IDLF_DECLSPEC_PIDL; \
78 } \
79 } while (0)
80
81 #define assign_props(tree,props) do { \
82 if (__IDL_flags & IDLF_PROPERTIES) \
83 IDL_NODE_PROPERTIES (tree) = (props); \
84 else \
85 __IDL_free_properties (props); \
86 } while (0)
87
88 extern int yylex (void);
89 static IDL_declspec_t IDL_parse_declspec (const char *strspec);
90 static int IDL_binop_chktypes (enum IDL_binop op,
91 IDL_tree a,
92 IDL_tree b);
93 static int IDL_unaryop_chktypes (enum IDL_unaryop op,
94 IDL_tree a);
95 static IDL_tree IDL_binop_eval (enum IDL_binop op,
96 IDL_tree a,
97 IDL_tree b);
98 static IDL_tree IDL_unaryop_eval (enum IDL_unaryop op,
99 IDL_tree a);
100 static IDL_tree list_start (IDL_tree a,
101 gboolean filter_null);
102 static IDL_tree list_chain (IDL_tree a,
103 IDL_tree b,
104 gboolean filter_null);
105 static IDL_tree zlist_chain (IDL_tree a,
106 IDL_tree b,
107 gboolean filter_null);
108 static int do_token_error (IDL_tree p,
109 const char *message,
110 gboolean prev);
111 static void illegal_context_type_error (IDL_tree p,
112 const char *what);
113 static void illegal_type_error (IDL_tree p,
114 const char *message);
115 %}
116
117 %union {
118 IDL_tree tree;
119 struct {
120 IDL_tree tree;
121 gpointer data;
122 } treedata;
123 GHashTable *hash_table;
124 char *str;
125 gboolean boolean;
126 IDL_declspec_t declspec;
127 IDL_longlong_t integer;
128 double floatp;
129 enum IDL_unaryop unaryop;
130 enum IDL_param_attr paramattr;
131 }
132
133 /* Terminals */
134 %token TOK_ANY
135 %token TOK_ATTRIBUTE
136 %token TOK_BOOLEAN
137 %token TOK_CASE
138 %token TOK_CHAR
139 %token TOK_CONST
140 %token TOK_CONTEXT
141 %token TOK_DEFAULT
142 %token TOK_DOUBLE
143 %token TOK_ENUM
144 %token TOK_EXCEPTION
145 %token TOK_FALSE
146 %token TOK_FIXED
147 %token TOK_FLOAT
148 %token TOK_IN
149 %token TOK_INOUT
150 %token TOK_INTERFACE
151 %token TOK_LONG
152 %token TOK_MODULE
153 %token TOK_NATIVE
154 %token TOK_OBJECT
155 %token TOK_OCTET
156 %token TOK_ONEWAY
157 %token TOK_OP_SCOPE
158 %token TOK_OP_SHL
159 %token TOK_OP_SHR
160 %token TOK_OUT
161 %token TOK_RAISES
162 %token TOK_READONLY
163 %token TOK_SEQUENCE
164 %token TOK_SHORT
165 %token TOK_STRING
166 %token TOK_STRUCT
167 %token TOK_SWITCH
168 %token TOK_TRUE
169 %token TOK_TYPECODE
170 %token TOK_TYPEDEF
171 %token TOK_UNION
172 %token TOK_UNSIGNED
173 %token TOK_VARARGS
174 %token TOK_VOID
175 %token TOK_WCHAR
176 %token TOK_WSTRING
177 %token <floatp> TOK_FLOATP
178 %token <integer> TOK_INTEGER
179 %token <str> TOK_DECLSPEC TOK_PROP_KEY
180 %token <str> TOK_PROP_VALUE TOK_NATIVE_TYPE
181 %token <str> TOK_IDENT TOK_SQSTRING TOK_DQSTRING TOK_FIXEDP
182 %token <tree> TOK_CODEFRAG
183 %token <tree> TOK_SRCFILE
184
185 /* Non-Terminals */
186 %type <tree> add_expr
187 %type <tree> and_expr
188 %type <tree> any_type
189 %type <tree> array_declarator
190 %type <tree> attr_dcl
191 %type <tree> attr_dcl_def
192 %type <tree> base_type_spec
193 %type <tree> boolean_lit
194 %type <tree> boolean_type
195 %type <tree> case_label
196 %type <tree> case_label_list
197 %type <tree> case_stmt
198 %type <tree> case_stmt_list
199 %type <tree> char_lit
200 %type <tree> char_type
201 %type <tree> codefrag
202 %type <tree> complex_declarator
203 %type <tree> const_dcl
204 %type <tree> const_dcl_def
205 %type <tree> const_exp
206 %type <tree> const_type
207 %type <tree> constr_type_spec
208 %type <tree> context_expr
209 %type <tree> cur_ns_new_or_prev_ident
210 %type <tree> declarator
211 %type <tree> declarator_list
212 %type <tree> definition
213 %type <tree> definition_list
214 %type <tree> element_spec
215 %type <tree> enum_type
216 %type <tree> enumerator_list
217 %type <tree> except_dcl
218 %type <tree> except_dcl_def
219 %type <tree> export
220 %type <tree> export_list
221 %type <tree> fixed_array_size
222 %type <tree> fixed_array_size_list
223 %type <tree> fixed_pt_const_type
224 %type <tree> fixed_pt_lit
225 %type <tree> fixed_pt_type
226 %type <tree> floating_pt_lit
227 %type <tree> floating_pt_type
228 %type <tree> ident
229 %type <tree> illegal_ident
230 %type <tree> integer_lit
231 %type <tree> integer_type
232 %type <tree> interface
233 %type <tree> interface_body
234 %type <tree> interface_catch_ident
235 %type <tree> is_context_expr
236 %type <tree> is_raises_expr
237 %type <tree> literal
238 %type <tree> member
239 %type <tree> member_list
240 %type <tree> member_zlist
241 %type <tree> module
242 %type <tree> mult_expr
243 %type <tree> new_ident
244 %type <tree> new_or_prev_scope
245 %type <tree> new_scope
246 %type <tree> ns_global_ident
247 %type <tree> ns_new_ident
248 %type <tree> ns_prev_ident
249 %type <tree> ns_scoped_name
250 %type <tree> object_type
251 %type <tree> octet_type
252 %type <tree> op_dcl
253 %type <tree> op_dcl_def
254 %type <tree> op_param_type_spec
255 %type <tree> op_param_type_spec_illegal
256 %type <tree> op_type_spec
257 %type <tree> or_expr
258 %type <tree> param_dcl
259 %type <tree> param_dcl_list
260 %type <tree> param_type_spec
261 %type <tree> pop_scope
262 %type <tree> positive_int_const
263 %type <tree> primary_expr
264 %type <tree> raises_expr
265 %type <tree> scoped_name
266 %type <tree> scoped_name_list
267 %type <tree> sequence_type
268 %type <tree> shift_expr
269 %type <tree> simple_declarator
270 %type <tree> simple_declarator_list
271 %type <tree> simple_type_spec
272 %type <tree> specification
273 %type <tree> srcfile
274 %type <tree> string_lit
275 %type <tree> string_lit_list
276 %type <tree> string_type
277 %type <tree> struct_type
278 %type <tree> switch_body
279 %type <tree> switch_type_spec
280 %type <tree> template_type_spec
281 %type <tree> type_dcl
282 %type <tree> type_dcl_def
283 %type <tree> type_declarator
284 %type <tree> type_spec
285 %type <tree> unary_expr
286 %type <tree> union_type
287 %type <tree> useless_semicolon
288 %type <tree> wide_char_type
289 %type <tree> wide_string_type
290 %type <tree> xor_expr
291 %type <tree> z_definition_list
292 %type <tree> z_inheritance
293 %type <tree> z_new_ident_catch
294 %type <tree> z_new_scope_catch
295 %type <tree> typecode_type
296
297 %type <treedata> parameter_dcls
298 %type <declspec> z_declspec module_declspec
299 %type <hash_table> z_props prop_hash
300 %type <boolean> is_readonly is_oneway
301 %type <boolean> is_varargs is_cvarargs
302 %type <integer> signed_int unsigned_int
303 %type <paramattr> param_attribute
304 %type <str> sqstring dqstring dqstring_cat
305 %type <unaryop> unary_op
306
307 %%
308
309 specification: /* empty */ { yyerror ("Empty file"); YYABORT; }
310 | definition_list { __IDL_root = $1; }
311 ;
312
313 z_definition_list: /* empty */ { $$ = NULL; }
314 | definition_list
315 ;
316
317 definition_list: definition { $$ = list_start ($1, TRUE); }
318 | definition_list definition { $$ = list_chain ($1, $2, TRUE); }
319 ;
320
321 check_semicolon: ';'
322 | /* empty */ {
323 if (do_token_error ($<tree>0, "Missing semicolon after", TRUE))
324 YYABORT;
325 }
326 ;
327
328 useless_semicolon: ';' {
329 yyerror ("Dangling semicolon has no effect");
330 $$ = NULL;
331 }
332 ;
333
334 check_comma: ','
335 | /* empty */ {
336 if (do_token_error ($<tree>0, "Missing comma after", TRUE))
337 YYABORT;
338 }
339 ;
340
341 illegal_ident: scoped_name {
342 if (IDL_NODE_UP ($1))
343 do_token_error (IDL_NODE_UP ($1), "Illegal context for", FALSE);
344 else
345 yyerror ("Illegal context for identifier");
346 YYABORT;
347 }
348 ;
349
350 definition: type_dcl check_semicolon
351 | const_dcl check_semicolon
352 | except_dcl check_semicolon
353 | interface check_semicolon
354 | module check_semicolon
355 | codefrag
356 | srcfile
357 | illegal_ident
358 | useless_semicolon
359 ;
360
361 module_declspec: z_declspec TOK_MODULE
362 ;
363
364 module: module_declspec
365 new_or_prev_scope {
366 if (IDL_NODE_UP ($2) != NULL &&
367 IDL_NODE_TYPE (IDL_NODE_UP ($2)) != IDLN_MODULE) {
368 yyerror ("Module definition conflicts");
369 do_token_error (IDL_NODE_UP ($2), "with", FALSE);
370 YYABORT;
371 }
372 } '{'
373 z_definition_list
374 '}' pop_scope {
375 IDL_tree module;
376
377 if ($5 == NULL) {
378 yyerrorv ("Empty module declaration `%s' is not legal IDL",
379 IDL_IDENT ($2).str);
380 module = NULL;
381 }
382
383 if (__IDL_flags & IDLF_COMBINE_REOPENED_MODULES) {
384 if (IDL_NODE_UP ($2) == NULL)
385 module = IDL_module_new ($2, $5);
386 else {
387 module = IDL_NODE_UP ($2);
388 IDL_MODULE (module).definition_list =
389 IDL_list_concat (IDL_MODULE (module).definition_list, $5);
390 module = NULL;
391 }
392 } else
393 module = IDL_module_new ($2, $5);
394
395 $$ = module;
396 if ($$) assign_declspec ($$, $1);
397 }
398 ;
399
400 /* We only catch these errors for non-pidl because we want to be able to compile
401 the OMG CORBA .idl files which define interfaces by these names */
402 interface_catch_ident: new_or_prev_scope
403 | TOK_OBJECT {
404 yyerror ("Interfaces cannot be named `Object'");
405 YYABORT;
406 }
407 | TOK_TYPECODE {
408 yyerror ("Interfaces cannot be named `TypeCode'");
409 YYABORT;
410 }
411 ;
412
413 interface: z_declspec
414 z_props
415 TOK_INTERFACE
416 interface_catch_ident {
417 assert ($4 != NULL);
418 assert (IDL_NODE_TYPE ($4) == IDLN_IDENT);
419 assert (IDL_IDENT_TO_NS ($4) != NULL);
420 assert (IDL_NODE_TYPE (IDL_IDENT_TO_NS ($4)) == IDLN_GENTREE);
421
422 if (IDL_NODE_UP ($4) != NULL &&
423 IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_INTERFACE &&
424 IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_FORWARD_DCL) {
425 yyerrorl ("Interface definition conflicts",
426 __IDL_prev_token_line - __IDL_cur_token_line);
427 do_token_error (IDL_NODE_UP ($4), "with", FALSE);
428 YYABORT;
429 } else if (IDL_NODE_UP ($4) != NULL &&
430 IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_FORWARD_DCL) {
431 yyerrorv ("Cannot redeclare interface `%s'", IDL_IDENT ($4).str);
432 IDL_tree_error ($4, "Previous declaration of interface `%s'", IDL_IDENT ($4).str);
433 YYABORT;
434 } else if (IDL_NODE_UP ($4) != NULL &&
435 IDL_NODE_TYPE (IDL_NODE_UP ($4)) == IDLN_FORWARD_DCL)
436 __IDL_assign_this_location ($4, __IDL_cur_filename, __IDL_cur_line);
437 }
438 pop_scope
439 z_inheritance {
440 IDL_GENTREE (IDL_IDENT_TO_NS ($4))._import = $7;
441 IDL_ns_push_scope (__IDL_root_ns, IDL_IDENT_TO_NS ($4));
442 if (IDL_ns_check_for_ambiguous_inheritance ($4, $7))
443 __IDL_is_okay = FALSE;
444 } '{'
445 interface_body
446 '}' pop_scope {
447 $$ = IDL_interface_new ($4, $7, $10);
448 assign_declspec ($$, $1);
449 assign_props (IDL_INTERFACE ($$).ident, $2);
450 }
451 | z_declspec
452 z_props
453 TOK_INTERFACE
454 interface_catch_ident
455 pop_scope {
456 if ($2) yywarningv (IDL_WARNING1,
457 "Ignoring properties for forward declaration `%s'",
458 IDL_IDENT ($4).str);
459 $$ = IDL_forward_dcl_new ($4);
460 assign_declspec ($$, $1);
461 }
462 ;
463
464 z_inheritance: /* empty */ { $$ = NULL; }
465 | ':' scoped_name_list {
466 GHashTable *table = g_hash_table_new (g_direct_hash, g_direct_equal);
467 gboolean die = FALSE;
468 IDL_tree p = $2;
469
470 assert (IDL_NODE_TYPE (p) == IDLN_LIST);
471 for (; p != NULL && !die; p = IDL_LIST (p).next) {
472 assert (IDL_LIST (p).data != NULL);
473 assert (IDL_NODE_TYPE (IDL_LIST (p).data) == IDLN_IDENT);
474
475 if (g_hash_table_lookup_extended (table, IDL_LIST (p).data, NULL, NULL)) {
476 char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0);
477 yyerrorv ("Cannot inherit from interface `%s' more than once", s);
478 g_free (s);
479 die = TRUE;
480 break;
481 } else
482 g_hash_table_insert (table, IDL_LIST (p).data, NULL);
483
484 if (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (p).data)) == IDLN_FORWARD_DCL) {
485 char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0);
486 yyerrorv ("Incomplete definition of interface `%s'", s);
487 IDL_tree_error (IDL_LIST (p).data,
488 "Previous forward declaration of `%s'", s);
489 g_free (s);
490 die = TRUE;
491 }
492 else if (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (p).data)) != IDLN_INTERFACE) {
493 char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0);
494 yyerrorv ("`%s' is not an interface", s);
495 IDL_tree_error (IDL_LIST (p).data,
496 "Previous declaration of `%s'", s);
497 g_free (s);
498 die = TRUE;
499 }
500 }
501
502 g_hash_table_destroy (table);
503
504 if (die)
505 YYABORT;
506
507 $$ = $2;
508 }
509 ;
510
511 scoped_name_list: scoped_name { $$ = list_start ($1, TRUE); }
512 | scoped_name_list
513 check_comma scoped_name { $$ = list_chain ($1, $3, TRUE); }
514 ;
515
516 interface_body: export_list
517 ;
518
519 export_list: /* empty */ { $$ = NULL; }
520 | export_list export { $$ = zlist_chain ($1, $2, TRUE); }
521 ;
522
523 export: type_dcl check_semicolon
524 | except_dcl check_semicolon
525 | op_dcl check_semicolon
526 | attr_dcl check_semicolon
527 | const_dcl check_semicolon
528 | codefrag
529 | useless_semicolon
530 ;
531
532 type_dcl: z_declspec type_dcl_def {
533 $$ = $2;
534 assign_declspec ($$, $1);
535 }
536 ;
537
538 type_dcl_def: z_props TOK_TYPEDEF
539 type_declarator {
540 IDL_tree_node node;
541 IDL_tree p, dcl;
542
543 $$ = $3;
544 node.properties = $1;
545 for (p = IDL_TYPE_DCL ($3).dcls; p; p = IDL_LIST (p).next) {
546 dcl = IDL_LIST (p).data;
547 IDL_tree_properties_copy (&node, dcl);
548 }
549 __IDL_free_properties (node.properties);
550 }
551 | struct_type
552 | union_type
553 | enum_type
554 | z_props TOK_NATIVE
555 simple_declarator {
556 $$ = IDL_native_new ($3);
557 assign_props (IDL_NATIVE ($$).ident, $1);
558 }
559 | z_props TOK_NATIVE simple_declarator
560 '(' {
561 /* Enable native type scanning */
562 if (__IDL_pidl > 0)
563 __IDL_flagsi |= IDLFP_NATIVE;
564 else {
565 yyerror ("Native syntax not enabled");
566 YYABORT;
567 }
568 } TOK_NATIVE_TYPE {
569 $$ = IDL_native_new ($3);
570 IDL_NATIVE ($$).user_type = $6;
571 assign_props (IDL_NATIVE ($$).ident, $1);
572 }
573 ;
574
575 type_declarator: type_spec declarator_list { $$ = IDL_type_dcl_new ($1, $2); }
576 ;
577
578 type_spec: simple_type_spec
579 | constr_type_spec
580 ;
581
582 simple_type_spec: base_type_spec
583 | template_type_spec
584 | scoped_name
585 ;
586
587 constr_type_spec: struct_type
588 | union_type
589 | enum_type
590 ;
591
592 z_new_ident_catch: /* empty */ {
593 yyerrorv ("Missing identifier in %s definition", $<str>0);
594 YYABORT;
595 }
596 | new_ident
597 ;
598
599 z_new_scope_catch: /* empty */ {
600 yyerrorv ("Missing identifier in %s definition", $<str>0);
601 YYABORT;
602 }
603 | new_scope
604 ;
605
606 struct_type: z_props TOK_STRUCT
607 { $<str>$ = "struct"; }
608 z_new_scope_catch '{' {
609 g_hash_table_insert (__IDL_structunion_ht, $4, $4);
610 $<tree>$ = IDL_type_struct_new ($4, NULL);
611 } member_list
612 '}' pop_scope {
613 g_hash_table_remove (__IDL_structunion_ht, $4);
614 $$ = $<tree>6;
615 __IDL_assign_up_node ($$, $7);
616 IDL_TYPE_STRUCT ($$).member_list = $7;
617 assign_props (IDL_TYPE_STRUCT ($$).ident, $1);
618 }
619 ;
620
621 union_type: z_props TOK_UNION
622 { $<str>$ = "union"; }
623 z_new_scope_catch TOK_SWITCH '('
624 switch_type_spec
625 ')' '{' {
626 g_hash_table_insert (__IDL_structunion_ht, $4, $4);
627 $<tree>$ = IDL_type_union_new ($4, $7, NULL);
628 } switch_body
629 '}' pop_scope {
630 g_hash_table_remove (__IDL_structunion_ht, $4);
631 $$ = $<tree>10;
632 __IDL_assign_up_node ($$, $11);
633 IDL_TYPE_UNION ($$).switch_body = $11;
634 assign_props (IDL_TYPE_UNION ($$).ident, $1);
635 }
636 ;
637
638 switch_type_spec: integer_type
639 | char_type
640 | boolean_type
641 | enum_type
642 | scoped_name
643 ;
644
645 switch_body: case_stmt_list
646 ;
647
648 case_stmt_list: case_stmt { $$ = list_start ($1, TRUE); }
649 | case_stmt_list case_stmt { $$ = list_chain ($1, $2, TRUE); }
650 ;
651
652 case_stmt: case_label_list
653 element_spec check_semicolon { $$ = IDL_case_stmt_new ($1, $2); }
654 ;
655
656 element_spec: type_spec declarator {
657 char *s;
658
659 $$ = IDL_member_new ($1, list_start ($2, TRUE));
660 if (IDL_NODE_TYPE ($1) == IDLN_IDENT &&
661 g_hash_table_lookup (__IDL_structunion_ht, $1)) {
662 s = IDL_ns_ident_to_qstring ($2, "::", 0);
663 yyerrorv ("Member `%s'", s);
664 do_token_error (IDL_NODE_UP ($1), "recurses", TRUE);
665 g_free (s);
666 }
667 }
668 ;
669
670 case_label_list: case_label { $$ = list_start ($1, FALSE); }
671 | case_label_list case_label { $$ = list_chain ($1, $2, FALSE); }
672 ;
673
674 case_label: TOK_CASE const_exp ':' { $$ = $2; }
675 | TOK_DEFAULT ':' { $$ = NULL; }
676 ;
677
678 const_dcl: z_declspec const_dcl_def {
679 $$ = $2;
680 assign_declspec ($$, $1);
681 }
682 ;
683
684 const_dcl_def: TOK_CONST const_type new_ident
685 '=' const_exp {
686 $$ = IDL_const_dcl_new ($2, $3, $5);
687 /* Should probably do some type checking here... */
688 }
689 ;
690
691 except_dcl: z_declspec except_dcl_def {
692 $$ = $2;
693 assign_declspec ($$, $1);
694 }
695 ;
696
697 except_dcl_def: TOK_EXCEPTION new_scope '{'
698 member_zlist
699 '}' pop_scope { $$ = IDL_except_dcl_new ($2, $4); }
700 ;
701
702 member_zlist: /* empty */ { $$ = NULL; }
703 | member_zlist member { $$ = zlist_chain ($1, $2, TRUE); }
704 ;
705
706 is_readonly: /* empty */ { $$ = FALSE; }
707 | TOK_READONLY { $$ = TRUE; }
708 ;
709
710 attr_dcl: z_declspec attr_dcl_def {
711 $$ = $2;
712 assign_declspec ($$, $1);
713 }
714 ;
715
716 attr_dcl_def: z_props
717 is_readonly
718 TOK_ATTRIBUTE
719 { $<str>$ = "attribute"; }
720 param_type_spec
721 simple_declarator_list {
722 IDL_tree_node node;
723 IDL_tree p, dcl;
724
725 $$ = IDL_attr_dcl_new ($2, $5, $6);
726 node.properties = $1;
727 for (p = $6; p; p = IDL_LIST (p).next) {
728 dcl = IDL_LIST (p).data;
729 IDL_tree_properties_copy (&node, dcl);
730 }
731 __IDL_free_properties (node.properties);
732 }
733 ;
734
735 param_type_spec: op_param_type_spec
736 | TOK_VOID {
737 yyerrorv ("Illegal type `void' for %s", $<str>0);
738 $$ = NULL;
739 }
740 ;
741
742 op_param_type_spec_illegal:
743 sequence_type
744 | constr_type_spec
745 ;
746
747 op_param_type_spec: base_type_spec
748 | string_type
749 | wide_string_type
750 | fixed_pt_type
751 | scoped_name
752 | op_param_type_spec_illegal {
753 illegal_context_type_error ($1, $<str>0);
754 $$ = $1;
755 }
756 ;
757
758 is_oneway: /* empty */ { $$ = FALSE; }
759 | TOK_ONEWAY { $$ = TRUE; }
760 ;
761
762 op_dcl: z_declspec op_dcl_def {
763 $$ = $2;
764 assign_declspec ($$, $1);
765 }
766 ;
767
768 op_dcl_def: z_props
769 is_oneway
770 op_type_spec
771 new_scope parameter_dcls pop_scope
772 is_raises_expr
773 is_context_expr {
774 $$ = IDL_op_dcl_new ($2, $3, $4, $5.tree, $7, $8);
775 IDL_OP_DCL ($$).f_varargs = GPOINTER_TO_INT ($5.data);
776 assign_props (IDL_OP_DCL ($$).ident, $1);
777 }
778 ;
779
780 op_type_spec: { $<str>$ = "operation return value"; }
781 op_param_type_spec { $$ = $2; }
782 | TOK_VOID { $$ = NULL; }
783 ;
784
785 is_varargs: /* empty */ { $$ = FALSE; }
786 | TOK_VARARGS { $$ = TRUE; }
787 ;
788
789 is_cvarargs: /* empty */ { $$ = FALSE; }
790 | ',' TOK_VARARGS { $$ = TRUE; }
791 ;
792
793 parameter_dcls: '('
794 param_dcl_list
795 is_cvarargs
796 ')' {
797 $$.tree = $2;
798 $$.data = GINT_TO_POINTER ($3);
799 }
800 | '(' is_varargs ')' {
801 $$.tree = NULL;
802 $$.data = GINT_TO_POINTER ($2);
803 }
804 ;
805
806 param_dcl_list: param_dcl { $$ = list_start ($1, TRUE); }
807 | param_dcl_list
808 check_comma param_dcl { $$ = list_chain ($1, $3, TRUE); }
809 ;
810
811 param_dcl: z_props
812 param_attribute
813 { $<str>$ = "parameter"; }
814 param_type_spec
815 simple_declarator {
816 $$ = IDL_param_dcl_new ($2, $4, $5);
817 assign_props (IDL_PARAM_DCL ($$).simple_declarator, $1);
818 }
819 ;
820
821 param_attribute: TOK_IN { $$ = IDL_PARAM_IN; }
822 | TOK_OUT { $$ = IDL_PARAM_OUT; }
823 | TOK_INOUT { $$ = IDL_PARAM_INOUT; }
824 | param_type_spec {
825 yyerrorv ("Missing direction attribute (in, out, inout) before parameter");
826 IDL_tree_free ($1);
827 }
828 ;
829
830 is_raises_expr: /* empty */ { $$ = NULL; }
831 | raises_expr
832 ;
833
834 is_context_expr: /* empty */ { $$ = NULL; }
835 | context_expr
836 ;
837
838 raises_expr: TOK_RAISES '('
839 scoped_name_list
840 ')' { $$ = $3; }
841 ;
842
843 context_expr: TOK_CONTEXT '('
844 string_lit_list
845 ')' { $$ = $3; }
846 ;
847
848 const_type: integer_type
849 | char_type
850 | octet_type
851 | wide_char_type
852 | boolean_type
853 | floating_pt_type
854 | string_type
855 | wide_string_type
856 | fixed_pt_const_type
857 | scoped_name
858 ;
859
860 const_exp: or_expr
861 ;
862
863 or_expr: xor_expr
864 | or_expr '|' xor_expr { do_binop ($$, IDL_BINOP_OR, $1, $3); }
865 ;
866
867 xor_expr: and_expr
868 | xor_expr '^' and_expr { do_binop ($$, IDL_BINOP_XOR, $1, $3); }
869 ;
870
871 and_expr: shift_expr
872 | and_expr '&' shift_expr { do_binop ($$, IDL_BINOP_AND, $1, $3); }
873 ;
874
875 shift_expr: add_expr
876 | shift_expr TOK_OP_SHR add_expr { do_binop ($$, IDL_BINOP_SHR, $1, $3); }
877 | shift_expr TOK_OP_SHL add_expr { do_binop ($$, IDL_BINOP_SHL, $1, $3); }
878 ;
879
880 add_expr: mult_expr
881 | add_expr '+' mult_expr { do_binop ($$, IDL_BINOP_ADD, $1, $3); }
882 | add_expr '-' mult_expr { do_binop ($$, IDL_BINOP_SUB, $1, $3); }
883 ;
884
885 mult_expr: unary_expr
886 | mult_expr '*' unary_expr { do_binop ($$, IDL_BINOP_MULT, $1, $3); }
887 | mult_expr '/' unary_expr { do_binop ($$, IDL_BINOP_DIV, $1, $3); }
888 | mult_expr '%' unary_expr { do_binop ($$, IDL_BINOP_MOD, $1, $3); }
889 ;
890
891 unary_expr: unary_op primary_expr { do_unaryop ($$, $1, $2); }
892 | primary_expr
893 ;
894
895 unary_op: '-' { $$ = IDL_UNARYOP_MINUS; }
896 | '+' { $$ = IDL_UNARYOP_PLUS; }
897 | '~' { $$ = IDL_UNARYOP_COMPLEMENT; }
898 ;
899
900 primary_expr: scoped_name {
901 IDL_tree p, literal;
902
903 assert (IDL_NODE_TYPE ($1) == IDLN_IDENT);
904
905 p = IDL_NODE_UP ($1);
906
907 if ((literal = IDL_resolve_const_exp ($1, IDLN_ANY))) {
908 ++IDL_NODE_REFS (literal);
909 $$ = literal;
910 IDL_tree_free ($1);
911 } else
912 $$ = $1;
913 }
914 | literal
915 | '(' const_exp ')' { $$ = $2; }
916 ;
917
918 literal: integer_lit
919 | string_lit
920 | char_lit
921 | fixed_pt_lit
922 | floating_pt_lit
923 | boolean_lit
924 ;
925
926 enum_type: z_props TOK_ENUM
927 { $<str>$ = "enum"; }
928 z_new_ident_catch '{'
929 enumerator_list
930 '}' {
931 $$ = IDL_type_enum_new ($4, $6);
932 assign_props (IDL_TYPE_ENUM ($$).ident, $1);
933 }
934 ;
935
936 scoped_name: ns_scoped_name {
937 assert ($1 != NULL);
938 assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE);
939 assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
940 $$ = IDL_GENTREE ($1).data;
941 }
942 ;
943
944 ns_scoped_name: ns_prev_ident
945 | TOK_OP_SCOPE ns_global_ident { $$ = $2; }
946 | ns_scoped_name TOK_OP_SCOPE
947 ident {
948 IDL_tree p;
949
950 assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE);
951 assert (IDL_NODE_TYPE ($3) == IDLN_IDENT);
952
953 #ifdef YYDEBUG
954 if (yydebug)
955 fprintf (stderr, "ns: looking in `%s' for `%s'\n",
956 IDL_IDENT (IDL_GENTREE ($1).data).str, IDL_IDENT($3).str);
957 #endif
958
959 if ((p = IDL_ns_lookup_this_scope (__IDL_root_ns, $1, $3, NULL)) == NULL) {
960 yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($3).str);
961 IDL_tree_free ($3);
962 YYABORT;
963 }
964 IDL_tree_free ($3);
965 #ifdef REF_IDENTS
966 ++IDL_NODE_REFS (IDL_GENTREE (p).data);
967 #endif
968 $$ = p;
969 }
970 ;
971
972 enumerator_list: new_ident { $$ = list_start ($1, TRUE); }
973 | enumerator_list
974 check_comma new_ident { $$ = list_chain ($1, $3, TRUE); }
975 ;
976
977 member_list: member { $$ = list_start ($1, TRUE); }
978 | member_list member { $$ = list_chain ($1, $2, TRUE); }
979 ;
980
981 member: type_spec declarator_list
982 check_semicolon {
983 char *s;
984
985 $$ = IDL_member_new ($1, $2);
986 if (IDL_NODE_TYPE ($1) == IDLN_IDENT &&
987 g_hash_table_lookup (__IDL_structunion_ht, $1)) {
988 s = IDL_ns_ident_to_qstring (IDL_LIST ($2).data, "::", 0);
989 yyerrorv ("Member `%s'", s);
990 do_token_error (IDL_NODE_UP ($1), "recurses", TRUE);
991 g_free (s);
992 }
993 }
994 ;
995
996 base_type_spec: floating_pt_type
997 | integer_type
998 | char_type
999 | wide_char_type
1000 | boolean_type
1001 | octet_type
1002 | any_type
1003 | object_type
1004 | typecode_type
1005 ;
1006
1007 template_type_spec: sequence_type
1008 | string_type
1009 | wide_string_type
1010 | fixed_pt_type
1011 ;
1012
1013 sequence_type: TOK_SEQUENCE '<'
1014 simple_type_spec ',' positive_int_const
1015 '>' { $$ = IDL_type_sequence_new ($3, $5); }
1016 | TOK_SEQUENCE '<'
1017 simple_type_spec
1018 '>' { $$ = IDL_type_sequence_new ($3, NULL); }
1019 ;
1020
1021 floating_pt_type: TOK_FLOAT { $$ = IDL_type_float_new (IDL_FLOAT_TYPE_FLOAT); }
1022 | TOK_DOUBLE { $$ = IDL_type_float_new (IDL_FLOAT_TYPE_DOUBLE); }
1023 | TOK_LONG TOK_DOUBLE { $$ = IDL_type_float_new (IDL_FLOAT_TYPE_LONGDOUBLE); }
1024 ;
1025
1026 fixed_pt_type: TOK_FIXED '<'
1027 positive_int_const ',' integer_lit
1028 '>' { $$ = IDL_type_fixed_new ($3, $5); }
1029 ;
1030
1031 fixed_pt_const_type: TOK_FIXED { $$ = IDL_type_fixed_new (NULL, NULL); }
1032 ;
1033
1034 integer_type: signed_int { $$ = IDL_type_integer_new (TRUE, $1); }
1035 | unsigned_int { $$ = IDL_type_integer_new (FALSE, $1); }
1036 ;
1037
1038 signed_int: signed_short_int { $$ = IDL_INTEGER_TYPE_SHORT; }
1039 | signed_long_int { $$ = IDL_INTEGER_TYPE_LONG; }
1040 | signed_longlong_int { $$ = IDL_INTEGER_TYPE_LONGLONG; }
1041 ;
1042
1043 signed_short_int: TOK_SHORT
1044 ;
1045
1046 signed_long_int: TOK_LONG
1047 ;
1048
1049 signed_longlong_int: TOK_LONG TOK_LONG
1050 ;
1051
1052 unsigned_int: unsigned_short_int { $$ = IDL_INTEGER_TYPE_SHORT; }
1053 | unsigned_long_int { $$ = IDL_INTEGER_TYPE_LONG; }
1054 | unsigned_longlong_int { $$ = IDL_INTEGER_TYPE_LONGLONG; }
1055 ;
1056
1057 unsigned_short_int: TOK_UNSIGNED TOK_SHORT
1058 ;
1059
1060 unsigned_long_int: TOK_UNSIGNED TOK_LONG
1061 ;
1062
1063 unsigned_longlong_int: TOK_UNSIGNED TOK_LONG TOK_LONG
1064 ;
1065
1066 char_type: TOK_CHAR { $$ = IDL_type_char_new (); }
1067 ;
1068
1069 wide_char_type: TOK_WCHAR { $$ = IDL_type_wide_char_new (); }
1070 ;
1071
1072 boolean_type: TOK_BOOLEAN { $$ = IDL_type_boolean_new (); }
1073 ;
1074
1075 octet_type: TOK_OCTET { $$ = IDL_type_octet_new (); }
1076 ;
1077
1078 any_type: TOK_ANY { $$ = IDL_type_any_new (); }
1079 ;
1080
1081 object_type: TOK_OBJECT { $$ = IDL_type_object_new (); }
1082 ;
1083
1084 typecode_type: TOK_TYPECODE { $$ = IDL_type_typecode_new (); }
1085 ;
1086
1087 string_type: TOK_STRING '<'
1088 positive_int_const
1089 '>' { $$ = IDL_type_string_new ($3); }
1090 | TOK_STRING { $$ = IDL_type_string_new (NULL); }
1091 ;
1092
1093 wide_string_type: TOK_WSTRING '<'
1094 positive_int_const
1095 '>' { $$ = IDL_type_wide_string_new ($3); }
1096 | TOK_WSTRING { $$ = IDL_type_wide_string_new (NULL); }
1097 ;
1098
1099 declarator_list: declarator { $$ = list_start ($1, TRUE); }
1100 | declarator_list
1101 check_comma declarator { $$ = list_chain ($1, $3, TRUE); }
1102 ;
1103
1104 declarator: simple_declarator
1105 | complex_declarator
1106 ;
1107
1108 simple_declarator: new_ident
1109 ;
1110
1111 complex_declarator: array_declarator
1112 ;
1113
1114 simple_declarator_list: simple_declarator { $$ = list_start ($1, TRUE); }
1115 | simple_declarator_list
1116 check_comma simple_declarator { $$ = list_chain ($1, $3, TRUE); }
1117 ;
1118
1119 array_declarator: new_ident
1120 fixed_array_size_list {
1121 IDL_tree p;
1122 int i;
1123
1124 $$ = IDL_type_array_new ($1, $2);
1125 for (i = 1, p = $2; p; ++i, p = IDL_LIST (p).next)
1126 if (!IDL_LIST (p).data) {
1127 char *s = IDL_ns_ident_to_qstring ($1, "::", 0);
1128 yyerrorv ("Missing value in dimension %d of array `%s'", i, s);
1129 g_free (s);
1130 }
1131 }
1132 ;
1133
1134 fixed_array_size_list: fixed_array_size { $$ = list_start ($1, FALSE); }
1135 | fixed_array_size_list
1136 fixed_array_size { $$ = list_chain ($1, $2, FALSE); }
1137 ;
1138
1139 fixed_array_size: '[' positive_int_const ']' { $$ = $2; }
1140 | '[' ']' { $$ = NULL; }
1141 ;
1142
1143 prop_hash: TOK_PROP_KEY
1144 TOK_PROP_VALUE {
1145 $$ = g_hash_table_new (IDL_strcase_hash, IDL_strcase_equal);
1146 g_hash_table_insert ($$, $1, $2);
1147 }
1148 | prop_hash ','
1149 TOK_PROP_KEY
1150 TOK_PROP_VALUE {
1151 $$ = $1;
1152 g_hash_table_insert ($$, $3, $4);
1153 }
1154 | TOK_PROP_KEY {
1155 $$ = g_hash_table_new (IDL_strcase_hash, IDL_strcase_equal);
1156 g_hash_table_insert ($$, $1, g_strdup (""));
1157 }
1158 | prop_hash ','
1159 TOK_PROP_KEY {
1160 $$ = $1;
1161 g_hash_table_insert ($$, $3, g_strdup (""));
1162 }
1163 ;
1164
1165 ident: TOK_IDENT { $$ = IDL_ident_new ($1); }
1166 ;
1167
1168 new_ident: ns_new_ident {
1169 assert ($1 != NULL);
1170 assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE);
1171 assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
1172 $$ = IDL_GENTREE ($1).data;
1173 }
1174 ;
1175
1176 new_scope: ns_new_ident {
1177 IDL_tree old_top = IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data;
1178 IDL_ns_push_scope (__IDL_root_ns, $1);
1179 #ifdef YYDEBUG
1180 if (yydebug)
1181 fprintf (stderr, "ns: entering new scope `%s' of `%s'\n",
1182 IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str, IDL_IDENT(old_top).str);
1183 #endif
1184 assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
1185 $$ = IDL_GENTREE ($1).data;
1186 }
1187 ;
1188
1189 new_or_prev_scope: cur_ns_new_or_prev_ident {
1190 IDL_tree old_top = IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data;
1191 IDL_ns_push_scope (__IDL_root_ns, $1);
1192 assert (IDL_NS (__IDL_root_ns).current != NULL);
1193 assert (IDL_NODE_TYPE (IDL_NS (__IDL_root_ns).current) == IDLN_GENTREE);
1194 assert (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data != NULL);
1195 assert (IDL_NODE_TYPE (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data) == IDLN_IDENT);
1196 #ifdef YYDEBUG
1197 if (yydebug)
1198 fprintf (stderr,"ns: entering new/prev scope `%s' of `%s'\n",
1199 IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str, IDL_IDENT(old_top).str);
1200 #endif
1201 assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
1202 $$ = IDL_GENTREE ($1).data;
1203 }
1204 ;
1205
1206 pop_scope: /* empty */ {
1207 IDL_tree cur_top = IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data;
1208 IDL_ns_pop_scope (__IDL_root_ns);
1209 #ifdef YYDEBUG
1210 if (yydebug)
1211 fprintf (stderr, "ns: pop scope from `%s' to `%s'\n",
1212 IDL_IDENT(cur_top).str,
1213 IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str);
1214 #endif
1215 }
1216 ;
1217
1218 ns_new_ident: ident {
1219 IDL_tree p;
1220
1221 if ((p = IDL_ns_place_new (__IDL_root_ns, $1)) == NULL) {
1222 IDL_tree q;
1223 int i;
1224
1225 p = IDL_ns_lookup_cur_scope (__IDL_root_ns, $1, NULL);
1226
1227 for (i = 0, q = IDL_GENTREE (p).data;
1228 q && (IDL_NODE_TYPE (q) == IDLN_IDENT ||
1229 IDL_NODE_TYPE (q) == IDLN_LIST) && i < 4;
1230 ++i)
1231 if (IDL_NODE_UP (q))
1232 q = IDL_NODE_UP (q);
1233
1234 if (q) {
1235 IDL_tree_error ($1, "`%s' conflicts", IDL_IDENT ($1).str);
1236 do_token_error (q, "with", FALSE);
1237 } else
1238 yyerrorv ("`%s' duplicate identifier", IDL_IDENT ($1).str);
1239
1240 IDL_tree_free ($1);
1241 YYABORT;
1242 }
1243 assert (IDL_IDENT ($1)._ns_ref == p);
1244 #ifdef REF_IDENTS
1245 ++IDL_NODE_REFS (IDL_GENTREE (p).data);
1246 #endif
1247 if (__IDL_new_ident_comments != NULL) {
1248 assert (IDL_IDENT ($1).comments == NULL);
1249 IDL_IDENT ($1).comments = __IDL_new_ident_comments;
1250 __IDL_new_ident_comments = NULL;
1251 }
1252 $$ = p;
1253 }
1254 ;
1255
1256 ns_prev_ident: ident {
1257 IDL_tree p;
1258
1259 if ((p = IDL_ns_resolve_ident (__IDL_root_ns, $1)) == NULL) {
1260 yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($1).str);
1261 IDL_tree_free ($1);
1262 YYABORT;
1263 }
1264 IDL_tree_free ($1);
1265 assert (IDL_GENTREE (p).data != NULL);
1266 assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p);
1267 #ifdef REF_IDENTS
1268 ++IDL_NODE_REFS (IDL_GENTREE (p).data);
1269 #endif
1270 $$ = p;
1271 }
1272 ;
1273
1274 cur_ns_new_or_prev_ident:
1275 ident {
1276 IDL_tree p;
1277
1278 if ((p = IDL_ns_lookup_cur_scope (__IDL_root_ns, $1, NULL)) == NULL) {
1279 #ifdef YYDEBUG
1280 if (yydebug)
1281 fprintf (stderr, "ns: place_new `%s' in `%s'\n",
1282 IDL_IDENT($1).str,
1283 IDL_IDENT(IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str );
1284 #endif
1285 p = IDL_ns_place_new (__IDL_root_ns, $1);
1286 assert (p != NULL);
1287 assert (IDL_IDENT ($1)._ns_ref == p);
1288 if (__IDL_new_ident_comments != NULL) {
1289 assert (IDL_IDENT ($1).comments == NULL);
1290 IDL_IDENT ($1).comments = __IDL_new_ident_comments;
1291 __IDL_new_ident_comments = NULL;
1292 }
1293 } else {
1294 IDL_tree_free ($1);
1295 assert (IDL_GENTREE (p).data != NULL);
1296 assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p);
1297 }
1298 #ifdef REF_IDENTS
1299 ++IDL_NODE_REFS (IDL_GENTREE (p).data);
1300 #endif
1301 $$ = p;
1302 }
1303 ;
1304
1305 ns_global_ident: ident {
1306 IDL_tree p;
1307
1308 if ((p = IDL_ns_lookup_this_scope (
1309 __IDL_root_ns,IDL_NS (__IDL_root_ns).file, $1, NULL)) == NULL) {
1310 yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($1).str);
1311 IDL_tree_free ($1);
1312 YYABORT;
1313 }
1314 IDL_tree_free ($1);
1315 assert (IDL_GENTREE (p).data != NULL);
1316 assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p);
1317 #ifdef REF_IDENTS
1318 ++IDL_NODE_REFS (IDL_GENTREE (p).data);
1319 #endif
1320 $$ = p;
1321 }
1322 ;
1323
1324 string_lit_list: string_lit { $$ = list_start ($1, TRUE); }
1325 | string_lit_list
1326 check_comma string_lit { $$ = list_chain ($1, $3, TRUE); }
1327 ;
1328
1329 positive_int_const: const_exp {
1330 IDL_tree literal, ident = NULL;
1331 IDL_longlong_t value = 0;
1332
1333 if ((literal = IDL_resolve_const_exp ($1, IDLN_INTEGER))) {
1334 assert (IDL_NODE_TYPE (literal) == IDLN_INTEGER);
1335 ++IDL_NODE_REFS (literal);
1336 value = IDL_INTEGER (literal).value;
1337 if ( literal != $1 )
1338 IDL_tree_free ($1);
1339 }
1340
1341 if (literal && IDL_NODE_UP (literal) &&
1342 IDL_NODE_TYPE (IDL_NODE_UP (literal)) == IDLN_CONST_DCL)
1343 ident = IDL_CONST_DCL (IDL_NODE_UP (literal)).ident;
1344
1345 if (literal == NULL) {
1346 if (!(__IDL_flags & IDLF_NO_EVAL_CONST))
1347 yyerror ("Could not resolve constant expression");
1348 $$ = $1;
1349 } else if (value == 0) {
1350 yyerror ("Zero array size is illegal");
1351 if (ident)
1352 IDL_tree_error (ident, "From constant declared here");
1353 $$ = NULL;
1354 } else if (value < 0) {
1355 yywarningv (IDL_WARNING1, "Cannot use negative value %"
1356 IDL_LL "d, using %" IDL_LL "d",
1357 value, -value);
1358 if (ident)
1359 IDL_tree_warning (ident,
1360 IDL_WARNING1, "From constant declared here");
1361 $$ = IDL_integer_new (-value);
1362 }
1363 else
1364 $$ = IDL_integer_new (value);
1365 }
1366 ;
1367
1368 z_declspec: /* empty */ { $$ = 0; }
1369 | TOK_DECLSPEC {
1370 $$ = IDL_parse_declspec ($1);
1371 g_free ($1);
1372 }
1373 ;
1374
1375 z_props: /* empty */ { $$ = NULL; }
1376 | '[' {
1377 /* Enable property scanning */
1378 if (__IDL_flags & IDLF_PROPERTIES)
1379 __IDL_flagsi |= IDLFP_PROPERTIES;
1380 else {
1381 yyerror ("Property syntax not enabled");
1382 YYABORT;
1383 }
1384 } prop_hash
1385 ']' { $$ = $3; }
1386 ;
1387
1388 integer_lit: TOK_INTEGER { $$ = IDL_integer_new ($1); }
1389 ;
1390
1391 string_lit: dqstring_cat { $$ = IDL_string_new ($1); }
1392 ;
1393
1394 char_lit: sqstring { $$ = IDL_char_new ($1); }
1395 ;
1396
1397 fixed_pt_lit: TOK_FIXEDP { $$ = IDL_fixed_new ($1); }
1398 ;
1399
1400 floating_pt_lit: TOK_FLOATP { $$ = IDL_float_new ($1); }
1401 ;
1402
1403 boolean_lit: TOK_TRUE { $$ = IDL_boolean_new (TRUE); }
1404 | TOK_FALSE { $$ = IDL_boolean_new (FALSE); }
1405 ;
1406
1407 codefrag: z_declspec TOK_CODEFRAG {
1408 $$ = $2;
1409 assign_declspec ($$, $1);
1410 }
1411 ;
1412
1413 srcfile: TOK_SRCFILE {
1414 $$ = $1;
1415 }
1416 ;
1417
1418 dqstring_cat: dqstring
1419 | dqstring_cat dqstring {
1420 char *catstr = g_malloc (strlen ($1) + strlen ($2) + 1);
1421 strcpy (catstr, $1); g_free ($1);
1422 strcat (catstr, $2); g_free ($2);
1423 $$ = catstr;
1424 }
1425 ;
1426
1427 dqstring: TOK_DQSTRING {
1428 char *s = IDL_do_escapes ($1);
1429 g_free ($1);
1430 $$ = s;
1431 }
1432 ;
1433
1434 sqstring: TOK_SQSTRING {
1435 char *s = IDL_do_escapes ($1);
1436 g_free ($1);
1437 $$ = s;
1438 }
1439 ;
1440
1441 %%
1442
1443 void __IDL_parser_reset (void)
1444 {
1445 yyclearin;
1446 }
1447
IDL_ns_get_cur_prefix(IDL_ns ns)1448 static const char *IDL_ns_get_cur_prefix (IDL_ns ns)
1449 {
1450 IDL_tree p;
1451
1452 p = IDL_NS (ns).current;
1453
1454 assert (p != NULL);
1455
1456 while (p && !IDL_GENTREE (p)._cur_prefix)
1457 p = IDL_NODE_UP (p);
1458
1459 return p ? IDL_GENTREE (p)._cur_prefix : NULL;
1460 }
1461
IDL_ns_ident_make_repo_id(IDL_ns ns,IDL_tree p,const char * p_prefix,int * major,int * minor)1462 gchar *IDL_ns_ident_make_repo_id (IDL_ns ns, IDL_tree p,
1463 const char *p_prefix, int *major, int *minor)
1464 {
1465 GString *s = g_string_new (NULL);
1466 const char *prefix;
1467 char *q;
1468
1469 assert (p != NULL);
1470
1471 if (IDL_NODE_TYPE (p) == IDLN_IDENT)
1472 p = IDL_IDENT_TO_NS (p);
1473
1474 assert (p != NULL);
1475
1476 prefix = p_prefix ? p_prefix : IDL_ns_get_cur_prefix (ns);
1477
1478 q = IDL_ns_ident_to_qstring (p, "/", 0);
1479 g_string_printf (s, "IDL:%s%s%s:%d.%d",
1480 prefix ? prefix : "",
1481 prefix && *prefix ? "/" : "",
1482 q,
1483 major ? *major : 1,
1484 minor ? *minor : 0);
1485 g_free (q);
1486
1487 q = s->str;
1488 g_string_free (s, FALSE);
1489
1490 return q;
1491 }
1492
get_name_token(const char * s,char ** tok)1493 static const char *get_name_token (const char *s, char **tok)
1494 {
1495 const char *begin = s;
1496 int state = 0;
1497
1498 if (!s)
1499 return NULL;
1500
1501 while (g_ascii_isspace (*s)) ++s;
1502
1503 while (1) switch (state) {
1504 case 0: /* Unknown */
1505 if (*s == ':')
1506 state = 1;
1507 else if (isalnum ((int)*s) || *s == '_') {
1508 begin = s;
1509 state = 2;
1510 } else
1511 return NULL;
1512 break;
1513 case 1: /* Scope */
1514 if (strncmp (s, "::", 2) == 0) {
1515 char *r = g_malloc (3);
1516 strcpy (r, "::");
1517 *tok = r;
1518 return s + 2;
1519 } else /* Invalid */
1520 return NULL;
1521 break;
1522 case 2:
1523 if (isalnum ((int)*s) || *s == '_')
1524 ++s;
1525 else {
1526 char *r = g_malloc (s - begin + 1);
1527 strncpy (r, begin, s - begin + 1);
1528 r[s - begin] = 0;
1529 *tok = r;
1530 return s;
1531 }
1532 break;
1533 }
1534 }
1535
IDL_ns_pragma_parse_name(IDL_ns ns,const char * s)1536 static IDL_tree IDL_ns_pragma_parse_name (IDL_ns ns, const char *s)
1537 {
1538 IDL_tree p = IDL_NS (ns).current, q;
1539 int start = 1;
1540 char *tok;
1541
1542 /* This is a hack to allow directives for an ident (such
1543 * as and interface) to be located within the scope of
1544 * that identifier. */
1545 if ( p && (q=IDL_GENTREE(p).data)!=0
1546 && IDL_NODE_TYPE(q)==IDLN_IDENT
1547 && strcmp(s,IDL_IDENT(q).str)==0 ) {
1548 return p;
1549 }
1550
1551 while (p && *s && (s = get_name_token (s, &tok))) {
1552 if (tok == NULL)
1553 return NULL;
1554 if (strcmp (tok, "::") == 0) {
1555 if (start) {
1556 /* Globally scoped */
1557 p = IDL_NS (ns).file;
1558 }
1559 g_free (tok);
1560 } else {
1561 IDL_tree ident = IDL_ident_new (tok);
1562 p = IDL_ns_lookup_this_scope (__IDL_root_ns, p, ident, NULL);
1563 IDL_tree_free (ident);
1564 }
1565 start = 0;
1566 }
1567
1568 return p;
1569 }
1570
IDL_ns_ID(IDL_ns ns,const char * s)1571 void IDL_ns_ID (IDL_ns ns, const char *s)
1572 {
1573 char name[1024], id[1024];
1574 IDL_tree p, ident;
1575 int n;
1576
1577 n = sscanf (s, "%1023s \"%1023s\"", name, id);
1578 if (n < 2 && __IDL_is_parsing) {
1579 yywarning (IDL_WARNING1, "Malformed pragma ID");
1580 return;
1581 }
1582 if (id[strlen (id) - 1] == '"')
1583 id[strlen (id) - 1] = 0;
1584
1585 p = IDL_ns_pragma_parse_name (__IDL_root_ns, name);
1586 if (!p && __IDL_is_parsing) {
1587 yywarningv (IDL_WARNING1, "Unknown identifier `%s' in pragma ID", name);
1588 return;
1589 }
1590
1591 /* We have resolved the identifier, so assign the repo id */
1592 assert (IDL_NODE_TYPE (p) == IDLN_GENTREE);
1593 assert (IDL_GENTREE (p).data != NULL);
1594 assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT);
1595 ident = IDL_GENTREE (p).data;
1596
1597 if (IDL_IDENT_REPO_ID (ident) != NULL)
1598 g_free (IDL_IDENT_REPO_ID (ident));
1599
1600 IDL_IDENT_REPO_ID (ident) = g_strdup (id);
1601 }
1602
IDL_ns_version(IDL_ns ns,const char * s)1603 void IDL_ns_version (IDL_ns ns, const char *s)
1604 {
1605 char name[1024];
1606 int n, major, minor;
1607 IDL_tree p, ident;
1608
1609 n = sscanf (s, "%1023s %u.%u", name, &major, &minor);
1610 if (n < 3 && __IDL_is_parsing) {
1611 yywarning (IDL_WARNING1, "Malformed pragma version");
1612 return;
1613 }
1614
1615 p = IDL_ns_pragma_parse_name (__IDL_root_ns, name);
1616 if (!p && __IDL_is_parsing) {
1617 yywarningv (IDL_WARNING1, "Unknown identifier `%s' in pragma version", name);
1618 return;
1619 }
1620
1621 /* We have resolved the identifier, so assign the repo id */
1622 assert (IDL_NODE_TYPE (p) == IDLN_GENTREE);
1623 assert (IDL_GENTREE (p).data != NULL);
1624 assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT);
1625 ident = IDL_GENTREE (p).data;
1626
1627 if (IDL_IDENT_REPO_ID (ident) != NULL) {
1628 char *v = strrchr (IDL_IDENT_REPO_ID (ident), ':');
1629 if (v) {
1630 GString *s;
1631
1632 *v = 0;
1633 s = g_string_new (NULL);
1634 g_string_printf (s, "%s:%d.%d",
1635 IDL_IDENT_REPO_ID (ident), major, minor);
1636 g_free (IDL_IDENT_REPO_ID (ident));
1637 IDL_IDENT_REPO_ID (ident) = s->str;
1638 g_string_free (s, FALSE);
1639 } else if (__IDL_is_parsing)
1640 yywarningv (IDL_WARNING1, "Cannot find RepositoryID OMG IDL version in ID `%s'",
1641 IDL_IDENT_REPO_ID (ident));
1642 } else
1643 IDL_IDENT_REPO_ID (ident) =
1644 IDL_ns_ident_make_repo_id (
1645 __IDL_root_ns, p, NULL, &major, &minor);
1646 }
1647
IDL_inhibit_get(void)1648 int IDL_inhibit_get (void)
1649 {
1650 g_return_val_if_fail (__IDL_is_parsing, -1);
1651
1652 return __IDL_inhibits;
1653 }
1654
IDL_inhibit_push(void)1655 void IDL_inhibit_push (void)
1656 {
1657 g_return_if_fail (__IDL_is_parsing);
1658
1659 ++__IDL_inhibits;
1660 }
1661
IDL_inhibit_pop(void)1662 void IDL_inhibit_pop (void)
1663 {
1664 g_return_if_fail (__IDL_is_parsing);
1665
1666 if (--__IDL_inhibits < 0)
1667 __IDL_inhibits = 0;
1668 }
1669
IDL_inhibit(IDL_ns ns,const char * s)1670 static void IDL_inhibit (IDL_ns ns, const char *s)
1671 {
1672 if (g_ascii_strcasecmp ("push", s) == 0)
1673 IDL_inhibit_push ();
1674 else if (g_ascii_strcasecmp ("pop", s) == 0)
1675 IDL_inhibit_pop ();
1676 }
1677
IDL_typecodes_as_tok(IDL_ns ns,const char * s)1678 static void IDL_typecodes_as_tok (IDL_ns ns, const char *s)
1679 {
1680 if (g_ascii_strcasecmp ("push", s) == 0)
1681 ++(__IDL_typecodes_as_tok);
1682 else if (g_ascii_strcasecmp ("pop", s) == 0)
1683 --(__IDL_typecodes_as_tok);
1684 }
1685
IDL_pidl(IDL_ns ns,const char * s)1686 static void IDL_pidl (IDL_ns ns, const char *s)
1687 {
1688 if (g_ascii_strcasecmp ("push", s) == 0)
1689 ++(__IDL_pidl);
1690 else if (g_ascii_strcasecmp ("pop", s) == 0)
1691 --(__IDL_pidl);
1692 }
1693
__IDL_do_pragma(const char * s)1694 void __IDL_do_pragma (const char *s)
1695 {
1696 int n;
1697 char directive[256];
1698
1699 g_return_if_fail (__IDL_is_parsing);
1700 g_return_if_fail (s != NULL);
1701
1702 if (sscanf (s, "%255s%n", directive, &n) < 1)
1703 return;
1704 s += n;
1705 while (g_ascii_isspace (*s)) ++s;
1706
1707 if (strcmp (directive, "prefix") == 0)
1708 IDL_ns_prefix (__IDL_root_ns, s);
1709 else if (strcmp (directive, "ID") == 0)
1710 IDL_ns_ID (__IDL_root_ns, s);
1711 else if (strcmp (directive, "version") == 0)
1712 IDL_ns_version (__IDL_root_ns, s);
1713 else if (strcmp (directive, "inhibit") == 0)
1714 IDL_inhibit (__IDL_root_ns, s);
1715 else if (strcmp (directive, "typecodes_as_tok") == 0)
1716 IDL_typecodes_as_tok (__IDL_root_ns, s);
1717 else if (strcmp (directive, "pidl") == 0)
1718 IDL_pidl (__IDL_root_ns, s);
1719 }
1720
IDL_parse_declspec(const char * strspec)1721 static IDL_declspec_t IDL_parse_declspec (const char *strspec)
1722 {
1723 IDL_declspec_t flags = IDLF_DECLSPEC_EXIST;
1724
1725 if (strspec == NULL)
1726 return flags;
1727
1728 if (strcmp (strspec, "inhibit") == 0)
1729 flags |= IDLF_DECLSPEC_INHIBIT;
1730 if (strcmp (strspec, "pidl") == 0)
1731 flags |= IDLF_DECLSPEC_PIDL;
1732 else if (__IDL_is_parsing)
1733 yywarningv (IDL_WARNING1, "Ignoring unknown declspec `%s'", strspec);
1734
1735 return flags;
1736 }
1737
IDL_file_set(const char * filename,int line)1738 IDL_tree IDL_file_set (const char *filename, int line)
1739 {
1740 IDL_fileinfo *fi;
1741 IDL_tree tree = NULL;
1742
1743 g_return_val_if_fail (__IDL_is_parsing, NULL);
1744
1745 if (filename) {
1746 const char *oldfilename = __IDL_cur_filename;
1747 gboolean wasInhibit = IS_INHIBIT_STATE();
1748 gboolean isTop =
1749 #ifdef HAVE_CPP_PIPE_STDIN
1750 strlen (filename)==0;
1751 #else
1752 __IDL_tmp_filename &&
1753 strcmp (filename, __IDL_tmp_filename)==0;
1754 #endif
1755 if ( isTop ) {
1756 filename = __IDL_real_filename;
1757 __IDL_flagsi &= ~IDLFP_IN_INCLUDES;
1758 } else {
1759 __IDL_flagsi |= IDLFP_IN_INCLUDES;
1760 }
1761
1762 if ((fi=g_hash_table_lookup(__IDL_filename_hash, filename)) ) {
1763 __IDL_cur_fileinfo = fi;
1764 ++(fi->seenCnt);
1765 } else {
1766 fi = g_new0 (IDL_fileinfo, 1);
1767 fi->name = g_strdup(filename);
1768 g_hash_table_insert (__IDL_filename_hash, fi->name, fi);
1769 }
1770 __IDL_cur_fileinfo = fi;
1771 __IDL_cur_filename = fi->name;
1772 if ( (__IDL_flags & IDLF_SRCFILES)!=0
1773 && (oldfilename==0
1774 || strcmp(oldfilename,fi->name)!=0) ) {
1775 tree = IDL_srcfile_new(fi->name, fi->seenCnt, isTop, wasInhibit);
1776 }
1777 }
1778
1779 if (__IDL_cur_line > 0)
1780 __IDL_cur_line = line;
1781 return tree;
1782 }
1783
IDL_file_get(const char ** filename,int * line)1784 void IDL_file_get (const char **filename, int *line)
1785 {
1786 g_return_if_fail (__IDL_is_parsing);
1787
1788 if (filename)
1789 *filename = __IDL_cur_filename;
1790
1791 if (line)
1792 *line = __IDL_cur_line;
1793 }
1794
do_token_error(IDL_tree p,const char * message,gboolean prev)1795 static int do_token_error (IDL_tree p, const char *message, gboolean prev)
1796 {
1797 int dienow;
1798 char *what = NULL, *who = NULL;
1799
1800 assert (p != NULL);
1801
1802 dienow = IDL_tree_get_node_info (p, &what, &who);
1803
1804 assert (what != NULL);
1805
1806 if (who && *who)
1807 IDL_tree_error (p, "%s %s `%s'", message, what, who);
1808 else
1809 IDL_tree_error (p, "%s %s", message, what);
1810
1811 return dienow;
1812 }
1813
illegal_context_type_error(IDL_tree p,const char * what)1814 static void illegal_context_type_error (IDL_tree p, const char *what)
1815 {
1816 GString *s = g_string_new (NULL);
1817
1818 g_string_printf (s, "Illegal type `%%s' for %s", what);
1819 illegal_type_error (p, s->str);
1820 g_string_free (s, TRUE);
1821 }
1822
illegal_type_error(IDL_tree p,const char * message)1823 static void illegal_type_error (IDL_tree p, const char *message)
1824 {
1825 GString *s;
1826
1827 s = IDL_tree_to_IDL_string (p, NULL, IDLF_OUTPUT_NO_NEWLINES);
1828 yyerrorv (message, s->str);
1829 g_string_free (s, TRUE);
1830 }
1831
list_start(IDL_tree a,gboolean filter_null)1832 static IDL_tree list_start (IDL_tree a, gboolean filter_null)
1833 {
1834 IDL_tree p;
1835
1836 if (!a && filter_null)
1837 return NULL;
1838
1839 p = IDL_list_new (a);
1840
1841 return p;
1842 }
1843
list_chain(IDL_tree a,IDL_tree b,gboolean filter_null)1844 static IDL_tree list_chain (IDL_tree a, IDL_tree b, gboolean filter_null)
1845 {
1846 IDL_tree p;
1847
1848 if (filter_null) {
1849 if (!b)
1850 return a;
1851 if (!a)
1852 return list_start (b, filter_null);
1853 }
1854
1855 p = IDL_list_new (b);
1856 a = IDL_list_concat (a, p);
1857
1858 return a;
1859 }
1860
zlist_chain(IDL_tree a,IDL_tree b,gboolean filter_null)1861 static IDL_tree zlist_chain (IDL_tree a, IDL_tree b, gboolean filter_null)
1862 {
1863 if (a == NULL)
1864 return list_start (b, filter_null);
1865 else
1866 return list_chain (a, b, filter_null);
1867 }
1868
IDL_binop_chktypes(enum IDL_binop op,IDL_tree a,IDL_tree b)1869 static int IDL_binop_chktypes (enum IDL_binop op, IDL_tree a, IDL_tree b)
1870 {
1871 if (IDL_NODE_TYPE (a) != IDLN_BINOP &&
1872 IDL_NODE_TYPE (b) != IDLN_BINOP &&
1873 IDL_NODE_TYPE (a) != IDLN_UNARYOP &&
1874 IDL_NODE_TYPE (b) != IDLN_UNARYOP &&
1875 IDL_NODE_TYPE (a) != IDL_NODE_TYPE (b)) {
1876 yyerror ("Invalid mix of types in constant expression");
1877 return -1;
1878 }
1879
1880 switch (op) {
1881 case IDL_BINOP_MULT:
1882 case IDL_BINOP_DIV:
1883 case IDL_BINOP_ADD:
1884 case IDL_BINOP_SUB:
1885 break;
1886
1887 case IDL_BINOP_MOD:
1888 case IDL_BINOP_SHR:
1889 case IDL_BINOP_SHL:
1890 case IDL_BINOP_AND:
1891 case IDL_BINOP_OR:
1892 case IDL_BINOP_XOR:
1893 if ((IDL_NODE_TYPE (a) != IDLN_INTEGER ||
1894 IDL_NODE_TYPE (b) != IDLN_INTEGER) &&
1895 !(IDL_NODE_TYPE (a) == IDLN_BINOP ||
1896 IDL_NODE_TYPE (b) == IDLN_BINOP ||
1897 IDL_NODE_TYPE (a) == IDLN_UNARYOP ||
1898 IDL_NODE_TYPE (b) == IDLN_UNARYOP)) {
1899 yyerror ("Invalid operation on non-integer value");
1900 return -1;
1901 }
1902 break;
1903 }
1904
1905 return 0;
1906 }
1907
IDL_unaryop_chktypes(enum IDL_unaryop op,IDL_tree a)1908 static int IDL_unaryop_chktypes (enum IDL_unaryop op, IDL_tree a)
1909 {
1910 switch (op) {
1911 case IDL_UNARYOP_PLUS:
1912 case IDL_UNARYOP_MINUS:
1913 break;
1914
1915 case IDL_UNARYOP_COMPLEMENT:
1916 if (IDL_NODE_TYPE (a) != IDLN_INTEGER &&
1917 !(IDL_NODE_TYPE (a) == IDLN_BINOP ||
1918 IDL_NODE_TYPE (a) == IDLN_UNARYOP)) {
1919 yyerror ("Operand to complement must be integer");
1920 return -1;
1921 }
1922 break;
1923 }
1924
1925 return 0;
1926 }
1927
IDL_binop_eval_integer(enum IDL_binop op,IDL_tree a,IDL_tree b)1928 static IDL_tree IDL_binop_eval_integer (enum IDL_binop op, IDL_tree a, IDL_tree b)
1929 {
1930 IDL_tree p = NULL;
1931
1932 assert (IDL_NODE_TYPE (a) == IDLN_INTEGER);
1933
1934 switch (op) {
1935 case IDL_BINOP_MULT:
1936 p = IDL_integer_new (IDL_INTEGER (a).value * IDL_INTEGER (b).value);
1937 break;
1938
1939 case IDL_BINOP_DIV:
1940 if (IDL_INTEGER (b).value == 0) {
1941 yyerror ("Divide by zero in constant expression");
1942 return NULL;
1943 }
1944 p = IDL_integer_new (IDL_INTEGER (a).value / IDL_INTEGER (b).value);
1945 break;
1946
1947 case IDL_BINOP_ADD:
1948 p = IDL_integer_new (IDL_INTEGER (a).value + IDL_INTEGER (b).value);
1949 break;
1950
1951 case IDL_BINOP_SUB:
1952 p = IDL_integer_new (IDL_INTEGER (a).value - IDL_INTEGER (b).value);
1953 break;
1954
1955 case IDL_BINOP_MOD:
1956 if (IDL_INTEGER (b).value == 0) {
1957 yyerror ("Modulo by zero in constant expression");
1958 return NULL;
1959 }
1960 p = IDL_integer_new (IDL_INTEGER (a).value % IDL_INTEGER (b).value);
1961 break;
1962
1963 case IDL_BINOP_SHR:
1964 p = IDL_integer_new (IDL_INTEGER (a).value >> IDL_INTEGER (b).value);
1965 break;
1966
1967 case IDL_BINOP_SHL:
1968 p = IDL_integer_new (IDL_INTEGER (a).value << IDL_INTEGER (b).value);
1969 break;
1970
1971 case IDL_BINOP_AND:
1972 p = IDL_integer_new (IDL_INTEGER (a).value & IDL_INTEGER (b).value);
1973 break;
1974
1975 case IDL_BINOP_OR:
1976 p = IDL_integer_new (IDL_INTEGER (a).value | IDL_INTEGER (b).value);
1977 break;
1978
1979 case IDL_BINOP_XOR:
1980 p = IDL_integer_new (IDL_INTEGER (a).value ^ IDL_INTEGER (b).value);
1981 break;
1982 }
1983
1984 return p;
1985 }
1986
IDL_binop_eval_float(enum IDL_binop op,IDL_tree a,IDL_tree b)1987 static IDL_tree IDL_binop_eval_float (enum IDL_binop op, IDL_tree a, IDL_tree b)
1988 {
1989 IDL_tree p = NULL;
1990
1991 assert (IDL_NODE_TYPE (a) == IDLN_FLOAT);
1992
1993 switch (op) {
1994 case IDL_BINOP_MULT:
1995 p = IDL_float_new (IDL_FLOAT (a).value * IDL_FLOAT (b).value);
1996 break;
1997
1998 case IDL_BINOP_DIV:
1999 if (IDL_FLOAT (b).value == 0.0) {
2000 yyerror ("Divide by zero in constant expression");
2001 return NULL;
2002 }
2003 p = IDL_float_new (IDL_FLOAT (a).value / IDL_FLOAT (b).value);
2004 break;
2005
2006 case IDL_BINOP_ADD:
2007 p = IDL_float_new (IDL_FLOAT (a).value + IDL_FLOAT (b).value);
2008 break;
2009
2010 case IDL_BINOP_SUB:
2011 p = IDL_float_new (IDL_FLOAT (a).value - IDL_FLOAT (b).value);
2012 break;
2013
2014 default:
2015 break;
2016 }
2017
2018 return p;
2019 }
2020
IDL_binop_eval(enum IDL_binop op,IDL_tree a,IDL_tree b)2021 static IDL_tree IDL_binop_eval (enum IDL_binop op, IDL_tree a, IDL_tree b)
2022 {
2023 assert (IDL_NODE_TYPE (a) == IDL_NODE_TYPE (b));
2024
2025 switch (IDL_NODE_TYPE (a)) {
2026 case IDLN_INTEGER: return IDL_binop_eval_integer (op, a, b);
2027 case IDLN_FLOAT: return IDL_binop_eval_float (op, a, b);
2028 default: return NULL;
2029 }
2030 }
2031
IDL_unaryop_eval_integer(enum IDL_unaryop op,IDL_tree a)2032 static IDL_tree IDL_unaryop_eval_integer (enum IDL_unaryop op, IDL_tree a)
2033 {
2034 IDL_tree p = NULL;
2035
2036 assert (IDL_NODE_TYPE (a) == IDLN_INTEGER);
2037
2038 switch (op) {
2039 case IDL_UNARYOP_PLUS:
2040 p = IDL_integer_new (IDL_INTEGER (a).value);
2041 break;
2042
2043 case IDL_UNARYOP_MINUS:
2044 p = IDL_integer_new (-IDL_INTEGER (a).value);
2045 break;
2046
2047 case IDL_UNARYOP_COMPLEMENT:
2048 p = IDL_integer_new (~IDL_INTEGER (a).value);
2049 break;
2050 }
2051
2052 return p;
2053 }
2054
IDL_unaryop_eval_fixed(enum IDL_unaryop op,IDL_tree a)2055 static IDL_tree IDL_unaryop_eval_fixed (enum IDL_unaryop op, IDL_tree a)
2056 {
2057 IDL_tree p = NULL;
2058
2059 assert (IDL_NODE_TYPE (a) == IDLN_FIXED);
2060
2061 switch (op) {
2062 case IDL_UNARYOP_PLUS:
2063 p = IDL_fixed_new (IDL_FIXED (a).value);
2064 break;
2065
2066 default:
2067 break;
2068 }
2069
2070 return p;
2071 }
2072
IDL_unaryop_eval_float(enum IDL_unaryop op,IDL_tree a)2073 static IDL_tree IDL_unaryop_eval_float (enum IDL_unaryop op, IDL_tree a)
2074 {
2075 IDL_tree p = NULL;
2076
2077 assert (IDL_NODE_TYPE (a) == IDLN_FLOAT);
2078
2079 switch (op) {
2080 case IDL_UNARYOP_PLUS:
2081 p = IDL_float_new (IDL_FLOAT (a).value);
2082 break;
2083
2084 case IDL_UNARYOP_MINUS:
2085 p = IDL_float_new (-IDL_FLOAT (a).value);
2086 break;
2087
2088 default:
2089 break;
2090 }
2091
2092 return p;
2093 }
2094
IDL_unaryop_eval(enum IDL_unaryop op,IDL_tree a)2095 static IDL_tree IDL_unaryop_eval (enum IDL_unaryop op, IDL_tree a)
2096 {
2097 switch (IDL_NODE_TYPE (a)) {
2098 case IDLN_INTEGER: return IDL_unaryop_eval_integer (op, a);
2099 case IDLN_FIXED: return IDL_unaryop_eval_fixed (op, a);
2100 case IDLN_FLOAT: return IDL_unaryop_eval_float (op, a);
2101 default: return NULL;
2102 }
2103 }
2104
IDL_resolve_const_exp(IDL_tree p,IDL_tree_type type)2105 IDL_tree IDL_resolve_const_exp (IDL_tree p, IDL_tree_type type)
2106 {
2107 gboolean resolved_value = FALSE, die = FALSE;
2108 gboolean wrong_type = FALSE;
2109
2110 while (!resolved_value && !die) {
2111 if (IDL_NODE_TYPE (p) == IDLN_IDENT) {
2112 IDL_tree q = IDL_NODE_UP (p);
2113
2114 assert (q != NULL);
2115 if (IDL_NODE_UP (q) &&
2116 IDL_NODE_TYPE (IDL_NODE_UP (q)) == IDLN_TYPE_ENUM) {
2117 p = q;
2118 die = TRUE;
2119 break;
2120 } else if (IDL_NODE_TYPE (q) != IDLN_CONST_DCL) {
2121 p = q;
2122 wrong_type = TRUE;
2123 die = TRUE;
2124 } else
2125 p = IDL_CONST_DCL (q).const_exp;
2126 }
2127
2128 if (p == NULL ||
2129 IDL_NODE_TYPE (p) == IDLN_BINOP ||
2130 IDL_NODE_TYPE (p) == IDLN_UNARYOP) {
2131 die = TRUE;
2132 continue;
2133 }
2134
2135 resolved_value = IDL_NODE_IS_LITERAL (p);
2136 }
2137
2138 if (resolved_value &&
2139 type != IDLN_ANY &&
2140 IDL_NODE_TYPE (p) != type)
2141 wrong_type = TRUE;
2142
2143 if (wrong_type) {
2144 yyerror ("Invalid type for constant");
2145 IDL_tree_error (p, "Previous resolved type declaration");
2146 return NULL;
2147 }
2148
2149 return resolved_value ? p : NULL;
2150 }
2151
IDL_queue_new_ident_comment(const char * str)2152 void IDL_queue_new_ident_comment (const char *str)
2153 {
2154 g_return_if_fail (str != NULL);
2155
2156 __IDL_new_ident_comments = g_slist_append (__IDL_new_ident_comments, g_strdup (str));
2157 }
2158
2159 /*
2160 * Local variables:
2161 * mode: C
2162 * c-basic-offset: 8
2163 * tab-width: 8
2164 * indent-tabs-mode: t
2165 * End:
2166 */
2167