1 %{
2
3 //
4 // Copyright (c) ZeroC, Inc. All rights reserved.
5 //
6
7 #include <Slice/GrammarUtil.h>
8 #include <IceUtil/InputUtil.h>
9 #include <IceUtil/UUID.h>
10 #include <cstring>
11
12 #ifdef _MSC_VER
13 // warning C4102: 'yyoverflowlab' : unreferenced label
14 # pragma warning(disable:4102)
15 // warning C4065: switch statement contains 'default' but no 'case' labels
16 # pragma warning(disable:4065)
17 // warning C4244: '=': conversion from 'int' to 'yytype_int16', possible loss of data
18 # pragma warning(disable:4244)
19 #endif
20
21 //
22 // Avoid old style cast warnings in generated grammar
23 //
24 #ifdef __GNUC__
25 # pragma GCC diagnostic ignored "-Wold-style-cast"
26 #endif
27
28 using namespace std;
29 using namespace Slice;
30
31 void
slice_error(const char * s)32 slice_error(const char* s)
33 {
34 // yacc and recent versions of Bison use "syntax error" instead
35 // of "parse error".
36
37 if (strcmp(s, "parse error") == 0)
38 {
39 unit->error("syntax error");
40 }
41 else
42 {
43 unit->error(s);
44 }
45 }
46
47 %}
48
49 %pure-parser
50
51 //
52 // All keyword tokens. Make sure to modify the "keyword" rule in this
53 // file if the list of keywords is changed. Also make sure to add the
54 // keyword to the keyword table in Scanner.l.
55 //
56 %token ICE_MODULE
57 %token ICE_CLASS
58 %token ICE_INTERFACE
59 %token ICE_EXCEPTION
60 %token ICE_STRUCT
61 %token ICE_SEQUENCE
62 %token ICE_DICTIONARY
63 %token ICE_ENUM
64 %token ICE_OUT
65 %token ICE_EXTENDS
66 %token ICE_IMPLEMENTS
67 %token ICE_THROWS
68 %token ICE_VOID
69 %token ICE_BYTE
70 %token ICE_BOOL
71 %token ICE_SHORT
72 %token ICE_INT
73 %token ICE_LONG
74 %token ICE_FLOAT
75 %token ICE_DOUBLE
76 %token ICE_STRING
77 %token ICE_OBJECT
78 %token ICE_LOCAL_OBJECT
79 %token ICE_LOCAL
80 %token ICE_CONST
81 %token ICE_FALSE
82 %token ICE_TRUE
83 %token ICE_IDEMPOTENT
84 %token ICE_OPTIONAL
85 %token ICE_VALUE
86
87 //
88 // Other tokens.
89 //
90 %token ICE_IDENTIFIER
91 %token ICE_SCOPED_IDENTIFIER
92 %token ICE_STRING_LITERAL
93 %token ICE_INTEGER_LITERAL
94 %token ICE_FLOATING_POINT_LITERAL
95 %token ICE_IDENT_OP
96 %token ICE_KEYWORD_OP
97 %token ICE_OPTIONAL_OP
98 %token ICE_METADATA_OPEN
99 %token ICE_METADATA_CLOSE
100 %token ICE_GLOBAL_METADATA_OPEN
101 %token ICE_GLOBAL_METADATA_CLOSE
102
103 %token BAD_CHAR
104
105 %%
106
107 // ----------------------------------------------------------------------
108 start
109 // ----------------------------------------------------------------------
110 : definitions
111 {
112 }
113 ;
114
115 // ----------------------------------------------------------------------
116 opt_semicolon
117 // ----------------------------------------------------------------------
118 : ';'
119 {
120 }
121 |
122 {
123 }
124 ;
125
126 // ----------------------------------------------------------------------
127 global_meta_data
128 // ----------------------------------------------------------------------
129 : ICE_GLOBAL_METADATA_OPEN string_list ICE_GLOBAL_METADATA_CLOSE
130 {
131 $$ = $2;
132 }
133 ;
134
135 // ----------------------------------------------------------------------
136 meta_data
137 // ----------------------------------------------------------------------
138 : ICE_METADATA_OPEN string_list ICE_METADATA_CLOSE
139 {
140 $$ = $2;
141 }
142 |
143 {
144 $$ = new StringListTok;
145 }
146 ;
147
148 // ----------------------------------------------------------------------
149 definitions
150 // ----------------------------------------------------------------------
151 : global_meta_data
152 {
153 StringListTokPtr metaData = StringListTokPtr::dynamicCast($1);
154 if(!metaData->v.empty())
155 {
156 unit->addGlobalMetaData(metaData->v);
157 }
158 }
159 definitions
160 | meta_data definition
161 {
162 StringListTokPtr metaData = StringListTokPtr::dynamicCast($1);
163 ContainedPtr contained = ContainedPtr::dynamicCast($2);
164 if(contained && !metaData->v.empty())
165 {
166 contained->setMetaData(metaData->v);
167 }
168 }
169 definitions
170 |
171 {
172 }
173 ;
174
175 // ----------------------------------------------------------------------
176 definition
177 // ----------------------------------------------------------------------
178 : module_def
179 {
180 assert($1 == 0 || ModulePtr::dynamicCast($1));
181 }
182 opt_semicolon
183 | class_decl
184 {
185 assert($1 == 0 || ClassDeclPtr::dynamicCast($1));
186 }
187 ';'
188 | class_decl
189 {
190 unit->error("`;' missing after class forward declaration");
191 }
192 | class_def
193 {
194 assert($1 == 0 || ClassDefPtr::dynamicCast($1));
195 }
196 opt_semicolon
197 | interface_decl
198 {
199 assert($1 == 0 || ClassDeclPtr::dynamicCast($1));
200 }
201 ';'
202 | interface_decl
203 {
204 unit->error("`;' missing after interface forward declaration");
205 }
206 | interface_def
207 {
208 assert($1 == 0 || ClassDefPtr::dynamicCast($1));
209 }
210 opt_semicolon
211 | exception_decl
212 {
213 assert($1 == 0);
214 }
215 ';'
216 | exception_decl
217 {
218 unit->error("`;' missing after exception forward declaration");
219 }
220 | exception_def
221 {
222 assert($1 == 0 || ExceptionPtr::dynamicCast($1));
223 }
224 opt_semicolon
225 | struct_decl
226 {
227 assert($1 == 0);
228 }
229 ';'
230 | struct_decl
231 {
232 unit->error("`;' missing after struct forward declaration");
233 }
234 | struct_def
235 {
236 assert($1 == 0 || StructPtr::dynamicCast($1));
237 }
238 opt_semicolon
239 | sequence_def
240 {
241 assert($1 == 0 || SequencePtr::dynamicCast($1));
242 }
243 ';'
244 | sequence_def
245 {
246 unit->error("`;' missing after sequence definition");
247 }
248 | dictionary_def
249 {
250 assert($1 == 0 || DictionaryPtr::dynamicCast($1));
251 }
252 ';'
253 | dictionary_def
254 {
255 unit->error("`;' missing after dictionary definition");
256 }
257 | enum_def
258 {
259 assert($1 == 0 || EnumPtr::dynamicCast($1));
260 }
261 opt_semicolon
262 | const_def
263 {
264 assert($1 == 0 || ConstPtr::dynamicCast($1));
265 }
266 ';'
267 | const_def
268 {
269 unit->error("`;' missing after const definition");
270 }
271 | error ';'
272 {
273 yyerrok;
274 }
275 ;
276
277 // ----------------------------------------------------------------------
278 module_def
279 // ----------------------------------------------------------------------
280 : ICE_MODULE ICE_IDENTIFIER
281 {
282 unit->setSeenDefinition();
283 StringTokPtr ident = StringTokPtr::dynamicCast($2);
284 ContainerPtr cont = unit->currentContainer();
285 ModulePtr module = cont->createModule(ident->v);
286 if(module)
287 {
288 cont->checkIntroduced(ident->v, module);
289 unit->pushContainer(module);
290 $$ = module;
291 }
292 else
293 {
294 $$ = 0;
295 }
296 }
297 '{' definitions '}'
298 {
299 if($3)
300 {
301 unit->popContainer();
302 $$ = $3;
303 }
304 else
305 {
306 $$ = 0;
307 }
308 }
309 ;
310
311 // ----------------------------------------------------------------------
312 exception_id
313 // ----------------------------------------------------------------------
314 : ICE_EXCEPTION ICE_IDENTIFIER
315 {
316 $$ = $2;
317 }
318 | ICE_EXCEPTION keyword
319 {
320 StringTokPtr ident = StringTokPtr::dynamicCast($2);
321 unit->error("keyword `" + ident->v + "' cannot be used as exception name");
322 $$ = $2; // Dummy
323 }
324 ;
325
326 // ----------------------------------------------------------------------
327 exception_decl
328 // ----------------------------------------------------------------------
329 : local_qualifier exception_id
330 {
331 unit->error("exceptions cannot be forward declared");
332 $$ = 0;
333 }
334 ;
335
336 // ----------------------------------------------------------------------
337 exception_def
338 // ----------------------------------------------------------------------
339 : local_qualifier exception_id exception_extends
340 {
341 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
342 StringTokPtr ident = StringTokPtr::dynamicCast($2);
343 ExceptionPtr base = ExceptionPtr::dynamicCast($3);
344 ContainerPtr cont = unit->currentContainer();
345 ExceptionPtr ex = cont->createException(ident->v, base, local->v);
346 if(ex)
347 {
348 cont->checkIntroduced(ident->v, ex);
349 unit->pushContainer(ex);
350 }
351 $$ = ex;
352 }
353 '{' exception_exports '}'
354 {
355 if($4)
356 {
357 unit->popContainer();
358 }
359 $$ = $4;
360 }
361 ;
362
363 // ----------------------------------------------------------------------
364 exception_extends
365 // ----------------------------------------------------------------------
366 : ICE_EXTENDS scoped_name
367 {
368 StringTokPtr scoped = StringTokPtr::dynamicCast($2);
369 ContainerPtr cont = unit->currentContainer();
370 ContainedPtr contained = cont->lookupException(scoped->v);
371 cont->checkIntroduced(scoped->v);
372 $$ = contained;
373 }
374 |
375 {
376 $$ = 0;
377 }
378 ;
379
380 // ----------------------------------------------------------------------
381 exception_exports
382 // ----------------------------------------------------------------------
383 : meta_data exception_export ';' exception_exports
384 {
385 StringListTokPtr metaData = StringListTokPtr::dynamicCast($1);
386 ContainedPtr contained = ContainedPtr::dynamicCast($2);
387 if(contained && !metaData->v.empty())
388 {
389 contained->setMetaData(metaData->v);
390 }
391 }
392 | error ';' exception_exports
393 {
394 }
395 | meta_data exception_export
396 {
397 unit->error("`;' missing after definition");
398 }
399 |
400 {
401 }
402 ;
403
404 // ----------------------------------------------------------------------
405 type_id
406 // ----------------------------------------------------------------------
407 : type ICE_IDENTIFIER
408 {
409 TypePtr type = TypePtr::dynamicCast($1);
410 StringTokPtr ident = StringTokPtr::dynamicCast($2);
411 TypeStringTokPtr typestring = new TypeStringTok;
412 typestring->v = make_pair(type, ident->v);
413 $$ = typestring;
414 }
415 ;
416
417 // ----------------------------------------------------------------------
418 optional
419 // ----------------------------------------------------------------------
420 : ICE_OPTIONAL_OP ICE_INTEGER_LITERAL ')'
421 {
422 IntegerTokPtr i = IntegerTokPtr::dynamicCast($2);
423
424 int tag;
425 if(i->v < 0 || i->v > Int32Max)
426 {
427 unit->error("tag for optional is out of range");
428 tag = -1;
429 }
430 else
431 {
432 tag = static_cast<int>(i->v);
433 }
434
435 OptionalDefTokPtr m = new OptionalDefTok;
436 m->v.optional = tag >= 0;
437 m->v.tag = tag;
438 $$ = m;
439 }
440 | ICE_OPTIONAL_OP scoped_name ')'
441 {
442 StringTokPtr scoped = StringTokPtr::dynamicCast($2);
443
444 ContainerPtr cont = unit->currentContainer();
445 assert(cont);
446 ContainedList cl = cont->lookupContained(scoped->v, false);
447 if(cl.empty())
448 {
449 EnumeratorList enumerators = cont->enumerators(scoped->v);
450 if(enumerators.size() == 1)
451 {
452 // Found
453 cl.push_back(enumerators.front());
454 scoped->v = enumerators.front()->scoped();
455 unit->warning(Deprecated, string("referencing enumerator `") + scoped->v
456 + "' without its enumeration's scope is deprecated");
457 }
458 else if(enumerators.size() > 1)
459 {
460 ostringstream os;
461 os << "enumerator `" << scoped->v << "' could designate";
462 bool first = true;
463 for(EnumeratorList::iterator p = enumerators.begin(); p != enumerators.end(); ++p)
464 {
465 if(first)
466 {
467 first = false;
468 }
469 else
470 {
471 os << " or";
472 }
473
474 os << " `" << (*p)->scoped() << "'";
475 }
476 unit->error(os.str());
477 }
478 else
479 {
480 unit->error(string("`") + scoped->v + "' is not defined");
481 }
482 }
483
484 if(cl.empty())
485 {
486 YYERROR; // Can't continue, jump to next yyerrok
487 }
488 cont->checkIntroduced(scoped->v);
489
490 int tag = -1;
491 EnumeratorPtr enumerator = EnumeratorPtr::dynamicCast(cl.front());
492 ConstPtr constant = ConstPtr::dynamicCast(cl.front());
493 if(constant)
494 {
495 BuiltinPtr b = BuiltinPtr::dynamicCast(constant->type());
496 if(b)
497 {
498 switch(b->kind())
499 {
500 case Builtin::KindByte:
501 case Builtin::KindShort:
502 case Builtin::KindInt:
503 case Builtin::KindLong:
504 {
505 IceUtil::Int64 l = IceUtilInternal::strToInt64(constant->value().c_str(), 0, 0);
506 if(l < 0 || l > Int32Max)
507 {
508 unit->error("tag for optional is out of range");
509 }
510 tag = static_cast<int>(l);
511 break;
512 }
513 default:
514 break;
515 }
516 }
517 }
518 else if(enumerator)
519 {
520 tag = enumerator->value();
521 }
522
523 if(tag < 0)
524 {
525 unit->error("invalid tag `" + scoped->v + "' for optional");
526 }
527
528 OptionalDefTokPtr m = new OptionalDefTok;
529 m->v.optional = tag >= 0;
530 m->v.tag = tag;
531 $$ = m;
532 }
533 | ICE_OPTIONAL_OP ')'
534 {
535 unit->error("missing tag for optional");
536 OptionalDefTokPtr m = new OptionalDefTok; // Dummy
537 m->v.optional = false;
538 m->v.tag = -1;
539 $$ = m;
540 }
541 | ICE_OPTIONAL
542 {
543 unit->error("missing tag for optional");
544 OptionalDefTokPtr m = new OptionalDefTok; // Dummy
545 m->v.optional = false;
546 m->v.tag = -1;
547 $$ = m;
548 }
549 ;
550
551 // ----------------------------------------------------------------------
552 optional_type_id
553 // ----------------------------------------------------------------------
554 : optional type_id
555 {
556 OptionalDefTokPtr m = OptionalDefTokPtr::dynamicCast($1);
557 TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($2);
558 m->v.type = ts->v.first;
559 m->v.name = ts->v.second;
560 $$ = m;
561 }
562 | type_id
563 {
564 TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($1);
565 OptionalDefTokPtr m = new OptionalDefTok;
566 m->v.type = ts->v.first;
567 m->v.name = ts->v.second;
568 m->v.optional = false;
569 m->v.tag = -1;
570 $$ = m;
571 }
572 ;
573
574 // ----------------------------------------------------------------------
575 exception_export
576 // ----------------------------------------------------------------------
577 : data_member
578 ;
579
580 // ----------------------------------------------------------------------
581 struct_id
582 // ----------------------------------------------------------------------
583 : ICE_STRUCT ICE_IDENTIFIER
584 {
585 $$ = $2;
586 }
587 | ICE_STRUCT keyword
588 {
589 StringTokPtr ident = StringTokPtr::dynamicCast($2);
590 unit->error("keyword `" + ident->v + "' cannot be used as struct name");
591 $$ = $2; // Dummy
592 }
593 ;
594
595 // ----------------------------------------------------------------------
596 struct_decl
597 // ----------------------------------------------------------------------
598 : local_qualifier struct_id
599 {
600 unit->error("structs cannot be forward declared");
601 $$ = 0; // Dummy
602 }
603 ;
604
605 // ----------------------------------------------------------------------
606 struct_def
607 // ----------------------------------------------------------------------
608 : local_qualifier struct_id
609 {
610 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
611 StringTokPtr ident = StringTokPtr::dynamicCast($2);
612 ContainerPtr cont = unit->currentContainer();
613 StructPtr st = cont->createStruct(ident->v, local->v);
614 if(st)
615 {
616 cont->checkIntroduced(ident->v, st);
617 unit->pushContainer(st);
618 }
619 else
620 {
621 st = cont->createStruct(IceUtil::generateUUID(), local->v); // Dummy
622 assert(st);
623 unit->pushContainer(st);
624 }
625 $$ = st;
626 }
627 '{' struct_exports '}'
628 {
629 if($3)
630 {
631 unit->popContainer();
632 }
633 $$ = $3;
634
635 //
636 // Empty structures are not allowed
637 //
638 StructPtr st = StructPtr::dynamicCast($$);
639 assert(st);
640 if(st->dataMembers().empty())
641 {
642 unit->error("struct `" + st->name() + "' must have at least one member"); // $$ is a dummy
643 }
644 }
645 ;
646
647 // ----------------------------------------------------------------------
648 struct_exports
649 // ----------------------------------------------------------------------
650 : meta_data struct_export ';' struct_exports
651 {
652 StringListTokPtr metaData = StringListTokPtr::dynamicCast($1);
653 ContainedPtr contained = ContainedPtr::dynamicCast($2);
654 if(contained && !metaData->v.empty())
655 {
656 contained->setMetaData(metaData->v);
657 }
658 }
659 | error ';' struct_exports
660 {
661 }
662 | meta_data struct_export
663 {
664 unit->error("`;' missing after definition");
665 }
666 |
667 {
668 }
669 ;
670
671 // ----------------------------------------------------------------------
672 struct_export
673 // ----------------------------------------------------------------------
674 : struct_data_member
675 ;
676
677 // ----------------------------------------------------------------------
678 class_name
679 // ----------------------------------------------------------------------
680 : ICE_CLASS ICE_IDENTIFIER
681 {
682 $$ = $2;
683 }
684 | ICE_CLASS keyword
685 {
686 StringTokPtr ident = StringTokPtr::dynamicCast($2);
687 unit->error("keyword `" + ident->v + "' cannot be used as class name");
688 $$ = $2; // Dummy
689 }
690 ;
691
692 // ----------------------------------------------------------------------
693 class_id
694 // ----------------------------------------------------------------------
695 : ICE_CLASS ICE_IDENT_OP ICE_INTEGER_LITERAL ')'
696 {
697 IceUtil::Int64 id = IntegerTokPtr::dynamicCast($3)->v;
698 if(id < 0)
699 {
700 unit->error("invalid compact id for class: id must be a positive integer");
701 }
702 else if(id > Int32Max)
703 {
704 unit->error("invalid compact id for class: value is out of range");
705 }
706 else
707 {
708 string typeId = unit->getTypeId(static_cast<int>(id));
709 if(!typeId.empty() && !unit->ignRedefs())
710 {
711 unit->error("invalid compact id for class: already assigned to class `" + typeId + "'");
712 }
713 }
714
715 ClassIdTokPtr classId = new ClassIdTok();
716 classId->v = StringTokPtr::dynamicCast($2)->v;
717 classId->t = static_cast<int>(id);
718 $$ = classId;
719 }
720 | ICE_CLASS ICE_IDENT_OP scoped_name ')'
721 {
722 StringTokPtr scoped = StringTokPtr::dynamicCast($3);
723
724 ContainerPtr cont = unit->currentContainer();
725 assert(cont);
726 ContainedList cl = cont->lookupContained(scoped->v, false);
727 if(cl.empty())
728 {
729 EnumeratorList enumerators = cont->enumerators(scoped->v);
730 if(enumerators.size() == 1)
731 {
732 // Found
733 cl.push_back(enumerators.front());
734 scoped->v = enumerators.front()->scoped();
735 unit->warning(Deprecated, string("referencing enumerator `") + scoped->v
736 + "' without its enumeration's scope is deprecated");
737 }
738 else if(enumerators.size() > 1)
739 {
740 ostringstream os;
741 os << "enumerator `" << scoped->v << "' could designate";
742 bool first = true;
743 for(EnumeratorList::iterator p = enumerators.begin(); p != enumerators.end(); ++p)
744 {
745 if(first)
746 {
747 first = false;
748 }
749 else
750 {
751 os << " or";
752 }
753
754 os << " `" << (*p)->scoped() << "'";
755 }
756 unit->error(os.str());
757 }
758 else
759 {
760 unit->error(string("`") + scoped->v + "' is not defined");
761 }
762 }
763
764 if(cl.empty())
765 {
766 YYERROR; // Can't continue, jump to next yyerrok
767 }
768 cont->checkIntroduced(scoped->v);
769
770 int id = -1;
771 EnumeratorPtr enumerator = EnumeratorPtr::dynamicCast(cl.front());
772 ConstPtr constant = ConstPtr::dynamicCast(cl.front());
773 if(constant)
774 {
775 BuiltinPtr b = BuiltinPtr::dynamicCast(constant->type());
776 if(b)
777 {
778 switch(b->kind())
779 {
780 case Builtin::KindByte:
781 case Builtin::KindShort:
782 case Builtin::KindInt:
783 case Builtin::KindLong:
784 {
785 IceUtil::Int64 l = IceUtilInternal::strToInt64(constant->value().c_str(), 0, 0);
786 if(l < 0 || l > Int32Max)
787 {
788 unit->error("compact id for class is out of range");
789 }
790 id = static_cast<int>(l);
791 break;
792 }
793 default:
794 break;
795 }
796 }
797 }
798 else if(enumerator)
799 {
800 id = enumerator->value();
801 }
802
803 if(id < 0)
804 {
805 unit->error("invalid compact id for class: id must be a positive integer");
806 }
807 else
808 {
809 string typeId = unit->getTypeId(id);
810 if(!typeId.empty() && !unit->ignRedefs())
811 {
812 unit->error("invalid compact id for class: already assigned to class `" + typeId + "'");
813 }
814 }
815
816 ClassIdTokPtr classId = new ClassIdTok();
817 classId->v = StringTokPtr::dynamicCast($2)->v;
818 classId->t = id;
819 $$ = classId;
820
821 }
822 | class_name
823 {
824 ClassIdTokPtr classId = new ClassIdTok();
825 classId->v = StringTokPtr::dynamicCast($1)->v;
826 classId->t = -1;
827 $$ = classId;
828 }
829 ;
830
831 // ----------------------------------------------------------------------
832 class_decl
833 // ----------------------------------------------------------------------
834 : local_qualifier class_name
835 {
836 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
837 StringTokPtr ident = StringTokPtr::dynamicCast($2);
838 ContainerPtr cont = unit->currentContainer();
839 ClassDeclPtr cl = cont->createClassDecl(ident->v, false, local->v);
840 $$ = cl;
841 }
842 ;
843
844 // ----------------------------------------------------------------------
845 class_def
846 // ----------------------------------------------------------------------
847 : local_qualifier class_id class_extends implements
848 {
849 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
850 ClassIdTokPtr ident = ClassIdTokPtr::dynamicCast($2);
851 ContainerPtr cont = unit->currentContainer();
852 ClassDefPtr base = ClassDefPtr::dynamicCast($3);
853 ClassListTokPtr bases = ClassListTokPtr::dynamicCast($4);
854 if(base)
855 {
856 bases->v.push_front(base);
857 }
858 ClassDefPtr cl = cont->createClassDef(ident->v, ident->t, false, bases->v, local->v);
859 if(cl)
860 {
861 cont->checkIntroduced(ident->v, cl);
862 unit->pushContainer(cl);
863 $$ = cl;
864 }
865 else
866 {
867 $$ = 0;
868 }
869 }
870 '{' class_exports '}'
871 {
872 if($5)
873 {
874 unit->popContainer();
875 $$ = $5;
876 }
877 else
878 {
879 $$ = 0;
880 }
881 }
882 ;
883
884 // ----------------------------------------------------------------------
885 class_extends
886 // ----------------------------------------------------------------------
887 : ICE_EXTENDS scoped_name
888 {
889 StringTokPtr scoped = StringTokPtr::dynamicCast($2);
890 ContainerPtr cont = unit->currentContainer();
891 TypeList types = cont->lookupType(scoped->v);
892 $$ = 0;
893 if(!types.empty())
894 {
895 ClassDeclPtr cl = ClassDeclPtr::dynamicCast(types.front());
896 if(!cl || cl->isInterface())
897 {
898 string msg = "`";
899 msg += scoped->v;
900 msg += "' is not a class";
901 unit->error(msg);
902 }
903 else
904 {
905 ClassDefPtr def = cl->definition();
906 if(!def)
907 {
908 string msg = "`";
909 msg += scoped->v;
910 msg += "' has been declared but not defined";
911 unit->error(msg);
912 }
913 else
914 {
915 cont->checkIntroduced(scoped->v);
916 $$ = def;
917 }
918 }
919 }
920 }
921 |
922 {
923 $$ = 0;
924 }
925 ;
926
927 // ----------------------------------------------------------------------
928 implements
929 // ----------------------------------------------------------------------
930 : ICE_IMPLEMENTS interface_list
931 {
932 $$ = $2;
933 }
934 |
935 {
936 $$ = new ClassListTok;
937 }
938 ;
939
940 // ----------------------------------------------------------------------
941 class_exports
942 // ----------------------------------------------------------------------
943 : meta_data class_export ';' class_exports
944 {
945 StringListTokPtr metaData = StringListTokPtr::dynamicCast($1);
946 ContainedPtr contained = ContainedPtr::dynamicCast($2);
947 if(contained && !metaData->v.empty())
948 {
949 contained->setMetaData(metaData->v);
950 }
951 }
952 | error ';' class_exports
953 {
954 }
955 | meta_data class_export
956 {
957 unit->error("`;' missing after definition");
958 }
959 |
960 {
961 }
962 ;
963
964 // ----------------------------------------------------------------------
965 data_member
966 // ----------------------------------------------------------------------
967 : optional_type_id
968 {
969 OptionalDefTokPtr def = OptionalDefTokPtr::dynamicCast($1);
970 ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer());
971 DataMemberPtr dm;
972 if(cl)
973 {
974 dm = cl->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, 0, "", "");
975 }
976 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
977 if(st)
978 {
979 dm = st->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, 0, "", "");
980 }
981 ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer());
982 if(ex)
983 {
984 dm = ex->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, 0, "", "");
985 }
986 unit->currentContainer()->checkIntroduced(def->v.name, dm);
987 $$ = dm;
988 }
989 | optional_type_id '=' const_initializer
990 {
991 OptionalDefTokPtr def = OptionalDefTokPtr::dynamicCast($1);
992 ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($3);
993
994 ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer());
995 DataMemberPtr dm;
996 if(cl)
997 {
998 dm = cl->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, value->v.value,
999 value->v.valueAsString, value->v.valueAsLiteral);
1000 }
1001 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
1002 if(st)
1003 {
1004 dm = st->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, value->v.value,
1005 value->v.valueAsString, value->v.valueAsLiteral);
1006 }
1007 ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer());
1008 if(ex)
1009 {
1010 dm = ex->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, value->v.value,
1011 value->v.valueAsString, value->v.valueAsLiteral);
1012 }
1013 unit->currentContainer()->checkIntroduced(def->v.name, dm);
1014 $$ = dm;
1015 }
1016 | type keyword
1017 {
1018 TypePtr type = TypePtr::dynamicCast($1);
1019 string name = StringTokPtr::dynamicCast($2)->v;
1020 ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer());
1021 if(cl)
1022 {
1023 $$ = cl->createDataMember(name, type, false, 0, 0, "", ""); // Dummy
1024 }
1025 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
1026 if(st)
1027 {
1028 $$ = st->createDataMember(name, type, false, 0, 0, "", ""); // Dummy
1029 }
1030 ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer());
1031 if(ex)
1032 {
1033 $$ = ex->createDataMember(name, type, false, 0, 0, "", ""); // Dummy
1034 }
1035 assert($$);
1036 unit->error("keyword `" + name + "' cannot be used as data member name");
1037 }
1038 | type
1039 {
1040 TypePtr type = TypePtr::dynamicCast($1);
1041 ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer());
1042 if(cl)
1043 {
1044 $$ = cl->createDataMember(IceUtil::generateUUID(), type, false, 0, 0, "", ""); // Dummy
1045 }
1046 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
1047 if(st)
1048 {
1049 $$ = st->createDataMember(IceUtil::generateUUID(), type, false, 0, 0, "", ""); // Dummy
1050 }
1051 ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer());
1052 if(ex)
1053 {
1054 $$ = ex->createDataMember(IceUtil::generateUUID(), type, false, 0, 0, "", ""); // Dummy
1055 }
1056 assert($$);
1057 unit->error("missing data member name");
1058 }
1059 ;
1060
1061 // ----------------------------------------------------------------------
1062 struct_data_member
1063 // ----------------------------------------------------------------------
1064 : type_id
1065 {
1066 TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($1);
1067 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
1068 assert(st);
1069 DataMemberPtr dm = st->createDataMember(ts->v.second, ts->v.first, false, -1, 0, "", "");
1070 unit->currentContainer()->checkIntroduced(ts->v.second, dm);
1071 $$ = dm;
1072 }
1073 | type_id '=' const_initializer
1074 {
1075 TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($1);
1076 ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($3);
1077 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
1078 assert(st);
1079 DataMemberPtr dm = st->createDataMember(ts->v.second, ts->v.first, false, -1, value->v.value,
1080 value->v.valueAsString, value->v.valueAsLiteral);
1081 unit->currentContainer()->checkIntroduced(ts->v.second, dm);
1082 $$ = dm;
1083 }
1084 | optional type_id
1085 {
1086 TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($2);
1087 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
1088 assert(st);
1089 $$ = st->createDataMember(ts->v.second, ts->v.first, false, 0, 0, "", ""); // Dummy
1090 assert($$);
1091 unit->error("optional data members not supported in struct");
1092 }
1093 | optional type_id '=' const_initializer
1094 {
1095 TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($2);
1096 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
1097 assert(st);
1098 $$ = st->createDataMember(ts->v.second, ts->v.first, false, 0, 0, "", ""); // Dummy
1099 assert($$);
1100 unit->error("optional data members not supported in struct");
1101 }
1102 | type keyword
1103 {
1104 TypePtr type = TypePtr::dynamicCast($1);
1105 string name = StringTokPtr::dynamicCast($2)->v;
1106 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
1107 assert(st);
1108 $$ = st->createDataMember(name, type, false, 0, 0, "", ""); // Dummy
1109 assert($$);
1110 unit->error("keyword `" + name + "' cannot be used as data member name");
1111 }
1112 | type
1113 {
1114 TypePtr type = TypePtr::dynamicCast($1);
1115 StructPtr st = StructPtr::dynamicCast(unit->currentContainer());
1116 assert(st);
1117 $$ = st->createDataMember(IceUtil::generateUUID(), type, false, 0, 0, "", ""); // Dummy
1118 assert($$);
1119 unit->error("missing data member name");
1120 }
1121 ;
1122
1123 // ----------------------------------------------------------------------
1124 return_type
1125 // ----------------------------------------------------------------------
1126 : optional type
1127 {
1128 OptionalDefTokPtr m = OptionalDefTokPtr::dynamicCast($1);
1129 m->v.type = TypePtr::dynamicCast($2);
1130 $$ = m;
1131 }
1132 | type
1133 {
1134 OptionalDefTokPtr m = new OptionalDefTok();
1135 m->v.type = TypePtr::dynamicCast($1);
1136 m->v.optional = false;
1137 m->v.tag = -1;
1138 $$ = m;
1139 }
1140 | ICE_VOID
1141 {
1142 OptionalDefTokPtr m = new OptionalDefTok;
1143 m->v.optional = false;
1144 m->v.tag = -1;
1145 $$ = m;
1146 }
1147 ;
1148
1149 // ----------------------------------------------------------------------
1150 operation_preamble
1151 // ----------------------------------------------------------------------
1152 : return_type ICE_IDENT_OP
1153 {
1154 OptionalDefTokPtr returnType = OptionalDefTokPtr::dynamicCast($1);
1155 string name = StringTokPtr::dynamicCast($2)->v;
1156 ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer());
1157 if(cl)
1158 {
1159 OperationPtr op = cl->createOperation(name, returnType->v.type, returnType->v.optional, returnType->v.tag);
1160 if(op)
1161 {
1162 cl->checkIntroduced(name, op);
1163 unit->pushContainer(op);
1164 $$ = op;
1165 }
1166 else
1167 {
1168 $$ = 0;
1169 }
1170 }
1171 else
1172 {
1173 $$ = 0;
1174 }
1175 }
1176 | ICE_IDEMPOTENT return_type ICE_IDENT_OP
1177 {
1178 OptionalDefTokPtr returnType = OptionalDefTokPtr::dynamicCast($2);
1179 string name = StringTokPtr::dynamicCast($3)->v;
1180 ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer());
1181 if(cl)
1182 {
1183 OperationPtr op = cl->createOperation(name, returnType->v.type, returnType->v.optional, returnType->v.tag,
1184 Operation::Idempotent);
1185 if(op)
1186 {
1187 cl->checkIntroduced(name, op);
1188 unit->pushContainer(op);
1189 $$ = op;
1190 }
1191 else
1192 {
1193 $$ = 0;
1194 }
1195 }
1196 else
1197 {
1198 $$ = 0;
1199 }
1200 }
1201 | return_type ICE_KEYWORD_OP
1202 {
1203 OptionalDefTokPtr returnType = OptionalDefTokPtr::dynamicCast($1);
1204 string name = StringTokPtr::dynamicCast($2)->v;
1205 ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer());
1206 if(cl)
1207 {
1208 OperationPtr op = cl->createOperation(name, returnType->v.type, returnType->v.optional, returnType->v.tag);
1209 if(op)
1210 {
1211 unit->pushContainer(op);
1212 unit->error("keyword `" + name + "' cannot be used as operation name");
1213 $$ = op; // Dummy
1214 }
1215 else
1216 {
1217 $$ = 0;
1218 }
1219 }
1220 else
1221 {
1222 $$ = 0;
1223 }
1224 }
1225 | ICE_IDEMPOTENT return_type ICE_KEYWORD_OP
1226 {
1227 OptionalDefTokPtr returnType = OptionalDefTokPtr::dynamicCast($2);
1228 string name = StringTokPtr::dynamicCast($3)->v;
1229 ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer());
1230 if(cl)
1231 {
1232 OperationPtr op = cl->createOperation(name, returnType->v.type, returnType->v.optional, returnType->v.tag,
1233 Operation::Idempotent);
1234 if(op)
1235 {
1236 unit->pushContainer(op);
1237 unit->error("keyword `" + name + "' cannot be used as operation name");
1238 $$ = op; // Dummy
1239 }
1240 else
1241 {
1242 return 0;
1243 }
1244 }
1245 else
1246 {
1247 $$ = 0;
1248 }
1249 }
1250 ;
1251
1252 // ----------------------------------------------------------------------
1253 operation
1254 // ----------------------------------------------------------------------
1255 : operation_preamble parameters ')'
1256 {
1257 if($1)
1258 {
1259 unit->popContainer();
1260 $$ = $1;
1261 }
1262 else
1263 {
1264 $$ = 0;
1265 }
1266 }
1267 throws
1268 {
1269 OperationPtr op = OperationPtr::dynamicCast($4);
1270 ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($5);
1271 assert(el);
1272 if(op)
1273 {
1274 op->setExceptionList(el->v);
1275 }
1276 }
1277 | operation_preamble error ')'
1278 {
1279 if($1)
1280 {
1281 unit->popContainer();
1282 }
1283 yyerrok;
1284 }
1285 throws
1286 {
1287 OperationPtr op = OperationPtr::dynamicCast($4);
1288 ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($5);
1289 assert(el);
1290 if(op)
1291 {
1292 op->setExceptionList(el->v); // Dummy
1293 }
1294 }
1295 ;
1296
1297 // ----------------------------------------------------------------------
1298 class_export
1299 // ----------------------------------------------------------------------
1300 : data_member
1301 | operation
1302 ;
1303
1304 // ----------------------------------------------------------------------
1305 interface_id
1306 // ----------------------------------------------------------------------
1307 : ICE_INTERFACE ICE_IDENTIFIER
1308 {
1309 $$ = $2;
1310 }
1311 | ICE_INTERFACE keyword
1312 {
1313 StringTokPtr ident = StringTokPtr::dynamicCast($2);
1314 unit->error("keyword `" + ident->v + "' cannot be used as interface name");
1315 $$ = $2; // Dummy
1316 }
1317 ;
1318
1319 // ----------------------------------------------------------------------
1320 interface_decl
1321 // ----------------------------------------------------------------------
1322 : local_qualifier interface_id
1323 {
1324 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
1325 StringTokPtr ident = StringTokPtr::dynamicCast($2);
1326 ContainerPtr cont = unit->currentContainer();
1327 ClassDeclPtr cl = cont->createClassDecl(ident->v, true, local->v);
1328 cont->checkIntroduced(ident->v, cl);
1329 $$ = cl;
1330 }
1331 ;
1332
1333 // ----------------------------------------------------------------------
1334 interface_def
1335 // ----------------------------------------------------------------------
1336 : local_qualifier interface_id interface_extends
1337 {
1338 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
1339 StringTokPtr ident = StringTokPtr::dynamicCast($2);
1340 ContainerPtr cont = unit->currentContainer();
1341 ClassListTokPtr bases = ClassListTokPtr::dynamicCast($3);
1342 ClassDefPtr cl = cont->createClassDef(ident->v, -1, true, bases->v, local->v);
1343 if(cl)
1344 {
1345 cont->checkIntroduced(ident->v, cl);
1346 unit->pushContainer(cl);
1347 $$ = cl;
1348 }
1349 else
1350 {
1351 $$ = 0;
1352 }
1353 }
1354 '{' interface_exports '}'
1355 {
1356 if($4)
1357 {
1358 unit->popContainer();
1359 $$ = $4;
1360 }
1361 else
1362 {
1363 $$ = 0;
1364 }
1365 }
1366 ;
1367
1368 // ----------------------------------------------------------------------
1369 interface_list
1370 // ----------------------------------------------------------------------
1371 : scoped_name ',' interface_list
1372 {
1373 ClassListTokPtr intfs = ClassListTokPtr::dynamicCast($3);
1374 StringTokPtr scoped = StringTokPtr::dynamicCast($1);
1375 ContainerPtr cont = unit->currentContainer();
1376 TypeList types = cont->lookupType(scoped->v);
1377 if(!types.empty())
1378 {
1379 ClassDeclPtr cl = ClassDeclPtr::dynamicCast(types.front());
1380 if(!cl || !cl->isInterface())
1381 {
1382 string msg = "`";
1383 msg += scoped->v;
1384 msg += "' is not an interface";
1385 unit->error(msg);
1386 }
1387 else
1388 {
1389 ClassDefPtr def = cl->definition();
1390 if(!def)
1391 {
1392 string msg = "`";
1393 msg += scoped->v;
1394 msg += "' has been declared but not defined";
1395 unit->error(msg);
1396 }
1397 else
1398 {
1399 cont->checkIntroduced(scoped->v);
1400 intfs->v.push_front(def);
1401 }
1402 }
1403 }
1404 $$ = intfs;
1405 }
1406 | scoped_name
1407 {
1408 ClassListTokPtr intfs = new ClassListTok;
1409 StringTokPtr scoped = StringTokPtr::dynamicCast($1);
1410 ContainerPtr cont = unit->currentContainer();
1411 TypeList types = cont->lookupType(scoped->v);
1412 if(!types.empty())
1413 {
1414 ClassDeclPtr cl = ClassDeclPtr::dynamicCast(types.front());
1415 if(!cl || !cl->isInterface())
1416 {
1417 string msg = "`";
1418 msg += scoped->v;
1419 msg += "' is not an interface";
1420 unit->error(msg); // $$ is a dummy
1421 }
1422 else
1423 {
1424 ClassDefPtr def = cl->definition();
1425 if(!def)
1426 {
1427 string msg = "`";
1428 msg += scoped->v;
1429 msg += "' has been declared but not defined";
1430 unit->error(msg); // $$ is a dummy
1431 }
1432 else
1433 {
1434 cont->checkIntroduced(scoped->v);
1435 intfs->v.push_front(def);
1436 }
1437 }
1438 }
1439 $$ = intfs;
1440 }
1441 | ICE_OBJECT
1442 {
1443 unit->error("illegal inheritance from type Object");
1444 $$ = new ClassListTok; // Dummy
1445 }
1446 | ICE_VALUE
1447 {
1448 unit->error("illegal inheritance from type Value");
1449 $$ = new ClassListTok; // Dummy
1450 }
1451 ;
1452
1453 // ----------------------------------------------------------------------
1454 interface_extends
1455 // ----------------------------------------------------------------------
1456 : ICE_EXTENDS interface_list
1457 {
1458 $$ = $2;
1459 }
1460 |
1461 {
1462 $$ = new ClassListTok;
1463 }
1464 ;
1465
1466 // ----------------------------------------------------------------------
1467 interface_exports
1468 // ----------------------------------------------------------------------
1469 : meta_data interface_export ';' interface_exports
1470 {
1471 StringListTokPtr metaData = StringListTokPtr::dynamicCast($1);
1472 ContainedPtr contained = ContainedPtr::dynamicCast($2);
1473 if(contained && !metaData->v.empty())
1474 {
1475 contained->setMetaData(metaData->v);
1476 }
1477 }
1478 | error ';' interface_exports
1479 {
1480 }
1481 | meta_data interface_export
1482 {
1483 unit->error("`;' missing after definition");
1484 }
1485 |
1486 {
1487 }
1488 ;
1489
1490 // ----------------------------------------------------------------------
1491 interface_export
1492 // ----------------------------------------------------------------------
1493 : operation
1494 ;
1495
1496 // ----------------------------------------------------------------------
1497 exception_list
1498 // ----------------------------------------------------------------------
1499 : exception ',' exception_list
1500 {
1501 ExceptionPtr exception = ExceptionPtr::dynamicCast($1);
1502 ExceptionListTokPtr exceptionList = ExceptionListTokPtr::dynamicCast($3);
1503 exceptionList->v.push_front(exception);
1504 $$ = exceptionList;
1505 }
1506 | exception
1507 {
1508 ExceptionPtr exception = ExceptionPtr::dynamicCast($1);
1509 ExceptionListTokPtr exceptionList = new ExceptionListTok;
1510 exceptionList->v.push_front(exception);
1511 $$ = exceptionList;
1512 }
1513 ;
1514
1515 // ----------------------------------------------------------------------
1516 exception
1517 // ----------------------------------------------------------------------
1518 : scoped_name
1519 {
1520 StringTokPtr scoped = StringTokPtr::dynamicCast($1);
1521 ContainerPtr cont = unit->currentContainer();
1522 ExceptionPtr exception = cont->lookupException(scoped->v);
1523 if(!exception)
1524 {
1525 exception = cont->createException(IceUtil::generateUUID(), 0, false, Dummy); // Dummy
1526 }
1527 cont->checkIntroduced(scoped->v, exception);
1528 $$ = exception;
1529 }
1530 | keyword
1531 {
1532 StringTokPtr ident = StringTokPtr::dynamicCast($1);
1533 unit->error("keyword `" + ident->v + "' cannot be used as exception name");
1534 $$ = unit->currentContainer()->createException(IceUtil::generateUUID(), 0, false, Dummy); // Dummy
1535 }
1536 ;
1537
1538 // ----------------------------------------------------------------------
1539 sequence_def
1540 // ----------------------------------------------------------------------
1541 : local_qualifier ICE_SEQUENCE '<' meta_data type '>' ICE_IDENTIFIER
1542 {
1543 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
1544 StringTokPtr ident = StringTokPtr::dynamicCast($7);
1545 StringListTokPtr metaData = StringListTokPtr::dynamicCast($4);
1546 TypePtr type = TypePtr::dynamicCast($5);
1547 ContainerPtr cont = unit->currentContainer();
1548 $$ = cont->createSequence(ident->v, type, metaData->v, local->v);
1549 }
1550 | local_qualifier ICE_SEQUENCE '<' meta_data type '>' keyword
1551 {
1552 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
1553 StringTokPtr ident = StringTokPtr::dynamicCast($7);
1554 StringListTokPtr metaData = StringListTokPtr::dynamicCast($4);
1555 TypePtr type = TypePtr::dynamicCast($5);
1556 ContainerPtr cont = unit->currentContainer();
1557 $$ = cont->createSequence(ident->v, type, metaData->v, local->v); // Dummy
1558 unit->error("keyword `" + ident->v + "' cannot be used as sequence name");
1559 }
1560 ;
1561
1562 // ----------------------------------------------------------------------
1563 dictionary_def
1564 // ----------------------------------------------------------------------
1565 : local_qualifier ICE_DICTIONARY '<' meta_data type ',' meta_data type '>' ICE_IDENTIFIER
1566 {
1567 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
1568 StringTokPtr ident = StringTokPtr::dynamicCast($10);
1569 StringListTokPtr keyMetaData = StringListTokPtr::dynamicCast($4);
1570 TypePtr keyType = TypePtr::dynamicCast($5);
1571 StringListTokPtr valueMetaData = StringListTokPtr::dynamicCast($7);
1572 TypePtr valueType = TypePtr::dynamicCast($8);
1573 ContainerPtr cont = unit->currentContainer();
1574 $$ = cont->createDictionary(ident->v, keyType, keyMetaData->v, valueType, valueMetaData->v, local->v);
1575 }
1576 | local_qualifier ICE_DICTIONARY '<' meta_data type ',' meta_data type '>' keyword
1577 {
1578 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
1579 StringTokPtr ident = StringTokPtr::dynamicCast($10);
1580 StringListTokPtr keyMetaData = StringListTokPtr::dynamicCast($4);
1581 TypePtr keyType = TypePtr::dynamicCast($5);
1582 StringListTokPtr valueMetaData = StringListTokPtr::dynamicCast($7);
1583 TypePtr valueType = TypePtr::dynamicCast($8);
1584 ContainerPtr cont = unit->currentContainer();
1585 $$ = cont->createDictionary(ident->v, keyType, keyMetaData->v, valueType, valueMetaData->v, local->v); // Dummy
1586 unit->error("keyword `" + ident->v + "' cannot be used as dictionary name");
1587 }
1588 ;
1589
1590 // ----------------------------------------------------------------------
1591 enum_id
1592 // ----------------------------------------------------------------------
1593 : ICE_ENUM ICE_IDENTIFIER
1594 {
1595 $$ = $2;
1596 }
1597 | ICE_ENUM keyword
1598 {
1599 StringTokPtr ident = StringTokPtr::dynamicCast($2);
1600 unit->error("keyword `" + ident->v + "' cannot be used as enumeration name");
1601 $$ = $2; // Dummy
1602 }
1603 ;
1604
1605 // ----------------------------------------------------------------------
1606 enum_def
1607 // ----------------------------------------------------------------------
1608 : local_qualifier enum_id
1609 {
1610 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
1611 StringTokPtr ident = StringTokPtr::dynamicCast($2);
1612 ContainerPtr cont = unit->currentContainer();
1613 EnumPtr en = cont->createEnum(ident->v, local->v);
1614 if(en)
1615 {
1616 cont->checkIntroduced(ident->v, en);
1617 }
1618 else
1619 {
1620 en = cont->createEnum(IceUtil::generateUUID(), local->v, Dummy);
1621 }
1622 unit->pushContainer(en);
1623 $$ = en;
1624 }
1625 '{' enumerator_list '}'
1626 {
1627 EnumPtr en = EnumPtr::dynamicCast($3);
1628 if(en)
1629 {
1630 EnumeratorListTokPtr enumerators = EnumeratorListTokPtr::dynamicCast($5);
1631 if(enumerators->v.empty())
1632 {
1633 unit->error("enum `" + en->name() + "' must have at least one enumerator");
1634 }
1635 unit->popContainer();
1636 }
1637 $$ = $3;
1638 }
1639 |
1640 local_qualifier ICE_ENUM
1641 {
1642 unit->error("missing enumeration name");
1643 BoolTokPtr local = BoolTokPtr::dynamicCast($1);
1644 ContainerPtr cont = unit->currentContainer();
1645 EnumPtr en = cont->createEnum(IceUtil::generateUUID(), local->v, Dummy);
1646 unit->pushContainer(en);
1647 $$ = en;
1648 }
1649 '{' enumerator_list '}'
1650 {
1651 unit->popContainer();
1652 $$ = $2;
1653 }
1654 ;
1655
1656 // ----------------------------------------------------------------------
1657 enumerator_list
1658 // ----------------------------------------------------------------------
1659 : enumerator ',' enumerator_list
1660 {
1661 EnumeratorListTokPtr ens = EnumeratorListTokPtr::dynamicCast($1);
1662 ens->v.splice(ens->v.end(), EnumeratorListTokPtr::dynamicCast($3)->v);
1663 $$ = ens;
1664 }
1665 | enumerator
1666 {
1667 }
1668 ;
1669
1670 // ----------------------------------------------------------------------
1671 enumerator
1672 // ----------------------------------------------------------------------
1673 : ICE_IDENTIFIER
1674 {
1675 StringTokPtr ident = StringTokPtr::dynamicCast($1);
1676 EnumeratorListTokPtr ens = new EnumeratorListTok;
1677 ContainerPtr cont = unit->currentContainer();
1678 EnumeratorPtr en = cont->createEnumerator(ident->v);
1679 if(en)
1680 {
1681 ens->v.push_front(en);
1682 }
1683 $$ = ens;
1684 }
1685 | ICE_IDENTIFIER '=' enumerator_initializer
1686 {
1687 StringTokPtr ident = StringTokPtr::dynamicCast($1);
1688 EnumeratorListTokPtr ens = new EnumeratorListTok;
1689 ContainerPtr cont = unit->currentContainer();
1690 IntegerTokPtr intVal = IntegerTokPtr::dynamicCast($3);
1691 if(intVal)
1692 {
1693 if(intVal->v < 0 || intVal->v > Int32Max)
1694 {
1695 unit->error("value for enumerator `" + ident->v + "' is out of range");
1696 }
1697 else
1698 {
1699 EnumeratorPtr en = cont->createEnumerator(ident->v, static_cast<int>(intVal->v));
1700 ens->v.push_front(en);
1701 }
1702 }
1703 $$ = ens;
1704 }
1705 | keyword
1706 {
1707 StringTokPtr ident = StringTokPtr::dynamicCast($1);
1708 unit->error("keyword `" + ident->v + "' cannot be used as enumerator");
1709 EnumeratorListTokPtr ens = new EnumeratorListTok; // Dummy
1710 $$ = ens;
1711 }
1712 |
1713 {
1714 EnumeratorListTokPtr ens = new EnumeratorListTok;
1715 $$ = ens; // Dummy
1716 }
1717 ;
1718
1719 // ----------------------------------------------------------------------
1720 enumerator_initializer
1721 // ----------------------------------------------------------------------
1722 : ICE_INTEGER_LITERAL
1723 {
1724 $$ = $1;
1725 }
1726 | scoped_name
1727 {
1728 StringTokPtr scoped = StringTokPtr::dynamicCast($1);
1729 ContainedList cl = unit->currentContainer()->lookupContained(scoped->v);
1730 IntegerTokPtr tok;
1731 if(!cl.empty())
1732 {
1733 ConstPtr constant = ConstPtr::dynamicCast(cl.front());
1734 if(constant)
1735 {
1736 unit->currentContainer()->checkIntroduced(scoped->v, constant);
1737 BuiltinPtr b = BuiltinPtr::dynamicCast(constant->type());
1738 if(b && (b->kind() == Builtin::KindByte || b->kind() == Builtin::KindShort ||
1739 b->kind() == Builtin::KindInt || b->kind() == Builtin::KindLong))
1740 {
1741 IceUtil::Int64 v;
1742 if(IceUtilInternal::stringToInt64(constant->value(), v))
1743 {
1744 tok = new IntegerTok;
1745 tok->v = v;
1746 tok->literal = constant->value();
1747 }
1748 }
1749 }
1750 }
1751
1752 if(!tok)
1753 {
1754 string msg = "illegal initializer: `" + scoped->v + "' is not an integer constant";
1755 unit->error(msg); // $$ is dummy
1756 }
1757
1758 $$ = tok;
1759 }
1760 ;
1761
1762 // ----------------------------------------------------------------------
1763 out_qualifier
1764 // ----------------------------------------------------------------------
1765 : ICE_OUT
1766 {
1767 BoolTokPtr out = new BoolTok;
1768 out->v = true;
1769 $$ = out;
1770 }
1771 |
1772 {
1773 BoolTokPtr out = new BoolTok;
1774 out->v = false;
1775 $$ = out;
1776 }
1777 ;
1778
1779 // ----------------------------------------------------------------------
1780 parameters
1781 // ----------------------------------------------------------------------
1782 : // empty
1783 {
1784 }
1785 | out_qualifier meta_data optional_type_id
1786 {
1787 BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($1);
1788 OptionalDefTokPtr tsp = OptionalDefTokPtr::dynamicCast($3);
1789 OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer());
1790 if(op)
1791 {
1792 ParamDeclPtr pd = op->createParamDecl(tsp->v.name, tsp->v.type, isOutParam->v, tsp->v.optional, tsp->v.tag);
1793 unit->currentContainer()->checkIntroduced(tsp->v.name, pd);
1794 StringListTokPtr metaData = StringListTokPtr::dynamicCast($2);
1795 if(!metaData->v.empty())
1796 {
1797 pd->setMetaData(metaData->v);
1798 }
1799 }
1800 }
1801 | parameters ',' out_qualifier meta_data optional_type_id
1802 {
1803 BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($3);
1804 OptionalDefTokPtr tsp = OptionalDefTokPtr::dynamicCast($5);
1805 OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer());
1806 if(op)
1807 {
1808 ParamDeclPtr pd = op->createParamDecl(tsp->v.name, tsp->v.type, isOutParam->v, tsp->v.optional, tsp->v.tag);
1809 unit->currentContainer()->checkIntroduced(tsp->v.name, pd);
1810 StringListTokPtr metaData = StringListTokPtr::dynamicCast($4);
1811 if(!metaData->v.empty())
1812 {
1813 pd->setMetaData(metaData->v);
1814 }
1815 }
1816 }
1817 | out_qualifier meta_data type keyword
1818 {
1819 BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($1);
1820 TypePtr type = TypePtr::dynamicCast($3);
1821 StringTokPtr ident = StringTokPtr::dynamicCast($4);
1822 OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer());
1823 if(op)
1824 {
1825 op->createParamDecl(ident->v, type, isOutParam->v, false, 0); // Dummy
1826 unit->error("keyword `" + ident->v + "' cannot be used as parameter name");
1827 }
1828 }
1829 | parameters ',' out_qualifier meta_data type keyword
1830 {
1831 BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($3);
1832 TypePtr type = TypePtr::dynamicCast($5);
1833 StringTokPtr ident = StringTokPtr::dynamicCast($6);
1834 OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer());
1835 if(op)
1836 {
1837 op->createParamDecl(ident->v, type, isOutParam->v, false, 0); // Dummy
1838 unit->error("keyword `" + ident->v + "' cannot be used as parameter name");
1839 }
1840 }
1841 | out_qualifier meta_data type
1842 {
1843 BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($1);
1844 TypePtr type = TypePtr::dynamicCast($3);
1845 OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer());
1846 if(op)
1847 {
1848 op->createParamDecl(IceUtil::generateUUID(), type, isOutParam->v, false, 0); // Dummy
1849 unit->error("missing parameter name");
1850 }
1851 }
1852 | parameters ',' out_qualifier meta_data type
1853 {
1854 BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($3);
1855 TypePtr type = TypePtr::dynamicCast($5);
1856 OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer());
1857 if(op)
1858 {
1859 op->createParamDecl(IceUtil::generateUUID(), type, isOutParam->v, false, 0); // Dummy
1860 unit->error("missing parameter name");
1861 }
1862 }
1863 ;
1864
1865 // ----------------------------------------------------------------------
1866 throws
1867 // ----------------------------------------------------------------------
1868 : ICE_THROWS exception_list
1869 {
1870 $$ = $2;
1871 }
1872 |
1873 {
1874 $$ = new ExceptionListTok;
1875 }
1876 ;
1877
1878 // ----------------------------------------------------------------------
1879 scoped_name
1880 // ----------------------------------------------------------------------
1881 : ICE_IDENTIFIER
1882 {
1883 }
1884 | ICE_SCOPED_IDENTIFIER
1885 {
1886 }
1887 ;
1888
1889 // ----------------------------------------------------------------------
1890 type
1891 // ----------------------------------------------------------------------
1892 : ICE_BYTE
1893 {
1894 $$ = unit->builtin(Builtin::KindByte);
1895 }
1896 | ICE_BOOL
1897 {
1898 $$ = unit->builtin(Builtin::KindBool);
1899 }
1900 | ICE_SHORT
1901 {
1902 $$ = unit->builtin(Builtin::KindShort);
1903 }
1904 | ICE_INT
1905 {
1906 $$ = unit->builtin(Builtin::KindInt);
1907 }
1908 | ICE_LONG
1909 {
1910 $$ = unit->builtin(Builtin::KindLong);
1911 }
1912 | ICE_FLOAT
1913 {
1914 $$ = unit->builtin(Builtin::KindFloat);
1915 }
1916 | ICE_DOUBLE
1917 {
1918 $$ = unit->builtin(Builtin::KindDouble);
1919 }
1920 | ICE_STRING
1921 {
1922 $$ = unit->builtin(Builtin::KindString);
1923 }
1924 | ICE_OBJECT
1925 {
1926 $$ = unit->builtin(Builtin::KindObject);
1927 }
1928 | ICE_OBJECT '*'
1929 {
1930 $$ = unit->builtin(Builtin::KindObjectProxy);
1931 }
1932 | ICE_LOCAL_OBJECT
1933 {
1934 $$ = unit->builtin(Builtin::KindLocalObject);
1935 }
1936 | ICE_VALUE
1937 {
1938 $$ = unit->builtin(Builtin::KindValue);
1939 }
1940 | scoped_name
1941 {
1942 StringTokPtr scoped = StringTokPtr::dynamicCast($1);
1943 ContainerPtr cont = unit->currentContainer();
1944 if(cont)
1945 {
1946 TypeList types = cont->lookupType(scoped->v);
1947 if(types.empty())
1948 {
1949 YYERROR; // Can't continue, jump to next yyerrok
1950 }
1951 cont->checkIntroduced(scoped->v);
1952 $$ = types.front();
1953 }
1954 else
1955 {
1956 $$ = 0;
1957 }
1958 }
1959 | scoped_name '*'
1960 {
1961 StringTokPtr scoped = StringTokPtr::dynamicCast($1);
1962 ContainerPtr cont = unit->currentContainer();
1963 if(cont)
1964 {
1965 TypeList types = cont->lookupType(scoped->v);
1966 if(types.empty())
1967 {
1968 YYERROR; // Can't continue, jump to next yyerrok
1969 }
1970 for(TypeList::iterator p = types.begin(); p != types.end(); ++p)
1971 {
1972 ClassDeclPtr cl = ClassDeclPtr::dynamicCast(*p);
1973 if(!cl)
1974 {
1975 string msg = "`";
1976 msg += scoped->v;
1977 msg += "' must be class or interface";
1978 unit->error(msg);
1979 YYERROR; // Can't continue, jump to next yyerrok
1980 }
1981 cont->checkIntroduced(scoped->v);
1982 if(cl->isLocal())
1983 {
1984 unit->error("cannot create proxy for " + cl->kindOf() + " `" + cl->name() + "'"); // $$ is dummy
1985 }
1986 *p = new Proxy(cl);
1987 }
1988 $$ = types.front();
1989 }
1990 else
1991 {
1992 $$ = 0;
1993 }
1994 }
1995 ;
1996
1997 // ----------------------------------------------------------------------
1998 string_literal
1999 // ----------------------------------------------------------------------
2000 : ICE_STRING_LITERAL string_literal // Adjacent string literals are concatenated
2001 {
2002 StringTokPtr str1 = StringTokPtr::dynamicCast($1);
2003 StringTokPtr str2 = StringTokPtr::dynamicCast($2);
2004 str1->v += str2->v;
2005 }
2006 | ICE_STRING_LITERAL
2007 {
2008 }
2009 ;
2010
2011 // ----------------------------------------------------------------------
2012 string_list
2013 // ----------------------------------------------------------------------
2014 : string_list ',' string_literal
2015 {
2016 StringTokPtr str = StringTokPtr::dynamicCast($3);
2017 StringListTokPtr stringList = StringListTokPtr::dynamicCast($1);
2018 stringList->v.push_back(str->v);
2019 $$ = stringList;
2020 }
2021 | string_literal
2022 {
2023 StringTokPtr str = StringTokPtr::dynamicCast($1);
2024 StringListTokPtr stringList = new StringListTok;
2025 stringList->v.push_back(str->v);
2026 $$ = stringList;
2027 }
2028 ;
2029
2030 // ----------------------------------------------------------------------
2031 local_qualifier
2032 // ----------------------------------------------------------------------
2033 : ICE_LOCAL
2034 {
2035 BoolTokPtr local = new BoolTok;
2036 local->v = true;
2037 $$ = local;
2038 }
2039 |
2040 {
2041 BoolTokPtr local = new BoolTok;
2042 local->v = false;
2043 $$ = local;
2044 }
2045 ;
2046
2047 // ----------------------------------------------------------------------
2048 const_initializer
2049 // ----------------------------------------------------------------------
2050 : ICE_INTEGER_LITERAL
2051 {
2052 BuiltinPtr type = unit->builtin(Builtin::KindLong);
2053 IntegerTokPtr intVal = IntegerTokPtr::dynamicCast($1);
2054 ostringstream sstr;
2055 sstr << intVal->v;
2056 ConstDefTokPtr def = new ConstDefTok;
2057 def->v.type = type;
2058 def->v.value = type;
2059 def->v.valueAsString = sstr.str();
2060 def->v.valueAsLiteral = intVal->literal;
2061 $$ = def;
2062 }
2063 | ICE_FLOATING_POINT_LITERAL
2064 {
2065 BuiltinPtr type = unit->builtin(Builtin::KindDouble);
2066 FloatingTokPtr floatVal = FloatingTokPtr::dynamicCast($1);
2067 ostringstream sstr;
2068 sstr << floatVal->v;
2069 ConstDefTokPtr def = new ConstDefTok;
2070 def->v.type = type;
2071 def->v.value = type;
2072 def->v.valueAsString = sstr.str();
2073 def->v.valueAsLiteral = floatVal->literal;
2074 $$ = def;
2075 }
2076 | scoped_name
2077 {
2078 StringTokPtr scoped = StringTokPtr::dynamicCast($1);
2079 ConstDefTokPtr def = new ConstDefTok;
2080 ContainedList cl = unit->currentContainer()->lookupContained(scoped->v, false);
2081 if(cl.empty())
2082 {
2083 // Could be an enumerator
2084 def->v.type = TypePtr(0);
2085 def->v.value = SyntaxTreeBasePtr(0);
2086 def->v.valueAsString = scoped->v;
2087 def->v.valueAsLiteral = scoped->v;
2088 }
2089 else
2090 {
2091 EnumeratorPtr enumerator = EnumeratorPtr::dynamicCast(cl.front());
2092 ConstPtr constant = ConstPtr::dynamicCast(cl.front());
2093 if(enumerator)
2094 {
2095 unit->currentContainer()->checkIntroduced(scoped->v, enumerator);
2096 def->v.type = enumerator->type();
2097 def->v.value = enumerator;
2098 def->v.valueAsString = scoped->v;
2099 def->v.valueAsLiteral = scoped->v;
2100 }
2101 else if(constant)
2102 {
2103 unit->currentContainer()->checkIntroduced(scoped->v, constant);
2104 def->v.value = constant;
2105 def->v.valueAsString = constant->value();
2106 def->v.valueAsLiteral = constant->value();
2107 }
2108 else
2109 {
2110 string msg = "illegal initializer: `" + scoped->v + "' is a";
2111 static const string vowels = "aeiou";
2112 string kindOf = cl.front()->kindOf();
2113 if(vowels.find_first_of(kindOf[0]) != string::npos)
2114 {
2115 msg += "n";
2116 }
2117 msg += " " + kindOf;
2118 unit->error(msg); // $$ is dummy
2119 }
2120 }
2121 $$ = def;
2122 }
2123 | ICE_STRING_LITERAL
2124 {
2125 BuiltinPtr type = unit->builtin(Builtin::KindString);
2126 StringTokPtr literal = StringTokPtr::dynamicCast($1);
2127 ConstDefTokPtr def = new ConstDefTok;
2128 def->v.type = type;
2129 def->v.value = type;
2130 def->v.valueAsString = literal->v;
2131 def->v.valueAsLiteral = literal->literal;
2132 $$ = def;
2133 }
2134 | ICE_FALSE
2135 {
2136 BuiltinPtr type = unit->builtin(Builtin::KindBool);
2137 StringTokPtr literal = StringTokPtr::dynamicCast($1);
2138 ConstDefTokPtr def = new ConstDefTok;
2139 def->v.type = type;
2140 def->v.value = type;
2141 def->v.valueAsString = "false";
2142 def->v.valueAsLiteral = "false";
2143 $$ = def;
2144 }
2145 | ICE_TRUE
2146 {
2147 BuiltinPtr type = unit->builtin(Builtin::KindBool);
2148 StringTokPtr literal = StringTokPtr::dynamicCast($1);
2149 ConstDefTokPtr def = new ConstDefTok;
2150 def->v.type = type;
2151 def->v.value = type;
2152 def->v.valueAsString = "true";
2153 def->v.valueAsLiteral = "true";
2154 $$ = def;
2155 }
2156 ;
2157
2158 // ----------------------------------------------------------------------
2159 const_def
2160 // ----------------------------------------------------------------------
2161 : ICE_CONST meta_data type ICE_IDENTIFIER '=' const_initializer
2162 {
2163 StringListTokPtr metaData = StringListTokPtr::dynamicCast($2);
2164 TypePtr const_type = TypePtr::dynamicCast($3);
2165 StringTokPtr ident = StringTokPtr::dynamicCast($4);
2166 ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($6);
2167 $$ = unit->currentContainer()->createConst(ident->v, const_type, metaData->v, value->v.value,
2168 value->v.valueAsString, value->v.valueAsLiteral);
2169 }
2170 | ICE_CONST meta_data type '=' const_initializer
2171 {
2172 StringListTokPtr metaData = StringListTokPtr::dynamicCast($2);
2173 TypePtr const_type = TypePtr::dynamicCast($3);
2174 ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($5);
2175 unit->error("missing constant name");
2176 $$ = unit->currentContainer()->createConst(IceUtil::generateUUID(), const_type, metaData->v, value->v.value,
2177 value->v.valueAsString, value->v.valueAsLiteral, Dummy); // Dummy
2178 }
2179 ;
2180
2181 // ----------------------------------------------------------------------
2182 keyword
2183 // ----------------------------------------------------------------------
2184 : ICE_MODULE
2185 {
2186 }
2187 | ICE_CLASS
2188 {
2189 }
2190 | ICE_INTERFACE
2191 {
2192 }
2193 | ICE_EXCEPTION
2194 {
2195 }
2196 | ICE_STRUCT
2197 {
2198 }
2199 | ICE_SEQUENCE
2200 {
2201 }
2202 | ICE_DICTIONARY
2203 {
2204 }
2205 | ICE_ENUM
2206 {
2207 }
2208 | ICE_OUT
2209 {
2210 }
2211 | ICE_EXTENDS
2212 {
2213 }
2214 | ICE_IMPLEMENTS
2215 {
2216 }
2217 | ICE_THROWS
2218 {
2219 }
2220 | ICE_VOID
2221 {
2222 }
2223 | ICE_BYTE
2224 {
2225 }
2226 | ICE_BOOL
2227 {
2228 }
2229 | ICE_SHORT
2230 {
2231 }
2232 | ICE_INT
2233 {
2234 }
2235 | ICE_LONG
2236 {
2237 }
2238 | ICE_FLOAT
2239 {
2240 }
2241 | ICE_DOUBLE
2242 {
2243 }
2244 | ICE_STRING
2245 {
2246 }
2247 | ICE_OBJECT
2248 {
2249 }
2250 | ICE_LOCAL_OBJECT
2251 {
2252 }
2253 | ICE_LOCAL
2254 {
2255 }
2256 | ICE_CONST
2257 {
2258 }
2259 | ICE_FALSE
2260 {
2261 }
2262 | ICE_TRUE
2263 {
2264 }
2265 | ICE_IDEMPOTENT
2266 {
2267 }
2268 | ICE_OPTIONAL
2269 {
2270 }
2271 | ICE_VALUE
2272 {
2273 }
2274 ;
2275
2276 %%
2277