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.1.1.1 2002-12-26 17:10:40 ghudson 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 | $$ = 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 | $$ = 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 | | wide_char_type |
---|
851 | | boolean_type |
---|
852 | | floating_pt_type |
---|
853 | | string_type |
---|
854 | | wide_string_type |
---|
855 | | fixed_pt_const_type |
---|
856 | | scoped_name |
---|
857 | ; |
---|
858 | |
---|
859 | const_exp: or_expr |
---|
860 | ; |
---|
861 | |
---|
862 | or_expr: xor_expr |
---|
863 | | or_expr '|' xor_expr { do_binop ($$, IDL_BINOP_OR, $1, $3); } |
---|
864 | ; |
---|
865 | |
---|
866 | xor_expr: and_expr |
---|
867 | | xor_expr '^' and_expr { do_binop ($$, IDL_BINOP_XOR, $1, $3); } |
---|
868 | ; |
---|
869 | |
---|
870 | and_expr: shift_expr |
---|
871 | | and_expr '&' shift_expr { do_binop ($$, IDL_BINOP_AND, $1, $3); } |
---|
872 | ; |
---|
873 | |
---|
874 | shift_expr: add_expr |
---|
875 | | shift_expr TOK_OP_SHR add_expr { do_binop ($$, IDL_BINOP_SHR, $1, $3); } |
---|
876 | | shift_expr TOK_OP_SHL add_expr { do_binop ($$, IDL_BINOP_SHL, $1, $3); } |
---|
877 | ; |
---|
878 | |
---|
879 | add_expr: mult_expr |
---|
880 | | add_expr '+' mult_expr { do_binop ($$, IDL_BINOP_ADD, $1, $3); } |
---|
881 | | add_expr '-' mult_expr { do_binop ($$, IDL_BINOP_SUB, $1, $3); } |
---|
882 | ; |
---|
883 | |
---|
884 | mult_expr: unary_expr |
---|
885 | | mult_expr '*' unary_expr { do_binop ($$, IDL_BINOP_MULT, $1, $3); } |
---|
886 | | mult_expr '/' unary_expr { do_binop ($$, IDL_BINOP_DIV, $1, $3); } |
---|
887 | | mult_expr '%' unary_expr { do_binop ($$, IDL_BINOP_MOD, $1, $3); } |
---|
888 | ; |
---|
889 | |
---|
890 | unary_expr: unary_op primary_expr { do_unaryop ($$, $1, $2); } |
---|
891 | | primary_expr |
---|
892 | ; |
---|
893 | |
---|
894 | unary_op: '-' { $$ = IDL_UNARYOP_MINUS; } |
---|
895 | | '+' { $$ = IDL_UNARYOP_PLUS; } |
---|
896 | | '~' { $$ = IDL_UNARYOP_COMPLEMENT; } |
---|
897 | ; |
---|
898 | |
---|
899 | primary_expr: scoped_name { |
---|
900 | IDL_tree p, literal; |
---|
901 | |
---|
902 | assert (IDL_NODE_TYPE ($1) == IDLN_IDENT); |
---|
903 | |
---|
904 | p = IDL_NODE_UP ($1); |
---|
905 | |
---|
906 | if ((literal = IDL_resolve_const_exp ($1, IDLN_ANY))) { |
---|
907 | ++IDL_NODE_REFS (literal); |
---|
908 | $$ = literal; |
---|
909 | IDL_tree_free ($1); |
---|
910 | } else |
---|
911 | $$ = $1; |
---|
912 | } |
---|
913 | | literal |
---|
914 | | '(' const_exp ')' { $$ = $2; } |
---|
915 | ; |
---|
916 | |
---|
917 | literal: integer_lit |
---|
918 | | string_lit |
---|
919 | | char_lit |
---|
920 | | fixed_pt_lit |
---|
921 | | floating_pt_lit |
---|
922 | | boolean_lit |
---|
923 | ; |
---|
924 | |
---|
925 | enum_type: z_props TOK_ENUM |
---|
926 | { $<str>$ = "enum"; } |
---|
927 | z_new_ident_catch '{' |
---|
928 | enumerator_list |
---|
929 | '}' { |
---|
930 | $$ = IDL_type_enum_new ($4, $6); |
---|
931 | assign_props (IDL_TYPE_ENUM ($$).ident, $1); |
---|
932 | } |
---|
933 | ; |
---|
934 | |
---|
935 | scoped_name: ns_scoped_name { |
---|
936 | assert ($1 != NULL); |
---|
937 | assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE); |
---|
938 | assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT); |
---|
939 | $$ = IDL_GENTREE ($1).data; |
---|
940 | } |
---|
941 | ; |
---|
942 | |
---|
943 | ns_scoped_name: ns_prev_ident |
---|
944 | | TOK_OP_SCOPE ns_global_ident { $$ = $2; } |
---|
945 | | ns_scoped_name TOK_OP_SCOPE |
---|
946 | ident { |
---|
947 | IDL_tree p; |
---|
948 | |
---|
949 | assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE); |
---|
950 | assert (IDL_NODE_TYPE ($3) == IDLN_IDENT); |
---|
951 | |
---|
952 | #ifdef YYDEBUG |
---|
953 | if (yydebug) |
---|
954 | fprintf (stderr, "ns: looking in `%s' for `%s'\n", |
---|
955 | IDL_IDENT (IDL_GENTREE ($1).data).str, IDL_IDENT($3).str); |
---|
956 | #endif |
---|
957 | |
---|
958 | if ((p = IDL_ns_lookup_this_scope (__IDL_root_ns, $1, $3, NULL)) == NULL) { |
---|
959 | yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($3).str); |
---|
960 | IDL_tree_free ($3); |
---|
961 | YYABORT; |
---|
962 | } |
---|
963 | IDL_tree_free ($3); |
---|
964 | #ifdef REF_IDENTS |
---|
965 | ++IDL_NODE_REFS (IDL_GENTREE (p).data); |
---|
966 | #endif |
---|
967 | $$ = p; |
---|
968 | } |
---|
969 | ; |
---|
970 | |
---|
971 | enumerator_list: new_ident { $$ = list_start ($1, TRUE); } |
---|
972 | | enumerator_list |
---|
973 | check_comma new_ident { $$ = list_chain ($1, $3, TRUE); } |
---|
974 | ; |
---|
975 | |
---|
976 | member_list: member { $$ = list_start ($1, TRUE); } |
---|
977 | | member_list member { $$ = list_chain ($1, $2, TRUE); } |
---|
978 | ; |
---|
979 | |
---|
980 | member: type_spec declarator_list |
---|
981 | check_semicolon { |
---|
982 | char *s; |
---|
983 | |
---|
984 | $$ = IDL_member_new ($1, $2); |
---|
985 | if (IDL_NODE_TYPE ($1) == IDLN_IDENT && |
---|
986 | g_hash_table_lookup (__IDL_structunion_ht, $1)) { |
---|
987 | s = IDL_ns_ident_to_qstring (IDL_LIST ($2).data, "::", 0); |
---|
988 | yyerrorv ("Member `%s'", s); |
---|
989 | do_token_error (IDL_NODE_UP ($1), "recurses", TRUE); |
---|
990 | g_free (s); |
---|
991 | } |
---|
992 | } |
---|
993 | ; |
---|
994 | |
---|
995 | base_type_spec: floating_pt_type |
---|
996 | | integer_type |
---|
997 | | char_type |
---|
998 | | wide_char_type |
---|
999 | | boolean_type |
---|
1000 | | octet_type |
---|
1001 | | any_type |
---|
1002 | | object_type |
---|
1003 | | typecode_type |
---|
1004 | ; |
---|
1005 | |
---|
1006 | template_type_spec: sequence_type |
---|
1007 | | string_type |
---|
1008 | | wide_string_type |
---|
1009 | | fixed_pt_type |
---|
1010 | ; |
---|
1011 | |
---|
1012 | sequence_type: TOK_SEQUENCE '<' |
---|
1013 | simple_type_spec ',' positive_int_const |
---|
1014 | '>' { $$ = IDL_type_sequence_new ($3, $5); } |
---|
1015 | | TOK_SEQUENCE '<' |
---|
1016 | simple_type_spec |
---|
1017 | '>' { $$ = IDL_type_sequence_new ($3, NULL); } |
---|
1018 | ; |
---|
1019 | |
---|
1020 | floating_pt_type: TOK_FLOAT { $$ = IDL_type_float_new (IDL_FLOAT_TYPE_FLOAT); } |
---|
1021 | | TOK_DOUBLE { $$ = IDL_type_float_new (IDL_FLOAT_TYPE_DOUBLE); } |
---|
1022 | | TOK_LONG TOK_DOUBLE { $$ = IDL_type_float_new (IDL_FLOAT_TYPE_LONGDOUBLE); } |
---|
1023 | ; |
---|
1024 | |
---|
1025 | fixed_pt_type: TOK_FIXED '<' |
---|
1026 | positive_int_const ',' integer_lit |
---|
1027 | '>' { $$ = IDL_type_fixed_new ($3, $5); } |
---|
1028 | ; |
---|
1029 | |
---|
1030 | fixed_pt_const_type: TOK_FIXED { $$ = IDL_type_fixed_new (NULL, NULL); } |
---|
1031 | ; |
---|
1032 | |
---|
1033 | integer_type: signed_int { $$ = IDL_type_integer_new (TRUE, $1); } |
---|
1034 | | unsigned_int { $$ = IDL_type_integer_new (FALSE, $1); } |
---|
1035 | ; |
---|
1036 | |
---|
1037 | signed_int: signed_short_int { $$ = IDL_INTEGER_TYPE_SHORT; } |
---|
1038 | | signed_long_int { $$ = IDL_INTEGER_TYPE_LONG; } |
---|
1039 | | signed_longlong_int { $$ = IDL_INTEGER_TYPE_LONGLONG; } |
---|
1040 | ; |
---|
1041 | |
---|
1042 | signed_short_int: TOK_SHORT |
---|
1043 | ; |
---|
1044 | |
---|
1045 | signed_long_int: TOK_LONG |
---|
1046 | ; |
---|
1047 | |
---|
1048 | signed_longlong_int: TOK_LONG TOK_LONG |
---|
1049 | ; |
---|
1050 | |
---|
1051 | unsigned_int: unsigned_short_int { $$ = IDL_INTEGER_TYPE_SHORT; } |
---|
1052 | | unsigned_long_int { $$ = IDL_INTEGER_TYPE_LONG; } |
---|
1053 | | unsigned_longlong_int { $$ = IDL_INTEGER_TYPE_LONGLONG; } |
---|
1054 | ; |
---|
1055 | |
---|
1056 | unsigned_short_int: TOK_UNSIGNED TOK_SHORT |
---|
1057 | ; |
---|
1058 | |
---|
1059 | unsigned_long_int: TOK_UNSIGNED TOK_LONG |
---|
1060 | ; |
---|
1061 | |
---|
1062 | unsigned_longlong_int: TOK_UNSIGNED TOK_LONG TOK_LONG |
---|
1063 | ; |
---|
1064 | |
---|
1065 | char_type: TOK_CHAR { $$ = IDL_type_char_new (); } |
---|
1066 | ; |
---|
1067 | |
---|
1068 | wide_char_type: TOK_WCHAR { $$ = IDL_type_wide_char_new (); } |
---|
1069 | ; |
---|
1070 | |
---|
1071 | boolean_type: TOK_BOOLEAN { $$ = IDL_type_boolean_new (); } |
---|
1072 | ; |
---|
1073 | |
---|
1074 | octet_type: TOK_OCTET { $$ = IDL_type_octet_new (); } |
---|
1075 | ; |
---|
1076 | |
---|
1077 | any_type: TOK_ANY { $$ = IDL_type_any_new (); } |
---|
1078 | ; |
---|
1079 | |
---|
1080 | object_type: TOK_OBJECT { $$ = IDL_type_object_new (); } |
---|
1081 | ; |
---|
1082 | |
---|
1083 | typecode_type: TOK_TYPECODE { $$ = IDL_type_typecode_new (); } |
---|
1084 | ; |
---|
1085 | |
---|
1086 | string_type: TOK_STRING '<' |
---|
1087 | positive_int_const |
---|
1088 | '>' { $$ = IDL_type_string_new ($3); } |
---|
1089 | | TOK_STRING { $$ = IDL_type_string_new (NULL); } |
---|
1090 | ; |
---|
1091 | |
---|
1092 | wide_string_type: TOK_WSTRING '<' |
---|
1093 | positive_int_const |
---|
1094 | '>' { $$ = IDL_type_wide_string_new ($3); } |
---|
1095 | | TOK_WSTRING { $$ = IDL_type_wide_string_new (NULL); } |
---|
1096 | ; |
---|
1097 | |
---|
1098 | declarator_list: declarator { $$ = list_start ($1, TRUE); } |
---|
1099 | | declarator_list |
---|
1100 | check_comma declarator { $$ = list_chain ($1, $3, TRUE); } |
---|
1101 | ; |
---|
1102 | |
---|
1103 | declarator: simple_declarator |
---|
1104 | | complex_declarator |
---|
1105 | ; |
---|
1106 | |
---|
1107 | simple_declarator: new_ident |
---|
1108 | ; |
---|
1109 | |
---|
1110 | complex_declarator: array_declarator |
---|
1111 | ; |
---|
1112 | |
---|
1113 | simple_declarator_list: simple_declarator { $$ = list_start ($1, TRUE); } |
---|
1114 | | simple_declarator_list |
---|
1115 | check_comma simple_declarator { $$ = list_chain ($1, $3, TRUE); } |
---|
1116 | ; |
---|
1117 | |
---|
1118 | array_declarator: new_ident |
---|
1119 | fixed_array_size_list { |
---|
1120 | IDL_tree p; |
---|
1121 | int i; |
---|
1122 | |
---|
1123 | $$ = IDL_type_array_new ($1, $2); |
---|
1124 | for (i = 1, p = $2; p; ++i, p = IDL_LIST (p).next) |
---|
1125 | if (!IDL_LIST (p).data) { |
---|
1126 | char *s = IDL_ns_ident_to_qstring ($1, "::", 0); |
---|
1127 | yyerrorv ("Missing value in dimension %d of array `%s'", i, s); |
---|
1128 | g_free (s); |
---|
1129 | } |
---|
1130 | } |
---|
1131 | ; |
---|
1132 | |
---|
1133 | fixed_array_size_list: fixed_array_size { $$ = list_start ($1, FALSE); } |
---|
1134 | | fixed_array_size_list |
---|
1135 | fixed_array_size { $$ = list_chain ($1, $2, FALSE); } |
---|
1136 | ; |
---|
1137 | |
---|
1138 | fixed_array_size: '[' positive_int_const ']' { $$ = $2; } |
---|
1139 | | '[' ']' { $$ = NULL; } |
---|
1140 | ; |
---|
1141 | |
---|
1142 | prop_hash: TOK_PROP_KEY |
---|
1143 | TOK_PROP_VALUE { |
---|
1144 | $$ = g_hash_table_new (IDL_strcase_hash, IDL_strcase_equal); |
---|
1145 | g_hash_table_insert ($$, $1, $2); |
---|
1146 | } |
---|
1147 | | prop_hash ',' |
---|
1148 | TOK_PROP_KEY |
---|
1149 | TOK_PROP_VALUE { |
---|
1150 | $$ = $1; |
---|
1151 | g_hash_table_insert ($$, $3, $4); |
---|
1152 | } |
---|
1153 | | TOK_PROP_KEY { |
---|
1154 | $$ = g_hash_table_new (IDL_strcase_hash, IDL_strcase_equal); |
---|
1155 | g_hash_table_insert ($$, $1, g_strdup ("")); |
---|
1156 | } |
---|
1157 | | prop_hash ',' |
---|
1158 | TOK_PROP_KEY { |
---|
1159 | $$ = $1; |
---|
1160 | g_hash_table_insert ($$, $3, g_strdup ("")); |
---|
1161 | } |
---|
1162 | ; |
---|
1163 | |
---|
1164 | ident: TOK_IDENT { $$ = IDL_ident_new ($1); } |
---|
1165 | ; |
---|
1166 | |
---|
1167 | new_ident: ns_new_ident { |
---|
1168 | assert ($1 != NULL); |
---|
1169 | assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE); |
---|
1170 | assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT); |
---|
1171 | $$ = IDL_GENTREE ($1).data; |
---|
1172 | } |
---|
1173 | ; |
---|
1174 | |
---|
1175 | new_scope: ns_new_ident { |
---|
1176 | IDL_tree old_top = IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data; |
---|
1177 | IDL_ns_push_scope (__IDL_root_ns, $1); |
---|
1178 | #ifdef YYDEBUG |
---|
1179 | if (yydebug) |
---|
1180 | fprintf (stderr, "ns: entering new scope `%s' of `%s'\n", |
---|
1181 | IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str, IDL_IDENT(old_top).str); |
---|
1182 | #endif |
---|
1183 | assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT); |
---|
1184 | $$ = IDL_GENTREE ($1).data; |
---|
1185 | } |
---|
1186 | ; |
---|
1187 | |
---|
1188 | new_or_prev_scope: cur_ns_new_or_prev_ident { |
---|
1189 | IDL_tree old_top = IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data; |
---|
1190 | IDL_ns_push_scope (__IDL_root_ns, $1); |
---|
1191 | assert (IDL_NS (__IDL_root_ns).current != NULL); |
---|
1192 | assert (IDL_NODE_TYPE (IDL_NS (__IDL_root_ns).current) == IDLN_GENTREE); |
---|
1193 | assert (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data != NULL); |
---|
1194 | assert (IDL_NODE_TYPE (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data) == IDLN_IDENT); |
---|
1195 | #ifdef YYDEBUG |
---|
1196 | if (yydebug) |
---|
1197 | fprintf (stderr,"ns: entering new/prev scope `%s' of `%s'\n", |
---|
1198 | IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str, IDL_IDENT(old_top).str); |
---|
1199 | #endif |
---|
1200 | assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT); |
---|
1201 | $$ = IDL_GENTREE ($1).data; |
---|
1202 | } |
---|
1203 | ; |
---|
1204 | |
---|
1205 | pop_scope: /* empty */ { |
---|
1206 | IDL_tree cur_top = IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data; |
---|
1207 | IDL_ns_pop_scope (__IDL_root_ns); |
---|
1208 | #ifdef YYDEBUG |
---|
1209 | if (yydebug) |
---|
1210 | fprintf (stderr, "ns: pop scope from `%s' to `%s'\n", |
---|
1211 | IDL_IDENT(cur_top).str, |
---|
1212 | IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str); |
---|
1213 | #endif |
---|
1214 | } |
---|
1215 | ; |
---|
1216 | |
---|
1217 | ns_new_ident: ident { |
---|
1218 | IDL_tree p; |
---|
1219 | |
---|
1220 | if ((p = IDL_ns_place_new (__IDL_root_ns, $1)) == NULL) { |
---|
1221 | IDL_tree q; |
---|
1222 | int i; |
---|
1223 | |
---|
1224 | p = IDL_ns_lookup_cur_scope (__IDL_root_ns, $1, NULL); |
---|
1225 | |
---|
1226 | for (i = 0, q = IDL_GENTREE (p).data; |
---|
1227 | q && (IDL_NODE_TYPE (q) == IDLN_IDENT || |
---|
1228 | IDL_NODE_TYPE (q) == IDLN_LIST) && i < 4; |
---|
1229 | ++i) |
---|
1230 | if (IDL_NODE_UP (q)) |
---|
1231 | q = IDL_NODE_UP (q); |
---|
1232 | |
---|
1233 | if (q) { |
---|
1234 | IDL_tree_error ($1, "`%s' conflicts", IDL_IDENT ($1).str); |
---|
1235 | do_token_error (q, "with", FALSE); |
---|
1236 | } else |
---|
1237 | yyerrorv ("`%s' duplicate identifier", IDL_IDENT ($1).str); |
---|
1238 | |
---|
1239 | IDL_tree_free ($1); |
---|
1240 | YYABORT; |
---|
1241 | } |
---|
1242 | assert (IDL_IDENT ($1)._ns_ref == p); |
---|
1243 | #ifdef REF_IDENTS |
---|
1244 | ++IDL_NODE_REFS (IDL_GENTREE (p).data); |
---|
1245 | #endif |
---|
1246 | if (__IDL_new_ident_comments != NULL) { |
---|
1247 | assert (IDL_IDENT ($1).comments == NULL); |
---|
1248 | IDL_IDENT ($1).comments = __IDL_new_ident_comments; |
---|
1249 | __IDL_new_ident_comments = NULL; |
---|
1250 | } |
---|
1251 | $$ = p; |
---|
1252 | } |
---|
1253 | ; |
---|
1254 | |
---|
1255 | ns_prev_ident: ident { |
---|
1256 | IDL_tree p; |
---|
1257 | |
---|
1258 | if ((p = IDL_ns_resolve_ident (__IDL_root_ns, $1)) == NULL) { |
---|
1259 | yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($1).str); |
---|
1260 | IDL_tree_free ($1); |
---|
1261 | YYABORT; |
---|
1262 | } |
---|
1263 | IDL_tree_free ($1); |
---|
1264 | assert (IDL_GENTREE (p).data != NULL); |
---|
1265 | assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p); |
---|
1266 | #ifdef REF_IDENTS |
---|
1267 | ++IDL_NODE_REFS (IDL_GENTREE (p).data); |
---|
1268 | #endif |
---|
1269 | $$ = p; |
---|
1270 | } |
---|
1271 | ; |
---|
1272 | |
---|
1273 | cur_ns_new_or_prev_ident: |
---|
1274 | ident { |
---|
1275 | IDL_tree p; |
---|
1276 | |
---|
1277 | if ((p = IDL_ns_lookup_cur_scope (__IDL_root_ns, $1, NULL)) == NULL) { |
---|
1278 | #ifdef YYDEBUG |
---|
1279 | if (yydebug) |
---|
1280 | fprintf (stderr, "ns: place_new `%s' in `%s'\n", |
---|
1281 | IDL_IDENT($1).str, |
---|
1282 | IDL_IDENT(IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str ); |
---|
1283 | #endif |
---|
1284 | p = IDL_ns_place_new (__IDL_root_ns, $1); |
---|
1285 | assert (p != NULL); |
---|
1286 | assert (IDL_IDENT ($1)._ns_ref == p); |
---|
1287 | if (__IDL_new_ident_comments != NULL) { |
---|
1288 | assert (IDL_IDENT ($1).comments == NULL); |
---|
1289 | IDL_IDENT ($1).comments = __IDL_new_ident_comments; |
---|
1290 | __IDL_new_ident_comments = NULL; |
---|
1291 | } |
---|
1292 | } else { |
---|
1293 | IDL_tree_free ($1); |
---|
1294 | assert (IDL_GENTREE (p).data != NULL); |
---|
1295 | assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p); |
---|
1296 | } |
---|
1297 | #ifdef REF_IDENTS |
---|
1298 | ++IDL_NODE_REFS (IDL_GENTREE (p).data); |
---|
1299 | #endif |
---|
1300 | $$ = p; |
---|
1301 | } |
---|
1302 | ; |
---|
1303 | |
---|
1304 | ns_global_ident: ident { |
---|
1305 | IDL_tree p; |
---|
1306 | |
---|
1307 | if ((p = IDL_ns_lookup_this_scope ( |
---|
1308 | __IDL_root_ns,IDL_NS (__IDL_root_ns).file, $1, NULL)) == NULL) { |
---|
1309 | yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($1).str); |
---|
1310 | IDL_tree_free ($1); |
---|
1311 | YYABORT; |
---|
1312 | } |
---|
1313 | IDL_tree_free ($1); |
---|
1314 | assert (IDL_GENTREE (p).data != NULL); |
---|
1315 | assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p); |
---|
1316 | #ifdef REF_IDENTS |
---|
1317 | ++IDL_NODE_REFS (IDL_GENTREE (p).data); |
---|
1318 | #endif |
---|
1319 | $$ = p; |
---|
1320 | } |
---|
1321 | ; |
---|
1322 | |
---|
1323 | string_lit_list: string_lit { $$ = list_start ($1, TRUE); } |
---|
1324 | | string_lit_list |
---|
1325 | check_comma string_lit { $$ = list_chain ($1, $3, TRUE); } |
---|
1326 | ; |
---|
1327 | |
---|
1328 | positive_int_const: const_exp { |
---|
1329 | IDL_tree literal, ident = NULL; |
---|
1330 | IDL_longlong_t value = 0; |
---|
1331 | |
---|
1332 | if ((literal = IDL_resolve_const_exp ($1, IDLN_INTEGER))) { |
---|
1333 | assert (IDL_NODE_TYPE (literal) == IDLN_INTEGER); |
---|
1334 | ++IDL_NODE_REFS (literal); |
---|
1335 | value = IDL_INTEGER (literal).value; |
---|
1336 | if ( literal != $1 ) |
---|
1337 | IDL_tree_free ($1); |
---|
1338 | } |
---|
1339 | |
---|
1340 | if (literal && IDL_NODE_UP (literal) && |
---|
1341 | IDL_NODE_TYPE (IDL_NODE_UP (literal)) == IDLN_CONST_DCL) |
---|
1342 | ident = IDL_CONST_DCL (IDL_NODE_UP (literal)).ident; |
---|
1343 | |
---|
1344 | if (literal == NULL) { |
---|
1345 | if (!(__IDL_flags & IDLF_NO_EVAL_CONST)) |
---|
1346 | yyerror ("Could not resolve constant expression"); |
---|
1347 | $$ = $1; |
---|
1348 | } else if (value == 0) { |
---|
1349 | yyerror ("Zero array size is illegal"); |
---|
1350 | if (ident) |
---|
1351 | IDL_tree_error (ident, "From constant declared here"); |
---|
1352 | $$ = NULL; |
---|
1353 | } else if (value < 0) { |
---|
1354 | yywarningv (IDL_WARNING1, "Cannot use negative value %" |
---|
1355 | IDL_LL "d, using %" IDL_LL "d", |
---|
1356 | value, -value); |
---|
1357 | if (ident) |
---|
1358 | IDL_tree_warning (ident, |
---|
1359 | IDL_WARNING1, "From constant declared here"); |
---|
1360 | $$ = IDL_integer_new (-value); |
---|
1361 | } |
---|
1362 | else |
---|
1363 | $$ = IDL_integer_new (value); |
---|
1364 | } |
---|
1365 | ; |
---|
1366 | |
---|
1367 | z_declspec: /* empty */ { $$ = 0; } |
---|
1368 | | TOK_DECLSPEC { |
---|
1369 | $$ = IDL_parse_declspec ($1); |
---|
1370 | g_free ($1); |
---|
1371 | } |
---|
1372 | ; |
---|
1373 | |
---|
1374 | z_props: /* empty */ { $$ = NULL; } |
---|
1375 | | '[' { |
---|
1376 | /* Enable property scanning */ |
---|
1377 | if (__IDL_flags & IDLF_PROPERTIES) |
---|
1378 | __IDL_flagsi |= IDLFP_PROPERTIES; |
---|
1379 | else { |
---|
1380 | yyerror ("Property syntax not enabled"); |
---|
1381 | YYABORT; |
---|
1382 | } |
---|
1383 | } prop_hash |
---|
1384 | ']' { $$ = $3; } |
---|
1385 | ; |
---|
1386 | |
---|
1387 | integer_lit: TOK_INTEGER { $$ = IDL_integer_new ($1); } |
---|
1388 | ; |
---|
1389 | |
---|
1390 | string_lit: dqstring_cat { $$ = IDL_string_new ($1); } |
---|
1391 | ; |
---|
1392 | |
---|
1393 | char_lit: sqstring { $$ = IDL_char_new ($1); } |
---|
1394 | ; |
---|
1395 | |
---|
1396 | fixed_pt_lit: TOK_FIXEDP { $$ = IDL_fixed_new ($1); } |
---|
1397 | ; |
---|
1398 | |
---|
1399 | floating_pt_lit: TOK_FLOATP { $$ = IDL_float_new ($1); } |
---|
1400 | ; |
---|
1401 | |
---|
1402 | boolean_lit: TOK_TRUE { $$ = IDL_boolean_new (TRUE); } |
---|
1403 | | TOK_FALSE { $$ = IDL_boolean_new (FALSE); } |
---|
1404 | ; |
---|
1405 | |
---|
1406 | codefrag: z_declspec TOK_CODEFRAG { |
---|
1407 | $$ = $2; |
---|
1408 | assign_declspec ($$, $1); |
---|
1409 | } |
---|
1410 | ; |
---|
1411 | |
---|
1412 | srcfile: TOK_SRCFILE { |
---|
1413 | $$ = $1; |
---|
1414 | } |
---|
1415 | ; |
---|
1416 | |
---|
1417 | dqstring_cat: dqstring |
---|
1418 | | dqstring_cat dqstring { |
---|
1419 | char *catstr = g_malloc (strlen ($1) + strlen ($2) + 1); |
---|
1420 | strcpy (catstr, $1); g_free ($1); |
---|
1421 | strcat (catstr, $2); g_free ($2); |
---|
1422 | $$ = catstr; |
---|
1423 | } |
---|
1424 | ; |
---|
1425 | |
---|
1426 | dqstring: TOK_DQSTRING { |
---|
1427 | char *s = IDL_do_escapes ($1); |
---|
1428 | g_free ($1); |
---|
1429 | $$ = s; |
---|
1430 | } |
---|
1431 | ; |
---|
1432 | |
---|
1433 | sqstring: TOK_SQSTRING { |
---|
1434 | char *s = IDL_do_escapes ($1); |
---|
1435 | g_free ($1); |
---|
1436 | $$ = s; |
---|
1437 | } |
---|
1438 | ; |
---|
1439 | |
---|
1440 | %% |
---|
1441 | |
---|
1442 | void __IDL_parser_reset (void) |
---|
1443 | { |
---|
1444 | yyclearin; |
---|
1445 | } |
---|
1446 | |
---|
1447 | static const char *IDL_ns_get_cur_prefix (IDL_ns ns) |
---|
1448 | { |
---|
1449 | IDL_tree p; |
---|
1450 | |
---|
1451 | p = IDL_NS (ns).current; |
---|
1452 | |
---|
1453 | assert (p != NULL); |
---|
1454 | |
---|
1455 | while (p && !IDL_GENTREE (p)._cur_prefix) |
---|
1456 | p = IDL_NODE_UP (p); |
---|
1457 | |
---|
1458 | return p ? IDL_GENTREE (p)._cur_prefix : NULL; |
---|
1459 | } |
---|
1460 | |
---|
1461 | gchar *IDL_ns_ident_make_repo_id (IDL_ns ns, IDL_tree p, |
---|
1462 | const char *p_prefix, int *major, int *minor) |
---|
1463 | { |
---|
1464 | GString *s = g_string_new (NULL); |
---|
1465 | const char *prefix; |
---|
1466 | char *q; |
---|
1467 | |
---|
1468 | assert (p != NULL); |
---|
1469 | |
---|
1470 | if (IDL_NODE_TYPE (p) == IDLN_IDENT) |
---|
1471 | p = IDL_IDENT_TO_NS (p); |
---|
1472 | |
---|
1473 | assert (p != NULL); |
---|
1474 | |
---|
1475 | prefix = p_prefix ? p_prefix : IDL_ns_get_cur_prefix (ns); |
---|
1476 | |
---|
1477 | q = IDL_ns_ident_to_qstring (p, "/", 0); |
---|
1478 | g_string_printf (s, "IDL:%s%s%s:%d.%d", |
---|
1479 | prefix ? prefix : "", |
---|
1480 | prefix && *prefix ? "/" : "", |
---|
1481 | q, |
---|
1482 | major ? *major : 1, |
---|
1483 | minor ? *minor : 0); |
---|
1484 | g_free (q); |
---|
1485 | |
---|
1486 | q = s->str; |
---|
1487 | g_string_free (s, FALSE); |
---|
1488 | |
---|
1489 | return q; |
---|
1490 | } |
---|
1491 | |
---|
1492 | static const char *get_name_token (const char *s, char **tok) |
---|
1493 | { |
---|
1494 | const char *begin = s; |
---|
1495 | int state = 0; |
---|
1496 | |
---|
1497 | if (!s) |
---|
1498 | return NULL; |
---|
1499 | |
---|
1500 | while (g_ascii_isspace (*s)) ++s; |
---|
1501 | |
---|
1502 | while (1) switch (state) { |
---|
1503 | case 0: /* Unknown */ |
---|
1504 | if (*s == ':') |
---|
1505 | state = 1; |
---|
1506 | else if (isalnum ((int)*s) || *s == '_') { |
---|
1507 | begin = s; |
---|
1508 | state = 2; |
---|
1509 | } else |
---|
1510 | return NULL; |
---|
1511 | break; |
---|
1512 | case 1: /* Scope */ |
---|
1513 | if (strncmp (s, "::", 2) == 0) { |
---|
1514 | char *r = g_malloc (3); |
---|
1515 | strcpy (r, "::"); |
---|
1516 | *tok = r; |
---|
1517 | return s + 2; |
---|
1518 | } else /* Invalid */ |
---|
1519 | return NULL; |
---|
1520 | break; |
---|
1521 | case 2: |
---|
1522 | if (isalnum ((int)*s) || *s == '_') |
---|
1523 | ++s; |
---|
1524 | else { |
---|
1525 | char *r = g_malloc (s - begin + 1); |
---|
1526 | strncpy (r, begin, s - begin + 1); |
---|
1527 | r[s - begin] = 0; |
---|
1528 | *tok = r; |
---|
1529 | return s; |
---|
1530 | } |
---|
1531 | break; |
---|
1532 | } |
---|
1533 | } |
---|
1534 | |
---|
1535 | static IDL_tree IDL_ns_pragma_parse_name (IDL_ns ns, const char *s) |
---|
1536 | { |
---|
1537 | IDL_tree p = IDL_NS (ns).current, q; |
---|
1538 | int start = 1; |
---|
1539 | char *tok; |
---|
1540 | |
---|
1541 | /* This is a hack to allow directives for an ident (such |
---|
1542 | * as and interface) to be located within the scope of |
---|
1543 | * that identifier. */ |
---|
1544 | if ( p && (q=IDL_GENTREE(p).data)!=0 |
---|
1545 | && IDL_NODE_TYPE(q)==IDLN_IDENT |
---|
1546 | && strcmp(s,IDL_IDENT(q).str)==0 ) { |
---|
1547 | return p; |
---|
1548 | } |
---|
1549 | |
---|
1550 | while (p && *s && (s = get_name_token (s, &tok))) { |
---|
1551 | if (tok == NULL) |
---|
1552 | return NULL; |
---|
1553 | if (strcmp (tok, "::") == 0) { |
---|
1554 | if (start) { |
---|
1555 | /* Globally scoped */ |
---|
1556 | p = IDL_NS (ns).file; |
---|
1557 | } |
---|
1558 | g_free (tok); |
---|
1559 | } else { |
---|
1560 | IDL_tree ident = IDL_ident_new (tok); |
---|
1561 | p = IDL_ns_lookup_this_scope (__IDL_root_ns, p, ident, NULL); |
---|
1562 | IDL_tree_free (ident); |
---|
1563 | } |
---|
1564 | start = 0; |
---|
1565 | } |
---|
1566 | |
---|
1567 | return p; |
---|
1568 | } |
---|
1569 | |
---|
1570 | void IDL_ns_ID (IDL_ns ns, const char *s) |
---|
1571 | { |
---|
1572 | char name[1024], id[1024]; |
---|
1573 | IDL_tree p, ident; |
---|
1574 | int n; |
---|
1575 | |
---|
1576 | n = sscanf (s, "%1023s \"%1023s\"", name, id); |
---|
1577 | if (n < 2 && __IDL_is_parsing) { |
---|
1578 | yywarning (IDL_WARNING1, "Malformed pragma ID"); |
---|
1579 | return; |
---|
1580 | } |
---|
1581 | if (id[strlen (id) - 1] == '"') |
---|
1582 | id[strlen (id) - 1] = 0; |
---|
1583 | |
---|
1584 | p = IDL_ns_pragma_parse_name (__IDL_root_ns, name); |
---|
1585 | if (!p && __IDL_is_parsing) { |
---|
1586 | yywarningv (IDL_WARNING1, "Unknown identifier `%s' in pragma ID", name); |
---|
1587 | return; |
---|
1588 | } |
---|
1589 | |
---|
1590 | /* We have resolved the identifier, so assign the repo id */ |
---|
1591 | assert (IDL_NODE_TYPE (p) == IDLN_GENTREE); |
---|
1592 | assert (IDL_GENTREE (p).data != NULL); |
---|
1593 | assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT); |
---|
1594 | ident = IDL_GENTREE (p).data; |
---|
1595 | |
---|
1596 | if (IDL_IDENT_REPO_ID (ident) != NULL) |
---|
1597 | g_free (IDL_IDENT_REPO_ID (ident)); |
---|
1598 | |
---|
1599 | IDL_IDENT_REPO_ID (ident) = g_strdup (id); |
---|
1600 | } |
---|
1601 | |
---|
1602 | void IDL_ns_version (IDL_ns ns, const char *s) |
---|
1603 | { |
---|
1604 | char name[1024]; |
---|
1605 | int n, major, minor; |
---|
1606 | IDL_tree p, ident; |
---|
1607 | |
---|
1608 | n = sscanf (s, "%1023s %u.%u", name, &major, &minor); |
---|
1609 | if (n < 3 && __IDL_is_parsing) { |
---|
1610 | yywarning (IDL_WARNING1, "Malformed pragma version"); |
---|
1611 | return; |
---|
1612 | } |
---|
1613 | |
---|
1614 | p = IDL_ns_pragma_parse_name (__IDL_root_ns, name); |
---|
1615 | if (!p && __IDL_is_parsing) { |
---|
1616 | yywarningv (IDL_WARNING1, "Unknown identifier `%s' in pragma version", name); |
---|
1617 | return; |
---|
1618 | } |
---|
1619 | |
---|
1620 | /* We have resolved the identifier, so assign the repo id */ |
---|
1621 | assert (IDL_NODE_TYPE (p) == IDLN_GENTREE); |
---|
1622 | assert (IDL_GENTREE (p).data != NULL); |
---|
1623 | assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT); |
---|
1624 | ident = IDL_GENTREE (p).data; |
---|
1625 | |
---|
1626 | if (IDL_IDENT_REPO_ID (ident) != NULL) { |
---|
1627 | char *v = strrchr (IDL_IDENT_REPO_ID (ident), ':'); |
---|
1628 | if (v) { |
---|
1629 | GString *s; |
---|
1630 | |
---|
1631 | *v = 0; |
---|
1632 | s = g_string_new (NULL); |
---|
1633 | g_string_printf (s, "%s:%d.%d", |
---|
1634 | IDL_IDENT_REPO_ID (ident), major, minor); |
---|
1635 | g_free (IDL_IDENT_REPO_ID (ident)); |
---|
1636 | IDL_IDENT_REPO_ID (ident) = s->str; |
---|
1637 | g_string_free (s, FALSE); |
---|
1638 | } else if (__IDL_is_parsing) |
---|
1639 | yywarningv (IDL_WARNING1, "Cannot find RepositoryID OMG IDL version in ID `%s'", |
---|
1640 | IDL_IDENT_REPO_ID (ident)); |
---|
1641 | } else |
---|
1642 | IDL_IDENT_REPO_ID (ident) = |
---|
1643 | IDL_ns_ident_make_repo_id ( |
---|
1644 | __IDL_root_ns, p, NULL, &major, &minor); |
---|
1645 | } |
---|
1646 | |
---|
1647 | int IDL_inhibit_get (void) |
---|
1648 | { |
---|
1649 | g_return_val_if_fail (__IDL_is_parsing, -1); |
---|
1650 | |
---|
1651 | return __IDL_inhibits; |
---|
1652 | } |
---|
1653 | |
---|
1654 | void IDL_inhibit_push (void) |
---|
1655 | { |
---|
1656 | g_return_if_fail (__IDL_is_parsing); |
---|
1657 | |
---|
1658 | ++__IDL_inhibits; |
---|
1659 | } |
---|
1660 | |
---|
1661 | void IDL_inhibit_pop (void) |
---|
1662 | { |
---|
1663 | g_return_if_fail (__IDL_is_parsing); |
---|
1664 | |
---|
1665 | if (--__IDL_inhibits < 0) |
---|
1666 | __IDL_inhibits = 0; |
---|
1667 | } |
---|
1668 | |
---|
1669 | static void IDL_inhibit (IDL_ns ns, const char *s) |
---|
1670 | { |
---|
1671 | if (g_ascii_strcasecmp ("push", s) == 0) |
---|
1672 | IDL_inhibit_push (); |
---|
1673 | else if (g_ascii_strcasecmp ("pop", s) == 0) |
---|
1674 | IDL_inhibit_pop (); |
---|
1675 | } |
---|
1676 | |
---|
1677 | static void IDL_typecodes_as_tok (IDL_ns ns, const char *s) |
---|
1678 | { |
---|
1679 | if (g_ascii_strcasecmp ("push", s) == 0) |
---|
1680 | ++(__IDL_typecodes_as_tok); |
---|
1681 | else if (g_ascii_strcasecmp ("pop", s) == 0) |
---|
1682 | --(__IDL_typecodes_as_tok); |
---|
1683 | } |
---|
1684 | |
---|
1685 | static void IDL_pidl (IDL_ns ns, const char *s) |
---|
1686 | { |
---|
1687 | if (g_ascii_strcasecmp ("push", s) == 0) |
---|
1688 | ++(__IDL_pidl); |
---|
1689 | else if (g_ascii_strcasecmp ("pop", s) == 0) |
---|
1690 | --(__IDL_pidl); |
---|
1691 | } |
---|
1692 | |
---|
1693 | void __IDL_do_pragma (const char *s) |
---|
1694 | { |
---|
1695 | int n; |
---|
1696 | char directive[256]; |
---|
1697 | |
---|
1698 | g_return_if_fail (__IDL_is_parsing); |
---|
1699 | g_return_if_fail (s != NULL); |
---|
1700 | |
---|
1701 | if (sscanf (s, "%255s%n", directive, &n) < 1) |
---|
1702 | return; |
---|
1703 | s += n; |
---|
1704 | while (g_ascii_isspace (*s)) ++s; |
---|
1705 | |
---|
1706 | if (strcmp (directive, "prefix") == 0) |
---|
1707 | IDL_ns_prefix (__IDL_root_ns, s); |
---|
1708 | else if (strcmp (directive, "ID") == 0) |
---|
1709 | IDL_ns_ID (__IDL_root_ns, s); |
---|
1710 | else if (strcmp (directive, "version") == 0) |
---|
1711 | IDL_ns_version (__IDL_root_ns, s); |
---|
1712 | else if (strcmp (directive, "inhibit") == 0) |
---|
1713 | IDL_inhibit (__IDL_root_ns, s); |
---|
1714 | else if (strcmp (directive, "typecodes_as_tok") == 0) |
---|
1715 | IDL_typecodes_as_tok (__IDL_root_ns, s); |
---|
1716 | else if (strcmp (directive, "pidl") == 0) |
---|
1717 | IDL_pidl (__IDL_root_ns, s); |
---|
1718 | } |
---|
1719 | |
---|
1720 | static IDL_declspec_t IDL_parse_declspec (const char *strspec) |
---|
1721 | { |
---|
1722 | IDL_declspec_t flags = IDLF_DECLSPEC_EXIST; |
---|
1723 | |
---|
1724 | if (strspec == NULL) |
---|
1725 | return flags; |
---|
1726 | |
---|
1727 | if (strcmp (strspec, "inhibit") == 0) |
---|
1728 | flags |= IDLF_DECLSPEC_INHIBIT; |
---|
1729 | if (strcmp (strspec, "pidl") == 0) |
---|
1730 | flags |= IDLF_DECLSPEC_PIDL; |
---|
1731 | else if (__IDL_is_parsing) |
---|
1732 | yywarningv (IDL_WARNING1, "Ignoring unknown declspec `%s'", strspec); |
---|
1733 | |
---|
1734 | return flags; |
---|
1735 | } |
---|
1736 | |
---|
1737 | IDL_tree IDL_file_set (const char *filename, int line) |
---|
1738 | { |
---|
1739 | IDL_fileinfo *fi; |
---|
1740 | IDL_tree tree = NULL; |
---|
1741 | |
---|
1742 | g_return_val_if_fail (__IDL_is_parsing, 0); |
---|
1743 | |
---|
1744 | if (filename) { |
---|
1745 | const char *oldfilename = __IDL_cur_filename; |
---|
1746 | gboolean wasInhibit = IS_INHIBIT_STATE(); |
---|
1747 | gboolean isTop = |
---|
1748 | #ifdef HAVE_CPP_PIPE_STDIN |
---|
1749 | strlen (filename)==0; |
---|
1750 | #else |
---|
1751 | __IDL_tmp_filename && |
---|
1752 | strcmp (filename, __IDL_tmp_filename)==0; |
---|
1753 | #endif |
---|
1754 | if ( isTop ) { |
---|
1755 | filename = __IDL_real_filename; |
---|
1756 | __IDL_flagsi &= ~IDLFP_IN_INCLUDES; |
---|
1757 | } else { |
---|
1758 | __IDL_flagsi |= IDLFP_IN_INCLUDES; |
---|
1759 | } |
---|
1760 | |
---|
1761 | if ((fi=g_hash_table_lookup(__IDL_filename_hash, filename)) ) { |
---|
1762 | __IDL_cur_fileinfo = fi; |
---|
1763 | ++(fi->seenCnt); |
---|
1764 | } else { |
---|
1765 | fi = g_new0 (IDL_fileinfo, 1); |
---|
1766 | fi->name = g_strdup(filename); |
---|
1767 | g_hash_table_insert (__IDL_filename_hash, fi->name, fi); |
---|
1768 | } |
---|
1769 | __IDL_cur_fileinfo = fi; |
---|
1770 | __IDL_cur_filename = fi->name; |
---|
1771 | if ( (__IDL_flags & IDLF_SRCFILES)!=0 |
---|
1772 | && (oldfilename==0 |
---|
1773 | || strcmp(oldfilename,fi->name)!=0) ) { |
---|
1774 | tree = IDL_srcfile_new(fi->name, fi->seenCnt, isTop, wasInhibit); |
---|
1775 | } |
---|
1776 | } |
---|
1777 | |
---|
1778 | if (__IDL_cur_line > 0) |
---|
1779 | __IDL_cur_line = line; |
---|
1780 | return tree; |
---|
1781 | } |
---|
1782 | |
---|
1783 | void IDL_file_get (const char **filename, int *line) |
---|
1784 | { |
---|
1785 | g_return_if_fail (__IDL_is_parsing); |
---|
1786 | |
---|
1787 | if (filename) |
---|
1788 | *filename = __IDL_cur_filename; |
---|
1789 | |
---|
1790 | if (line) |
---|
1791 | *line = __IDL_cur_line; |
---|
1792 | } |
---|
1793 | |
---|
1794 | static int do_token_error (IDL_tree p, const char *message, gboolean prev) |
---|
1795 | { |
---|
1796 | int dienow; |
---|
1797 | char *what = NULL, *who = NULL; |
---|
1798 | |
---|
1799 | assert (p != NULL); |
---|
1800 | |
---|
1801 | dienow = IDL_tree_get_node_info (p, &what, &who); |
---|
1802 | |
---|
1803 | assert (what != NULL); |
---|
1804 | |
---|
1805 | if (who && *who) |
---|
1806 | IDL_tree_error (p, "%s %s `%s'", message, what, who); |
---|
1807 | else |
---|
1808 | IDL_tree_error (p, "%s %s", message, what); |
---|
1809 | |
---|
1810 | return dienow; |
---|
1811 | } |
---|
1812 | |
---|
1813 | static void illegal_context_type_error (IDL_tree p, const char *what) |
---|
1814 | { |
---|
1815 | GString *s = g_string_new (NULL); |
---|
1816 | |
---|
1817 | g_string_printf (s, "Illegal type `%%s' for %s", what); |
---|
1818 | illegal_type_error (p, s->str); |
---|
1819 | g_string_free (s, TRUE); |
---|
1820 | } |
---|
1821 | |
---|
1822 | static void illegal_type_error (IDL_tree p, const char *message) |
---|
1823 | { |
---|
1824 | GString *s; |
---|
1825 | |
---|
1826 | s = IDL_tree_to_IDL_string (p, NULL, IDLF_OUTPUT_NO_NEWLINES); |
---|
1827 | yyerrorv (message, s->str); |
---|
1828 | g_string_free (s, TRUE); |
---|
1829 | } |
---|
1830 | |
---|
1831 | static IDL_tree list_start (IDL_tree a, gboolean filter_null) |
---|
1832 | { |
---|
1833 | IDL_tree p; |
---|
1834 | |
---|
1835 | if (!a && filter_null) |
---|
1836 | return NULL; |
---|
1837 | |
---|
1838 | p = IDL_list_new (a); |
---|
1839 | |
---|
1840 | return p; |
---|
1841 | } |
---|
1842 | |
---|
1843 | static IDL_tree list_chain (IDL_tree a, IDL_tree b, gboolean filter_null) |
---|
1844 | { |
---|
1845 | IDL_tree p; |
---|
1846 | |
---|
1847 | if (filter_null) { |
---|
1848 | if (!b) |
---|
1849 | return a; |
---|
1850 | if (!a) |
---|
1851 | return list_start (b, filter_null); |
---|
1852 | } |
---|
1853 | |
---|
1854 | p = IDL_list_new (b); |
---|
1855 | a = IDL_list_concat (a, p); |
---|
1856 | |
---|
1857 | return a; |
---|
1858 | } |
---|
1859 | |
---|
1860 | static IDL_tree zlist_chain (IDL_tree a, IDL_tree b, gboolean filter_null) |
---|
1861 | { |
---|
1862 | if (a == NULL) |
---|
1863 | return list_start (b, filter_null); |
---|
1864 | else |
---|
1865 | return list_chain (a, b, filter_null); |
---|
1866 | } |
---|
1867 | |
---|
1868 | static int IDL_binop_chktypes (enum IDL_binop op, IDL_tree a, IDL_tree b) |
---|
1869 | { |
---|
1870 | if (IDL_NODE_TYPE (a) != IDLN_BINOP && |
---|
1871 | IDL_NODE_TYPE (b) != IDLN_BINOP && |
---|
1872 | IDL_NODE_TYPE (a) != IDLN_UNARYOP && |
---|
1873 | IDL_NODE_TYPE (b) != IDLN_UNARYOP && |
---|
1874 | IDL_NODE_TYPE (a) != IDL_NODE_TYPE (b)) { |
---|
1875 | yyerror ("Invalid mix of types in constant expression"); |
---|
1876 | return -1; |
---|
1877 | } |
---|
1878 | |
---|
1879 | switch (op) { |
---|
1880 | case IDL_BINOP_MULT: |
---|
1881 | case IDL_BINOP_DIV: |
---|
1882 | case IDL_BINOP_ADD: |
---|
1883 | case IDL_BINOP_SUB: |
---|
1884 | break; |
---|
1885 | |
---|
1886 | case IDL_BINOP_MOD: |
---|
1887 | case IDL_BINOP_SHR: |
---|
1888 | case IDL_BINOP_SHL: |
---|
1889 | case IDL_BINOP_AND: |
---|
1890 | case IDL_BINOP_OR: |
---|
1891 | case IDL_BINOP_XOR: |
---|
1892 | if ((IDL_NODE_TYPE (a) != IDLN_INTEGER || |
---|
1893 | IDL_NODE_TYPE (b) != IDLN_INTEGER) && |
---|
1894 | !(IDL_NODE_TYPE (a) == IDLN_BINOP || |
---|
1895 | IDL_NODE_TYPE (b) == IDLN_BINOP || |
---|
1896 | IDL_NODE_TYPE (a) == IDLN_UNARYOP || |
---|
1897 | IDL_NODE_TYPE (b) == IDLN_UNARYOP)) { |
---|
1898 | yyerror ("Invalid operation on non-integer value"); |
---|
1899 | return -1; |
---|
1900 | } |
---|
1901 | break; |
---|
1902 | } |
---|
1903 | |
---|
1904 | return 0; |
---|
1905 | } |
---|
1906 | |
---|
1907 | static int IDL_unaryop_chktypes (enum IDL_unaryop op, IDL_tree a) |
---|
1908 | { |
---|
1909 | switch (op) { |
---|
1910 | case IDL_UNARYOP_PLUS: |
---|
1911 | case IDL_UNARYOP_MINUS: |
---|
1912 | break; |
---|
1913 | |
---|
1914 | case IDL_UNARYOP_COMPLEMENT: |
---|
1915 | if (IDL_NODE_TYPE (a) != IDLN_INTEGER && |
---|
1916 | !(IDL_NODE_TYPE (a) == IDLN_BINOP || |
---|
1917 | IDL_NODE_TYPE (a) == IDLN_UNARYOP)) { |
---|
1918 | yyerror ("Operand to complement must be integer"); |
---|
1919 | return -1; |
---|
1920 | } |
---|
1921 | break; |
---|
1922 | } |
---|
1923 | |
---|
1924 | return 0; |
---|
1925 | } |
---|
1926 | |
---|
1927 | static IDL_tree IDL_binop_eval_integer (enum IDL_binop op, IDL_tree a, IDL_tree b) |
---|
1928 | { |
---|
1929 | IDL_tree p = NULL; |
---|
1930 | |
---|
1931 | assert (IDL_NODE_TYPE (a) == IDLN_INTEGER); |
---|
1932 | |
---|
1933 | switch (op) { |
---|
1934 | case IDL_BINOP_MULT: |
---|
1935 | p = IDL_integer_new (IDL_INTEGER (a).value * IDL_INTEGER (b).value); |
---|
1936 | break; |
---|
1937 | |
---|
1938 | case IDL_BINOP_DIV: |
---|
1939 | if (IDL_INTEGER (b).value == 0) { |
---|
1940 | yyerror ("Divide by zero in constant expression"); |
---|
1941 | return NULL; |
---|
1942 | } |
---|
1943 | p = IDL_integer_new (IDL_INTEGER (a).value / IDL_INTEGER (b).value); |
---|
1944 | break; |
---|
1945 | |
---|
1946 | case IDL_BINOP_ADD: |
---|
1947 | p = IDL_integer_new (IDL_INTEGER (a).value + IDL_INTEGER (b).value); |
---|
1948 | break; |
---|
1949 | |
---|
1950 | case IDL_BINOP_SUB: |
---|
1951 | p = IDL_integer_new (IDL_INTEGER (a).value - IDL_INTEGER (b).value); |
---|
1952 | break; |
---|
1953 | |
---|
1954 | case IDL_BINOP_MOD: |
---|
1955 | if (IDL_INTEGER (b).value == 0) { |
---|
1956 | yyerror ("Modulo by zero in constant expression"); |
---|
1957 | return NULL; |
---|
1958 | } |
---|
1959 | p = IDL_integer_new (IDL_INTEGER (a).value % IDL_INTEGER (b).value); |
---|
1960 | break; |
---|
1961 | |
---|
1962 | case IDL_BINOP_SHR: |
---|
1963 | p = IDL_integer_new (IDL_INTEGER (a).value >> IDL_INTEGER (b).value); |
---|
1964 | break; |
---|
1965 | |
---|
1966 | case IDL_BINOP_SHL: |
---|
1967 | p = IDL_integer_new (IDL_INTEGER (a).value << IDL_INTEGER (b).value); |
---|
1968 | break; |
---|
1969 | |
---|
1970 | case IDL_BINOP_AND: |
---|
1971 | p = IDL_integer_new (IDL_INTEGER (a).value & IDL_INTEGER (b).value); |
---|
1972 | break; |
---|
1973 | |
---|
1974 | case IDL_BINOP_OR: |
---|
1975 | p = IDL_integer_new (IDL_INTEGER (a).value | IDL_INTEGER (b).value); |
---|
1976 | break; |
---|
1977 | |
---|
1978 | case IDL_BINOP_XOR: |
---|
1979 | p = IDL_integer_new (IDL_INTEGER (a).value ^ IDL_INTEGER (b).value); |
---|
1980 | break; |
---|
1981 | } |
---|
1982 | |
---|
1983 | return p; |
---|
1984 | } |
---|
1985 | |
---|
1986 | static IDL_tree IDL_binop_eval_float (enum IDL_binop op, IDL_tree a, IDL_tree b) |
---|
1987 | { |
---|
1988 | IDL_tree p = NULL; |
---|
1989 | |
---|
1990 | assert (IDL_NODE_TYPE (a) == IDLN_FLOAT); |
---|
1991 | |
---|
1992 | switch (op) { |
---|
1993 | case IDL_BINOP_MULT: |
---|
1994 | p = IDL_float_new (IDL_FLOAT (a).value * IDL_FLOAT (b).value); |
---|
1995 | break; |
---|
1996 | |
---|
1997 | case IDL_BINOP_DIV: |
---|
1998 | if (IDL_FLOAT (b).value == 0.0) { |
---|
1999 | yyerror ("Divide by zero in constant expression"); |
---|
2000 | return NULL; |
---|
2001 | } |
---|
2002 | p = IDL_float_new (IDL_FLOAT (a).value / IDL_FLOAT (b).value); |
---|
2003 | break; |
---|
2004 | |
---|
2005 | case IDL_BINOP_ADD: |
---|
2006 | p = IDL_float_new (IDL_FLOAT (a).value + IDL_FLOAT (b).value); |
---|
2007 | break; |
---|
2008 | |
---|
2009 | case IDL_BINOP_SUB: |
---|
2010 | p = IDL_float_new (IDL_FLOAT (a).value - IDL_FLOAT (b).value); |
---|
2011 | break; |
---|
2012 | |
---|
2013 | default: |
---|
2014 | break; |
---|
2015 | } |
---|
2016 | |
---|
2017 | return p; |
---|
2018 | } |
---|
2019 | |
---|
2020 | static IDL_tree IDL_binop_eval (enum IDL_binop op, IDL_tree a, IDL_tree b) |
---|
2021 | { |
---|
2022 | assert (IDL_NODE_TYPE (a) == IDL_NODE_TYPE (b)); |
---|
2023 | |
---|
2024 | switch (IDL_NODE_TYPE (a)) { |
---|
2025 | case IDLN_INTEGER: return IDL_binop_eval_integer (op, a, b); |
---|
2026 | case IDLN_FLOAT: return IDL_binop_eval_float (op, a, b); |
---|
2027 | default: return NULL; |
---|
2028 | } |
---|
2029 | } |
---|
2030 | |
---|
2031 | static IDL_tree IDL_unaryop_eval_integer (enum IDL_unaryop op, IDL_tree a) |
---|
2032 | { |
---|
2033 | IDL_tree p = NULL; |
---|
2034 | |
---|
2035 | assert (IDL_NODE_TYPE (a) == IDLN_INTEGER); |
---|
2036 | |
---|
2037 | switch (op) { |
---|
2038 | case IDL_UNARYOP_PLUS: |
---|
2039 | p = IDL_integer_new (IDL_INTEGER (a).value); |
---|
2040 | break; |
---|
2041 | |
---|
2042 | case IDL_UNARYOP_MINUS: |
---|
2043 | p = IDL_integer_new (-IDL_INTEGER (a).value); |
---|
2044 | break; |
---|
2045 | |
---|
2046 | case IDL_UNARYOP_COMPLEMENT: |
---|
2047 | p = IDL_integer_new (~IDL_INTEGER (a).value); |
---|
2048 | break; |
---|
2049 | } |
---|
2050 | |
---|
2051 | return p; |
---|
2052 | } |
---|
2053 | |
---|
2054 | static IDL_tree IDL_unaryop_eval_fixed (enum IDL_unaryop op, IDL_tree a) |
---|
2055 | { |
---|
2056 | IDL_tree p = NULL; |
---|
2057 | |
---|
2058 | assert (IDL_NODE_TYPE (a) == IDLN_FIXED); |
---|
2059 | |
---|
2060 | switch (op) { |
---|
2061 | case IDL_UNARYOP_PLUS: |
---|
2062 | p = IDL_fixed_new (IDL_FIXED (a).value); |
---|
2063 | break; |
---|
2064 | |
---|
2065 | default: |
---|
2066 | break; |
---|
2067 | } |
---|
2068 | |
---|
2069 | return p; |
---|
2070 | } |
---|
2071 | |
---|
2072 | static IDL_tree IDL_unaryop_eval_float (enum IDL_unaryop op, IDL_tree a) |
---|
2073 | { |
---|
2074 | IDL_tree p = NULL; |
---|
2075 | |
---|
2076 | assert (IDL_NODE_TYPE (a) == IDLN_FLOAT); |
---|
2077 | |
---|
2078 | switch (op) { |
---|
2079 | case IDL_UNARYOP_PLUS: |
---|
2080 | p = IDL_float_new (IDL_FLOAT (a).value); |
---|
2081 | break; |
---|
2082 | |
---|
2083 | case IDL_UNARYOP_MINUS: |
---|
2084 | p = IDL_float_new (-IDL_FLOAT (a).value); |
---|
2085 | break; |
---|
2086 | |
---|
2087 | default: |
---|
2088 | break; |
---|
2089 | } |
---|
2090 | |
---|
2091 | return p; |
---|
2092 | } |
---|
2093 | |
---|
2094 | static IDL_tree IDL_unaryop_eval (enum IDL_unaryop op, IDL_tree a) |
---|
2095 | { |
---|
2096 | switch (IDL_NODE_TYPE (a)) { |
---|
2097 | case IDLN_INTEGER: return IDL_unaryop_eval_integer (op, a); |
---|
2098 | case IDLN_FIXED: return IDL_unaryop_eval_fixed (op, a); |
---|
2099 | case IDLN_FLOAT: return IDL_unaryop_eval_float (op, a); |
---|
2100 | default: return NULL; |
---|
2101 | } |
---|
2102 | } |
---|
2103 | |
---|
2104 | IDL_tree IDL_resolve_const_exp (IDL_tree p, IDL_tree_type type) |
---|
2105 | { |
---|
2106 | gboolean resolved_value = FALSE, die = FALSE; |
---|
2107 | gboolean wrong_type = FALSE; |
---|
2108 | |
---|
2109 | while (!resolved_value && !die) { |
---|
2110 | if (IDL_NODE_TYPE (p) == IDLN_IDENT) { |
---|
2111 | IDL_tree q = IDL_NODE_UP (p); |
---|
2112 | |
---|
2113 | assert (q != NULL); |
---|
2114 | if (IDL_NODE_UP (q) && |
---|
2115 | IDL_NODE_TYPE (IDL_NODE_UP (q)) == IDLN_TYPE_ENUM) { |
---|
2116 | p = q; |
---|
2117 | die = TRUE; |
---|
2118 | break; |
---|
2119 | } else if (IDL_NODE_TYPE (q) != IDLN_CONST_DCL) { |
---|
2120 | p = q; |
---|
2121 | wrong_type = TRUE; |
---|
2122 | die = TRUE; |
---|
2123 | } else |
---|
2124 | p = IDL_CONST_DCL (q).const_exp; |
---|
2125 | } |
---|
2126 | |
---|
2127 | if (p == NULL || |
---|
2128 | IDL_NODE_TYPE (p) == IDLN_BINOP || |
---|
2129 | IDL_NODE_TYPE (p) == IDLN_UNARYOP) { |
---|
2130 | die = TRUE; |
---|
2131 | continue; |
---|
2132 | } |
---|
2133 | |
---|
2134 | resolved_value = IDL_NODE_IS_LITERAL (p); |
---|
2135 | } |
---|
2136 | |
---|
2137 | if (resolved_value && |
---|
2138 | type != IDLN_ANY && |
---|
2139 | IDL_NODE_TYPE (p) != type) |
---|
2140 | wrong_type = TRUE; |
---|
2141 | |
---|
2142 | if (wrong_type) { |
---|
2143 | yyerror ("Invalid type for constant"); |
---|
2144 | IDL_tree_error (p, "Previous resolved type declaration"); |
---|
2145 | return NULL; |
---|
2146 | } |
---|
2147 | |
---|
2148 | return resolved_value ? p : NULL; |
---|
2149 | } |
---|
2150 | |
---|
2151 | void IDL_queue_new_ident_comment (const char *str) |
---|
2152 | { |
---|
2153 | g_return_if_fail (str != NULL); |
---|
2154 | |
---|
2155 | __IDL_new_ident_comments = g_slist_append (__IDL_new_ident_comments, g_strdup (str)); |
---|
2156 | } |
---|
2157 | |
---|
2158 | /* |
---|
2159 | * Local variables: |
---|
2160 | * mode: C |
---|
2161 | * c-basic-offset: 8 |
---|
2162 | * tab-width: 8 |
---|
2163 | * indent-tabs-mode: t |
---|
2164 | * End: |
---|
2165 | */ |
---|