1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 /*
25 * parser.yy - BISON grammar for IDLC 1.0
26 */
27
28 %{
29 #include <string.h>
30
31 #ifndef _IDLC_IDLC_HXX_
32 #include <idlc/idlc.hxx>
33 #endif
34 #ifndef _IDLC_ERRORHANDLER_HXX_
35 #include <idlc/errorhandler.hxx>
36 #endif
37 #ifndef _IDLC_FEHELPER_HXX_
38 #include <idlc/fehelper.hxx>
39 #endif
40 #ifndef _IDLC_EXPRESSION_HXX_
41 #include <idlc/astexpression.hxx>
42 #endif
43 #ifndef _IDLC_ASTCONSTANTS_HXX_
44 #include <idlc/astconstants.hxx>
45 #endif
46 #ifndef _IDLC_ASTCONSTANT_HXX_
47 #include <idlc/astconstant.hxx>
48 #endif
49 #ifndef _IDLC_ASTARRAY_HXX_
50 #include <idlc/astarray.hxx>
51 #endif
52 #ifndef _IDLC_ASTBASETYPE_HXX_
53 #include <idlc/astbasetype.hxx>
54 #endif
55 #ifndef _IDLC_ASTTYPEDEF_HXX_
56 #include <idlc/asttypedef.hxx>
57 #endif
58 #ifndef _IDLC_ASTEXCEPTION_HXX_
59 #include <idlc/astexception.hxx>
60 #endif
61 #ifndef _IDLC_ASTMEMBER_HXX_
62 #include <idlc/astmember.hxx>
63 #endif
64 #ifndef _IDLC_ASTENUM_HXX_
65 #include <idlc/astenum.hxx>
66 #endif
67 #ifndef _IDLC_ASTSEQUENCE_HXX_
68 #include <idlc/astsequence.hxx>
69 #endif
70 #ifndef _IDLC_ASTATTRIBUTE_HXX_
71 #include <idlc/astattribute.hxx>
72 #endif
73 #ifndef _IDLC_ASTOPERATION_HXX_
74 #include <idlc/astoperation.hxx>
75 #endif
76 #ifndef _IDLC_ASTPARAMETER_HXX_
77 #include <idlc/astparameter.hxx>
78 #endif
79 #ifndef _IDLC_ASTINTERFACEMEMBER_HXX_
80 #include <idlc/astinterfacemember.hxx>
81 #endif
82 #ifndef _IDLC_ASTSERVICEMEMBER_HXX_
83 #include <idlc/astservicemember.hxx>
84 #endif
85 #ifndef _IDLC_ASTOBSERVES_HXX_
86 #include <idlc/astobserves.hxx>
87 #endif
88 #ifndef _IDLC_ASTNEEDS_HXX_
89 #include <idlc/astneeds.hxx>
90 #endif
91 #ifndef _IDLC_ASTUNION_HXX_
92 #include <idlc/astunion.hxx>
93 #endif
94 #include "idlc/aststructinstance.hxx"
95
96 #include "attributeexceptions.hxx"
97
98 #include "rtl/strbuf.hxx"
99
100 #include <algorithm>
101 #include <vector>
102
103 using namespace ::rtl;
104
105 #define YYDEBUG 1
106 #define YYERROR_VERBOSE 1
107
108 extern int yylex(void);
109 void yyerror(char const *);
110
checkIdentifier(::rtl::OString * id)111 void checkIdentifier(::rtl::OString* id)
112 {
113 static short check = 0;
114 if (check == 0) {
115 if (idlc()->getOptions()->isValid("-cid"))
116 check = 1;
117 else
118 check = 2;
119 }
120
121 if ( id->indexOf('_') >= 0 )
122 if ( (id->pData->buffer[0] >= 97 && id->pData->buffer[0] <= 122)
123 || id->pData->buffer[0] == '_') {
124 if (check == 1) {
125 ::rtl::OStringBuffer msg(25 + id->getLength());
126 msg.append("mismatched identifier '");
127 msg.append(*id);
128 msg.append("'");
129 idlc()->error()->syntaxError(idlc()->getParseState(),
130 idlc()->getLineNumber(),
131 msg.getStr());
132 }
133 else
134 idlc()->error()->warning0(WIDL_WRONG_NAMING_CONV, id->getStr());
135 }
136 }
137
reportDoubleMemberDeclarations(AstInterface::DoubleMemberDeclarations const & doubleMembers)138 void reportDoubleMemberDeclarations(
139 AstInterface::DoubleMemberDeclarations const & doubleMembers)
140 {
141 for (AstInterface::DoubleMemberDeclarations::const_iterator i(
142 doubleMembers.begin());
143 i != doubleMembers.end(); ++i)
144 {
145 idlc()->error()->error2(EIDL_DOUBLE_MEMBER, i->first, i->second);
146 }
147 }
148
addInheritedInterface(AstInterface * ifc,rtl::OString const & name,bool optional,rtl::OUString const & documentation)149 void addInheritedInterface(
150 AstInterface * ifc, rtl::OString const & name, bool optional,
151 rtl::OUString const & documentation)
152 {
153 AstDeclaration * decl = ifc->lookupByName(name);
154 AstDeclaration const * resolved = resolveTypedefs(decl);
155 if (resolved != 0 && resolved->getNodeType() == NT_interface) {
156 if (idlc()->error()->checkPublished(decl)) {
157 if (!static_cast< AstInterface const * >(resolved)->isDefined()) {
158 idlc()->error()->inheritanceError(
159 NT_interface, &ifc->getScopedName(), decl);
160 } else {
161 AstInterface::DoubleDeclarations doubleDecls(
162 ifc->checkInheritedInterfaceClashes(
163 static_cast< AstInterface const * >(resolved),
164 optional));
165 if (doubleDecls.interfaces.empty()
166 && doubleDecls.members.empty())
167 {
168 ifc->addInheritedInterface(
169 static_cast< AstType * >(decl), optional,
170 documentation);
171 } else {
172 for (AstInterface::DoubleInterfaceDeclarations::iterator i(
173 doubleDecls.interfaces.begin());
174 i != doubleDecls.interfaces.end(); ++i)
175 {
176 idlc()->error()->error1(
177 EIDL_DOUBLE_INHERITANCE, *i);
178 }
179 reportDoubleMemberDeclarations(doubleDecls.members);
180 }
181 }
182 }
183 } else {
184 idlc()->error()->lookupError(
185 EIDL_INTERFACEMEMBER_LOOKUP, name, scopeAsDecl(ifc));
186 }
187 }
188
createNamedType(rtl::OString const * scopedName,DeclList const * typeArgs)189 AstDeclaration const * createNamedType(
190 rtl::OString const * scopedName, DeclList const * typeArgs)
191 {
192 AstDeclaration * decl = idlc()->scopes()->topNonNull()->lookupByName(
193 *scopedName);
194 AstDeclaration const * resolved = resolveTypedefs(decl);
195 if (decl == 0) {
196 idlc()->error()->lookupError(*scopedName);
197 } else if (!idlc()->error()->checkPublished(decl)) {
198 decl = 0;
199 } else if (resolved->getNodeType() == NT_struct) {
200 if (static_cast< AstStruct const * >(resolved)->getTypeParameterCount()
201 != (typeArgs == 0 ? 0 : typeArgs->size()))
202 {
203 idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
204 decl = 0;
205 } else if (typeArgs != 0) {
206 AstScope * global = idlc()->scopes()->bottom();
207 AstDeclaration * inst = new AstStructInstance(
208 static_cast< AstType * >(decl), typeArgs, global);
209 decl = global->addDeclaration(inst);
210 if (decl != inst) {
211 delete inst;
212 }
213 }
214 } else if (decl->isType()) {
215 if (typeArgs != 0) {
216 idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
217 decl = 0;
218 }
219 } else {
220 idlc()->error()->noTypeError(decl);
221 decl = 0;
222 }
223 delete scopedName;
224 delete typeArgs;
225 return decl;
226 }
227
includes(AstDeclaration const * type1,AstDeclaration const * type2)228 bool includes(AstDeclaration const * type1, AstDeclaration const * type2) {
229 OSL_ASSERT(type2 != 0);
230 if (type1 != 0) {
231 if (type1->getNodeType() == NT_instantiated_struct) {
232 AstStructInstance const * inst
233 = static_cast< AstStructInstance const * >(type1);
234 if (inst->getTypeTemplate() == type2) {
235 return true;
236 }
237 for (DeclList::const_iterator i(inst->getTypeArgumentsBegin());
238 i != inst->getTypeArgumentsEnd(); ++i)
239 {
240 if (includes(*i, type2)) {
241 return true;
242 }
243 }
244 } else if (type1 == type2) {
245 return true;
246 }
247 }
248 return false;
249 }
250
251 // Suppress any warnings from generated code:
252 #if defined __GNUC__
253 #pragma GCC system_header
254 #elif defined __SUNPRO_CC
255 #pragma disable_warn
256 #elif defined _MSC_VER
257 #pragma warning(push, 1)
258 #pragma warning(disable: 4273 4701 4706)
259 #endif
260 %}
261 /*
262 * Declare the type of values in the grammar
263 */
264 %union {
265 ExprType etval; /* Expression type */
266 AstDeclaration* dclval; /* Declaration */
267 AstDeclaration const * cdclval;
268 DeclList * dclsval;
269 AstExpression* exval; /* expression value */
270 ExprList* exlval; /* expression list value */
271 FeDeclarator* fdval; /* declarator value */
272 FeDeclList* dlval; /* declarator list value */
273 FeInheritanceHeader* ihval; /* inheritance header value */
274 ::rtl::OString* sval; /* OString value */
275 std::vector< rtl::OString > * svals;
276 sal_Char* strval; /* sal_Char* value */
277 sal_Bool bval; /* sal_Boolean* value */
278 sal_Int64 ival; /* sal_Int64 value */
279 sal_uInt64 uval; /* sal_uInt64 value */
280 sal_uInt32 ulval; /* sal_uInt32 value */
281 double dval; /* double value */
282 float fval; /* float value */
283 StringList* slval; /* StringList value */
284 LabelList* llval; /* LabelList value */
285 AstUnionLabel* lbval; /* union label value */
286 AstMember* mval; /* member value */
287 AttributeExceptions::Part attexcpval;
288 AttributeExceptions attexcval;
289 }
290
291 /*
292 * Token types: These are returned by the lexer
293 */
294
295 %token <sval> IDL_IDENTIFIER
296 %token IDL_ATTRIBUTE
297 %token IDL_BOUND
298 %token IDL_CASE
299 %token IDL_CONST
300 %token IDL_CONSTANTS
301 %token IDL_CONSTRAINED
302 %token IDL_DEFAULT
303 %token IDL_ENUM
304 %token IDL_EXCEPTION
305 %token IDL_INTERFACE
306 %token IDL_MAYBEAMBIGUOUS
307 %token IDL_MAYBEDEFAULT
308 %token IDL_MAYBEVOID
309 %token IDL_MODULE
310 %token IDL_NEEDS
311 %token IDL_OBSERVES
312 %token IDL_OPTIONAL
313 %token IDL_PROPERTY
314 %token IDL_RAISES
315 %token IDL_READONLY
316 %token IDL_REMOVEABLE
317 %token IDL_SERVICE
318 %token IDL_SEQUENCE
319 %token IDL_SINGLETON
320 %token IDL_STRUCT
321 %token IDL_SWITCH
322 %token IDL_TYPEDEF
323 %token IDL_TRANSIENT
324 %token IDL_UNION
325
326 %token IDL_ANY
327 %token IDL_CHAR
328 %token IDL_BOOLEAN
329 %token IDL_BYTE
330 %token IDL_DOUBLE
331 %token IDL_FLOAT
332 %token IDL_HYPER
333 %token IDL_LONG
334 %token IDL_SHORT
335 %token IDL_VOID
336 %token IDL_STRING
337 %token IDL_TYPE
338 %token IDL_UNSIGNED
339
340 %token IDL_TRUE
341 %token IDL_FALSE
342
343 %token IDL_IN
344 %token IDL_OUT
345 %token IDL_INOUT
346 %token IDL_ONEWAY
347
348 %token IDL_GET
349 %token IDL_SET
350
351 %token IDL_PUBLISHED
352
353 %token IDL_ELLIPSIS
354
355 %token <strval> IDL_LEFTSHIFT
356 %token <strval> IDL_RIGHTSHIFT
357 %token <strval> IDL_SCOPESEPARATOR
358
359 %token <ival> IDL_INTEGER_LITERAL
360 %token <uval> IDL_INTEGER_ULITERAL
361 %token <dval> IDL_FLOATING_PT_LITERAL
362
363 /*
364 * These are production names:
365 */
366 %type <dclval> type_dcl const_dcl
367 %type <dclval> array_declarator
368 %type <dclval> exception_name
369 %type <cdclval> array_type constructed_type_spec enum_type op_type_spec
370 %type <cdclval> sequence_type_spec simple_type_spec struct_type switch_type_spec
371 %type <cdclval> template_type_spec type_spec union_type
372 %type <cdclval> fundamental_type type_arg type_or_parameter
373 %type <dclsval> opt_raises raises exception_list
374 %type <attexcpval> opt_attribute_get_raises attribute_get_raises
375 %type <attexcpval> opt_attribute_set_raises attribute_set_raises
376 %type <dclsval> opt_type_args type_args
377
378 %type <sval> identifier
379 %type <sval> interface_decl
380 %type <sval> scoped_name inheritance_spec
381 %type <slval> scoped_names at_least_one_scoped_name
382
383 %type <etval> const_type integer_type char_type boolean_type
384 %type <etval> floating_pt_type any_type signed_int string_type
385 %type <etval> unsigned_int base_type_spec byte_type type_type
386
387 %type <exval> expression const_expr or_expr xor_expr and_expr
388 %type <exval> add_expr mult_expr unary_expr primary_expr shift_expr
389 %type <exval> literal positive_int_expr array_dim
390
391 %type <exlval> at_least_one_array_dim array_dims
392
393 %type <fdval> declarator simple_declarator complex_declarator
394 %type <dlval> declarators at_least_one_declarator
395
396 %type <ihval> exception_header structure_header interfaceheader
397
398 %type <ulval> flag_header opt_attrflags opt_attrflag operation_head
399 %type <ulval> direction service_interface_header service_service_header
400
401 %type <llval> case_labels at_least_one_case_label
402 %type <lbval> case_label
403 %type <mval> element_spec
404
405 %type <bval> optional_inherited_interface opt_rest opt_service_body
406
407 %type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises
408
409 %type <svals> opt_type_params type_params
410
411 %%
412 /*
413 * Grammar start here
414 */
415 start : definitions;
416
417 definitions :
418 definition definitions
419 | /* EMPTY */
420 ;
421
422 definition :
423 opt_published publishable_definition
424 | module_dcl
425 {
426 idlc()->setParseState(PS_ModuleDeclSeen);
427 }
428 ';'
429 {
430 idlc()->setParseState(PS_NoState);
431 }
432 | error ';'
433 {
434 yyerror("definitions");
435 yyerrok;
436 }
437 ;
438
439 opt_published:
440 IDL_PUBLISHED { idlc()->setPublished(true); }
441 | /* empty */ { idlc()->setPublished(false); }
442 ;
443
444 publishable_definition:
445 type_dcl
446 {
447 idlc()->setParseState(PS_TypeDeclSeen);
448 }
449 ';'
450 {
451 idlc()->setParseState(PS_NoState);
452 }
453 | const_dcl
454 {
455 idlc()->setParseState(PS_ConstantDeclSeen);
456 }
457 ';'
458 {
459 idlc()->setParseState(PS_NoState);
460 }
461 | exception_dcl
462 {
463 idlc()->setParseState(PS_ExceptionDeclSeen);
464 }
465 ';'
466 {
467 idlc()->setParseState(PS_NoState);
468 }
469 | interface
470 {
471 idlc()->setParseState(PS_InterfaceDeclSeen);
472 }
473 ';'
474 {
475 idlc()->setParseState(PS_NoState);
476 }
477 | service_dcl
478 {
479 idlc()->setParseState(PS_ServiceDeclSeen);
480 }
481 ';'
482 {
483 idlc()->setParseState(PS_NoState);
484 }
485 | singleton_dcl
486 {
487 idlc()->setParseState(PS_SingletonDeclSeen);
488 }
489 ';'
490 {
491 idlc()->setParseState(PS_NoState);
492 }
493 | constants_dcl
494 {
495 idlc()->setParseState(PS_ConstantsDeclSeen);
496 }
497 ';'
498 {
499 idlc()->setParseState(PS_NoState);
500 }
501 ;
502
503 module_dcl :
504 IDL_MODULE
505 {
506 idlc()->setParseState(PS_ModuleSeen);
507 idlc()->setPublished(false);
508 }
509 identifier
510 {
511 idlc()->setParseState(PS_ModuleIDSeen);
512 checkIdentifier($3);
513
514 AstScope* pScope = idlc()->scopes()->topNonNull();
515 AstModule* pModule = NULL;
516 AstDeclaration* pExists = NULL;
517
518 if ( pScope )
519 {
520 pModule = new AstModule(*$3, pScope);
521 if( (pExists = pScope->lookupForAdd(pModule)) )
522 {
523 pExists->setInMainfile(idlc()->isInMainFile());
524 pExists->setFileName(pModule->getFileName());
525 if (pExists->isPredefined())
526 {
527 pExists->setPredefined(false);
528 if (pExists->getDocumentation().getLength() == 0 &&
529 pModule->getDocumentation().getLength() > 0)
530 {
531 pExists->setDocumentation(pModule->getDocumentation());
532 }
533 }
534 delete(pModule);
535 pModule = (AstModule*)pExists;
536 } else
537 {
538 pScope->addDeclaration(pModule);
539 }
540 idlc()->scopes()->push(pModule);
541 }
542 delete $3;
543 }
544 '{'
545 {
546 idlc()->setParseState(PS_ModuleSqSeen);
547 }
548 definitions
549 {
550 idlc()->setParseState(PS_ModuleBodySeen);
551 }
552 '}'
553 {
554 idlc()->setParseState(PS_ModuleQsSeen);
555 /*
556 * Finished with this module - pop it from the scope stack
557 */
558 idlc()->scopes()->pop();
559 }
560 ;
561
562 interface :
563 interface_dcl
564 | forward_dcl
565 ;
566
567 interface_decl :
568 IDL_INTERFACE
569 {
570 idlc()->setParseState(PS_InterfaceSeen);
571 }
572 identifier
573 {
574 idlc()->setParseState(PS_InterfaceIDSeen);
575 checkIdentifier($3);
576 $$ = $3;
577 }
578 ;
579
580 forward_dcl :
581 interface_decl
582 {
583 idlc()->setParseState(PS_ForwardDeclSeen);
584
585 AstScope* pScope = idlc()->scopes()->topNonNull();
586 AstInterface* pForward = NULL;
587 AstDeclaration* pDecl = NULL;
588
589 /*
590 * Make a new forward interface node and add it to its enclosing scope
591 */
592 if ( pScope && $1 )
593 {
594 pForward = new AstInterface(*$1, NULL, pScope);
595
596 if ( pDecl = pScope->lookupByName(pForward->getScopedName()) )
597 {
598 if ( (pDecl != pForward) &&
599 (pDecl->getNodeType() == NT_interface) )
600 {
601 delete pForward;
602 } else
603 {
604 idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(pScope), pDecl);
605 }
606 } else
607 {
608 /*
609 * Add the interface to its definition scope
610 */
611 pScope->addDeclaration(pForward);
612 }
613 }
614 delete $1;
615 }
616 ;
617
618 interface_dcl :
619 interfaceheader
620 {
621 idlc()->setParseState(PS_InterfaceHeadSeen);
622
623 AstScope* pScope = idlc()->scopes()->topNonNull();
624 AstInterface* pInterface = NULL;
625 AstInterface* pForward = NULL;
626 AstDeclaration* pDecl = NULL;
627
628 /*
629 * Make a new interface node and add it to its enclosing scope
630 */
631 if ( pScope && $1 )
632 {
633 pInterface = new AstInterface(
634 *$1->getName(),
635 static_cast< AstInterface * >($1->getInherits()), pScope);
636 if ( pInterface &&
637 (pDecl = pScope->lookupByName(pInterface->getScopedName())) )
638 {
639 /*
640 * See if we're defining a forward declared interface.
641 */
642 if (pDecl->getNodeType() == NT_interface)
643 {
644 pForward = (AstInterface*)pDecl;
645 if ( !pForward->isDefined() )
646 {
647 /*
648 * Check if redefining in same scope
649 */
650 if ( pForward->getScope() != pScope )
651 {
652 if ( pForward->getScopedName() != pInterface->getScopedName() )
653 {
654 idlc()->error()->error3(EIDL_SCOPE_CONFLICT,
655 pInterface, pForward, scopeAsDecl(pScope));
656 }
657 }
658 else if ( !pInterface->isPublished()
659 && pForward->isPublished() )
660 {
661 idlc()->error()->error0(EIDL_PUBLISHED_FORWARD);
662 }
663 /*
664 * All OK, set full definition
665 */
666 else
667 {
668 pForward->forwardDefined(*pInterface);
669 delete pInterface;
670 pInterface = pForward;
671 }
672 } else {
673 // special handling for XInterface because it is predefined
674 if ( pForward->isPredefined() &&
675 pForward->getScopedName() == "com::sun::star::uno::XInterface")
676 {
677 /* replace the predefined XInterface */
678 *pForward = *pInterface;
679 delete pInterface;
680 pInterface = pForward;
681 }
682
683 }
684 }
685 } else
686 {
687 /*
688 * Add the interface to its definition scope
689 */
690 pScope->addDeclaration(pInterface);
691 }
692 }
693 /*
694 * Push it on the scope stack
695 */
696 idlc()->scopes()->push(pInterface);
697 delete($1);
698 }
699 '{'
700 {
701 idlc()->setParseState(PS_InterfaceSqSeen);
702 }
703 exports
704 {
705 AstInterface * ifc = static_cast< AstInterface * >(
706 idlc()->scopes()->topNonNull());
707 if (!ifc->hasMandatoryInheritedInterfaces()
708 && ifc->getScopedName() != "com::sun::star::uno::XInterface")
709 {
710 addInheritedInterface(
711 ifc, rtl::OString("::com::sun::star::uno::XInterface"), false,
712 rtl::OUString());
713 }
714 ifc->setDefined();
715 idlc()->setParseState(PS_InterfaceBodySeen);
716 }
717 '}'
718 {
719 idlc()->setParseState(PS_InterfaceQsSeen);
720 /*
721 * Done with this interface - pop it off the scopes stack
722 */
723 idlc()->scopes()->pop();
724 }
725 | error '}'
726 {
727 yyerror("interface definition");
728 yyerrok;
729 }
730 ;
731
732 interfaceheader :
733 interface_decl inheritance_spec
734 {
735 idlc()->setParseState(PS_InheritSpecSeen);
736
737 $$ = new FeInheritanceHeader(NT_interface, $1, $2, 0);
738 delete $2;
739 }
740 ;
741
742 inheritance_spec :
743 ':'
744 {
745 idlc()->setParseState(PS_InheritColonSeen);
746 }
747 scoped_name
748 {
749 $$ = $3;
750 }
751 | /* EMPTY */
752 {
753 $$ = NULL;
754 }
755 ;
756
757 exports :
758 exports export
759 | /* EMPTY */
760 ;
761
762 export :
763 attribute
764 {
765 idlc()->setParseState(PS_AttributeDeclSeen);
766 }
767 ';'
768 {
769 idlc()->setParseState(PS_NoState);
770 }
771 | operation
772 {
773 idlc()->setParseState(PS_OperationDeclSeen);
774 }
775 ';'
776 {
777 idlc()->setParseState(PS_NoState);
778 }
779 | interface_inheritance_decl
780 {
781 idlc()->setParseState(PS_InterfaceInheritanceDeclSeen);
782 }
783 ';'
784 {
785 idlc()->setParseState(PS_NoState);
786 }
787 ;
788
789 attribute :
790 flag_header
791 simple_type_spec
792 {
793 idlc()->setParseState(PS_AttrTypeSeen);
794 }
795 simple_declarator
796 {
797 idlc()->setParseState(PS_AttrCompleted);
798 if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) {
799 idlc()->error()->flagError(EIDL_BAD_ATTRIBUTE_FLAGS, $1);
800 }
801 AstInterface * scope = static_cast< AstInterface * >(
802 idlc()->scopes()->top());
803 AstAttribute * attr = new AstAttribute(
804 $1, $4->compose($2), $4->getName(), scope);
805 delete $4;
806 AstInterface::DoubleMemberDeclarations doubleMembers(
807 scope->checkMemberClashes(attr));
808 if (doubleMembers.empty()) {
809 scope->addMember(attr);
810 } else {
811 reportDoubleMemberDeclarations(doubleMembers);
812 }
813 idlc()->scopes()->push(attr);
814 }
815 opt_attribute_block
816 {
817 static_cast< AstAttribute * >(idlc()->scopes()->top())->setExceptions(
818 $6.get.documentation, $6.get.exceptions, $6.set.documentation,
819 $6.set.exceptions);
820 delete $6.get.documentation;
821 delete $6.get.exceptions;
822 delete $6.set.documentation;
823 delete $6.set.exceptions;
824 idlc()->scopes()->pop();
825 }
826 ;
827
828 flag_header :
829 '[' opt_attrflags ']'
830 {
831 idlc()->setParseState(PS_FlagHeaderSeen);
832 $$ = $2;
833 }
834 ;
835
836 opt_attrflags :
837 opt_attrflags ',' opt_attrflag
838 {
839 if ( ($1 & $3) == $3 )
840 idlc()->error()->flagError(EIDL_DEFINED_ATTRIBUTEFLAG, $3);
841
842 $$ = $1 | $3;
843 }
844 | opt_attrflag
845 {
846 $$ = $1;
847 }
848 ;
849
850 opt_attrflag :
851 IDL_ATTRIBUTE
852 {
853 idlc()->setParseState(PS_AttrSeen);
854 $$ = AF_ATTRIBUTE;
855 }
856 | IDL_PROPERTY
857 {
858 idlc()->setParseState(PS_PropertySeen);
859 $$ = AF_PROPERTY;
860 }
861 | IDL_READONLY
862 {
863 idlc()->setParseState(PS_ReadOnlySeen);
864 $$ = AF_READONLY;
865 }
866 | IDL_OPTIONAL
867 {
868 idlc()->setParseState(PS_OptionalSeen);
869 $$ = AF_OPTIONAL;
870 }
871 | IDL_MAYBEVOID
872 {
873 idlc()->setParseState(PS_MayBeVoidSeen);
874 $$ = AF_MAYBEVOID;
875 }
876 | IDL_BOUND
877 {
878 idlc()->setParseState(PS_BoundSeen);
879 $$ = AF_BOUND;
880 }
881 | IDL_CONSTRAINED
882 {
883 idlc()->setParseState(PS_ConstrainedSeen);
884 $$ = AF_CONSTRAINED;
885 }
886 | IDL_TRANSIENT
887 {
888 idlc()->setParseState(PS_TransientSeen);
889 $$ = AF_TRANSIENT;
890 }
891 | IDL_MAYBEAMBIGUOUS
892 {
893 idlc()->setParseState(PS_MayBeAmbigiousSeen);
894 $$ = AF_MAYBEAMBIGUOUS;
895 }
896 | IDL_MAYBEDEFAULT
897 {
898 idlc()->setParseState(PS_MayBeDefaultSeen);
899 $$ = AF_MAYBEDEFAULT;
900 }
901 | IDL_REMOVEABLE
902 {
903 idlc()->setParseState(PS_RemoveableSeen);
904 $$ = AF_REMOVEABLE;
905 }
906 | error ']'
907 {
908 yyerror("unknown property|attribute flag");
909 yyerrok;
910 }
911 ;
912
913 opt_attribute_block:
914 '{' attribute_block_rest { $$ = $2; }
915 | /* empty */
916 {
917 $$.get.documentation = 0;
918 $$.get.exceptions = 0;
919 $$.set.documentation = 0;
920 $$.set.exceptions = 0;
921 }
922 ;
923
924 attribute_block_rest:
925 opt_attribute_raises '}'
926 | error '}'
927 {
928 yyerror("bad attribute raises block");
929 yyerrok;
930 $$.get.documentation = 0;
931 $$.get.exceptions = 0;
932 $$.set.documentation = 0;
933 $$.set.exceptions = 0;
934 }
935 ;
936
937 opt_attribute_raises:
938 attribute_get_raises
939 opt_attribute_set_raises
940 {
941 $$.get = $1;
942 $$.set = $2;
943 }
944 | attribute_set_raises
945 opt_attribute_get_raises
946 {
947 $$.get = $2;
948 $$.set = $1;
949 }
950 | /* empty */
951 {
952 $$.get.documentation = 0;
953 $$.get.exceptions = 0;
954 $$.set.documentation = 0;
955 $$.set.exceptions = 0;
956 }
957 ;
958
959 opt_attribute_get_raises:
960 attribute_get_raises
961 | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
962 ;
963
964 attribute_get_raises:
965 IDL_GET raises ';'
966 {
967 $$.documentation = new rtl::OUString(
968 rtl::OStringToOUString(
969 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
970 $$.exceptions = $2;
971 }
972 ;
973
974 opt_attribute_set_raises:
975 attribute_set_raises
976 | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
977 ;
978
979 attribute_set_raises:
980 IDL_SET
981 {
982 if (static_cast< AstAttribute * >(idlc()->scopes()->top())->
983 isReadonly())
984 {
985 idlc()->error()->error0(EIDL_READONLY_ATTRIBUTE_SET_EXCEPTIONS);
986 }
987 }
988 raises ';'
989 {
990 $$.documentation = new rtl::OUString(
991 rtl::OStringToOUString(
992 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
993 $$.exceptions = $3;
994 }
995 ;
996
997 operation :
998 operation_head
999 op_type_spec
1000 {
1001 idlc()->setParseState(PS_OpTypeSeen);
1002 }
1003 identifier
1004 {
1005 idlc()->setParseState(PS_OpIDSeen);
1006 checkIdentifier($4);
1007
1008 AstInterface * pScope = static_cast< AstInterface * >(
1009 idlc()->scopes()->top());
1010 AstOperation* pOp = NULL;
1011
1012 /*
1013 * Create a node representing an operation on an interface
1014 * and add it to its enclosing scope
1015 */
1016 if ( pScope && $2 )
1017 {
1018 AstType *pType = (AstType*)$2;
1019 if ( !pType || (pType->getNodeType() == NT_exception) )
1020 {
1021 // type ERROR
1022 } else
1023 {
1024 pOp = new AstOperation($1, pType, *$4, pScope);
1025
1026 AstInterface::DoubleMemberDeclarations doubleMembers(
1027 pScope->checkMemberClashes(pOp));
1028 if (doubleMembers.empty()) {
1029 pScope->addMember(pOp);
1030 } else {
1031 reportDoubleMemberDeclarations(doubleMembers);
1032 }
1033 }
1034 }
1035 delete $4;
1036 /*
1037 * Push the operation scope onto the scopes stack
1038 */
1039 idlc()->scopes()->push(pOp);
1040 }
1041 '('
1042 {
1043 idlc()->setParseState(PS_OpSqSeen);
1044 }
1045 parameters
1046 {
1047 idlc()->setParseState(PS_OpParsCompleted);
1048 }
1049 ')'
1050 {
1051 idlc()->setParseState(PS_OpQsSeen);
1052 }
1053 opt_raises
1054 {
1055 AstScope* pScope = idlc()->scopes()->topNonNull();
1056 AstOperation* pOp = NULL;
1057 /*
1058 * Add exceptions and context to the operation
1059 */
1060 if ( pScope && pScope->getScopeNodeType() == NT_operation)
1061 {
1062 pOp = (AstOperation*)pScope;
1063
1064 if ( pOp )
1065 pOp->setExceptions($12);
1066 }
1067 delete $12;
1068 /*
1069 * Done with this operation. Pop its scope from the scopes stack
1070 */
1071 idlc()->scopes()->pop();
1072 }
1073 ;
1074
1075 operation_head :
1076 '['
1077 IDL_ONEWAY
1078 {
1079 idlc()->setParseState(PS_OpOnewaySeen);
1080 }
1081 ']'
1082 {
1083 idlc()->setParseState(PS_OpHeadSeen);
1084 $$ = OP_ONEWAY;
1085 }
1086 | /* EMPTY */
1087 {
1088 $$ = OP_NONE;
1089 }
1090 ;
1091
1092 op_type_spec :
1093 simple_type_spec
1094 | IDL_VOID
1095 {
1096 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void);
1097 }
1098 ;
1099
1100 parameters :
1101 parameter
1102 | parameters
1103 ','
1104 {
1105 idlc()->setParseState(PS_OpParCommaSeen);
1106 }
1107 parameter
1108 | /* EMPTY */
1109 | error ','
1110 {
1111 yyerror("parameter definition");
1112 yyerrok;
1113 }
1114 ;
1115
1116 parameter :
1117 '['
1118 direction
1119 ']'
1120 {
1121 idlc()->setParseState(PS_OpParDirSeen);
1122 }
1123 simple_type_spec
1124 {
1125 idlc()->setParseState(PS_OpParTypeSeen);
1126 }
1127 opt_rest
1128 declarator
1129 {
1130 idlc()->setParseState(PS_OpParDeclSeen);
1131
1132 AstOperation * pScope = static_cast< AstOperation * >(
1133 idlc()->scopes()->top());
1134 AstParameter* pParam = NULL;
1135
1136 /*
1137 * Create a node representing an argument to an operation
1138 * Add it to the enclosing scope (the operation scope)
1139 */
1140 if ( pScope && $5 && $8 )
1141 {
1142 AstType const * pType = $8->compose($5);
1143 if ( pType )
1144 {
1145 if (pScope->isConstructor() && $2 != DIR_IN) {
1146 idlc()->error()->error0(EIDL_CONSTRUCTOR_PARAMETER_NOT_IN);
1147 }
1148 if (pScope->isVariadic()) {
1149 idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_LAST);
1150 }
1151 if ($7) {
1152 AstDeclaration const * type = resolveTypedefs(pType);
1153 if (type->getNodeType() != NT_predefined
1154 || (static_cast< AstBaseType const * >(type)->
1155 getExprType() != ET_any))
1156 {
1157 idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_ANY);
1158 }
1159 if (pScope->isConstructor()) {
1160 if (pScope->getIteratorBegin()
1161 != pScope->getIteratorEnd())
1162 {
1163 idlc()->error()->error0(
1164 EIDL_CONSTRUCTOR_REST_PARAMETER_NOT_FIRST);
1165 }
1166 } else {
1167 idlc()->error()->error0(EIDL_METHOD_HAS_REST_PARAMETER);
1168 }
1169 }
1170
1171 pParam = new AstParameter(
1172 static_cast< Direction >($2), $7, pType, $8->getName(),
1173 pScope);
1174
1175 if ( !$8->checkType($5) )
1176 {
1177 // WARNING
1178 }
1179
1180 pScope->addDeclaration(pParam);
1181 }
1182 }
1183 }
1184 | error
1185 simple_type_spec
1186 {
1187 idlc()->setParseState(PS_NoState);
1188 yyerrok;
1189 }
1190 ;
1191
1192 direction :
1193 IDL_IN
1194 {
1195 $$ = DIR_IN;
1196 }
1197 | IDL_OUT
1198 {
1199 $$ = DIR_OUT;
1200 }
1201 | IDL_INOUT
1202 {
1203 $$ = DIR_INOUT;
1204 }
1205 ;
1206
1207 opt_rest:
1208 IDL_ELLIPSIS
1209 {
1210 $$ = true;
1211 }
1212 | /* empty */
1213 {
1214 $$ = false;
1215 }
1216 ;
1217
1218 opt_raises:
1219 raises
1220 | /* empty */
1221 {
1222 $$ = 0;
1223 }
1224 ;
1225
1226 raises:
1227 IDL_RAISES
1228 {
1229 idlc()->setParseState(PS_RaiseSeen);
1230 }
1231 '('
1232 {
1233 idlc()->setParseState(PS_RaiseSqSeen);
1234 }
1235 exception_list
1236 ')'
1237 {
1238 idlc()->setParseState(PS_RaiseQsSeen);
1239 $$ = $5;
1240 }
1241 ;
1242
1243 exception_list:
1244 exception_name
1245 {
1246 $$ = new DeclList;
1247 $$->push_back($1);
1248 }
1249 | exception_list ',' exception_name
1250 {
1251 $1->push_back($3);
1252 $$ = $1;
1253 }
1254 ;
1255
1256 exception_name:
1257 scoped_name
1258 {
1259 // The topmost scope is either an AstOperation (for interface methods
1260 // and service constructors) or an AstAttribute (for interface
1261 // attributes), so look up exception names in the next-to-topmost scope:
1262 AstDeclaration * decl = idlc()->scopes()->nextToTop()->lookupByName(
1263 *$1);
1264 if (decl == 0) {
1265 idlc()->error()->lookupError(*$1);
1266 } else if (!idlc()->error()->checkPublished(decl)) {
1267 decl = 0;
1268 } else if (decl->getNodeType() != NT_exception) {
1269 idlc()->error()->error1(EIDL_ILLEGAL_RAISES, decl);
1270 decl = 0;
1271 }
1272 delete $1;
1273 $$ = decl;
1274 }
1275 ;
1276
1277 interface_inheritance_decl:
1278 optional_inherited_interface
1279 IDL_INTERFACE
1280 {
1281 idlc()->setParseState(PS_ServiceIFHeadSeen);
1282 }
1283 scoped_name
1284 {
1285 AstInterface * ifc = static_cast< AstInterface * >(
1286 idlc()->scopes()->top());
1287 if (ifc->usesSingleInheritance()) {
1288 idlc()->error()->error0(EIDL_MIXED_INHERITANCE);
1289 } else {
1290 addInheritedInterface(
1291 ifc, *$4, $1,
1292 rtl::OStringToOUString(
1293 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
1294 }
1295 delete $4;
1296 }
1297 ;
1298
1299 optional_inherited_interface:
1300 '[' IDL_OPTIONAL ']' { $$ = true; }
1301 | /* EMPTY */ { $$ = false; }
1302 ;
1303
1304 constants_exports :
1305 constants_export constants_exports
1306 | /* EMPTY */
1307 ;
1308
1309 constants_export :
1310 const_dcl
1311 {
1312 idlc()->setParseState(PS_ConstantDeclSeen);
1313 }
1314 ';' {};
1315
1316 const_dcl :
1317 IDL_CONST
1318 {
1319 idlc()->setParseState(PS_ConstSeen);
1320 }
1321 const_type
1322 {
1323 idlc()->setParseState(PS_ConstTypeSeen);
1324 }
1325 identifier
1326 {
1327 idlc()->setParseState(PS_ConstIDSeen);
1328 checkIdentifier($5);
1329 }
1330 '='
1331 {
1332 idlc()->setParseState(PS_ConstAssignSeen);
1333 }
1334 expression
1335 {
1336 idlc()->setParseState(PS_ConstExprSeen);
1337
1338 AstScope* pScope = idlc()->scopes()->topNonNull();
1339 AstConstant* pConstant = NULL;
1340
1341 if ( $9 && pScope )
1342 {
1343 if ( !$9->coerce($3) )
1344 {
1345 idlc()->error()->coercionError($9, $3);
1346 } else
1347 {
1348 pConstant = new AstConstant($3, $9, *$5, pScope);
1349 pScope->addDeclaration(pConstant);
1350 }
1351 }
1352 delete $5;
1353 }
1354 ;
1355
1356 constants_dcl :
1357 IDL_CONSTANTS
1358 {
1359 idlc()->setParseState(PS_ConstantsSeen);
1360 }
1361 identifier
1362 {
1363 idlc()->setParseState(PS_ConstantsIDSeen);
1364 checkIdentifier($3);
1365 }
1366 '{'
1367 {
1368 idlc()->setParseState(PS_ConstantsSqSeen);
1369
1370 AstScope* pScope = idlc()->scopes()->topNonNull();
1371 AstConstants* pConstants = NULL;
1372 AstDeclaration* pExists = NULL;
1373
1374 if ( pScope )
1375 {
1376 pConstants = new AstConstants(*$3, pScope);
1377 if( (pExists = pScope->lookupForAdd(pConstants)) )
1378 {
1379 pExists->setInMainfile(idlc()->isInMainFile());
1380 delete(pConstants);
1381 pConstants = (AstConstants*)pExists;
1382 } else
1383 {
1384 pScope->addDeclaration(pConstants);
1385 }
1386 idlc()->scopes()->push(pConstants);
1387 }
1388 delete $3;
1389 }
1390 constants_exports
1391 {
1392 idlc()->setParseState(PS_ConstantsBodySeen);
1393 }
1394 '}'
1395 {
1396 idlc()->setParseState(PS_ConstantsQsSeen);
1397 /*
1398 * Finished with this constants - pop it from the scope stack
1399 */
1400 idlc()->scopes()->pop();
1401 }
1402 ;
1403
1404 expression : const_expr ;
1405
1406 const_expr : or_expr ;
1407
1408 or_expr :
1409 xor_expr
1410 | or_expr '|' xor_expr
1411 {
1412 $$ = new AstExpression(EC_or, $1, $3);
1413 }
1414 ;
1415
1416 xor_expr :
1417 and_expr
1418 | xor_expr '^' and_expr
1419 {
1420 $$ = new AstExpression(EC_xor, $1, $3);
1421 }
1422 ;
1423
1424 and_expr :
1425 shift_expr
1426 | and_expr '&' shift_expr
1427 {
1428 $$ = new AstExpression(EC_and, $1, $3);
1429 }
1430 ;
1431
1432 shift_expr :
1433 add_expr
1434 | shift_expr IDL_LEFTSHIFT add_expr
1435 {
1436 $$ = new AstExpression(EC_left, $1, $3);
1437 }
1438 | shift_expr IDL_RIGHTSHIFT add_expr
1439 {
1440 $$ = new AstExpression(EC_right, $1, $3);
1441 }
1442 ;
1443
1444 add_expr :
1445 mult_expr
1446 | add_expr '+' mult_expr
1447 {
1448 $$ = new AstExpression(EC_add, $1, $3);
1449 }
1450 | add_expr '-' mult_expr
1451 {
1452 $$ = new AstExpression(EC_minus, $1, $3);
1453 }
1454 ;
1455
1456 mult_expr :
1457 unary_expr
1458 | mult_expr '*' unary_expr
1459 {
1460 $$ = new AstExpression(EC_mul, $1, $3);
1461 }
1462 | mult_expr '/' unary_expr
1463 {
1464 $$ = new AstExpression(EC_div, $1, $3);
1465 }
1466 | mult_expr '%' unary_expr
1467 {
1468 $$ = new AstExpression(EC_mod, $1, $3);
1469 }
1470 ;
1471
1472 unary_expr :
1473 primary_expr
1474 | '+' primary_expr
1475 {
1476 $$ = new AstExpression(EC_u_plus, $2, NULL);
1477 }
1478 | '-' primary_expr
1479 {
1480 $$ = new AstExpression(EC_u_minus, $2, NULL);
1481 }
1482 | '~' primary_expr
1483 {
1484 }
1485 ;
1486
1487 primary_expr :
1488 scoped_name
1489 {
1490 /*
1491 * An expression which is a scoped name is not resolved now,
1492 * but only when it is evaluated (such as when it is assigned
1493 * as a constant value)
1494 */
1495 $$ = new AstExpression($1);
1496 }
1497 | literal
1498 | '(' const_expr ')'
1499 {
1500 $$ = $2;
1501 }
1502 ;
1503
1504 literal :
1505 IDL_INTEGER_LITERAL
1506 {
1507 $$ = new AstExpression($1);
1508 }
1509 | IDL_INTEGER_ULITERAL
1510 {
1511 $$ = new AstExpression($1);
1512 }
1513 | IDL_FLOATING_PT_LITERAL
1514 {
1515 $$ = new AstExpression($1);
1516 }
1517 | IDL_TRUE
1518 {
1519 $$ = new AstExpression((sal_Int32)1, ET_boolean);
1520 }
1521 | IDL_FALSE
1522 {
1523 $$ = new AstExpression((sal_Int32)0, ET_boolean);
1524 }
1525 ;
1526
1527 positive_int_expr :
1528 const_expr
1529 {
1530 $1->evaluate(EK_const);
1531 if ( !$1->coerce(ET_ulong) )
1532 {
1533 idlc()->error()->coercionError($1, ET_ulong);
1534 delete $1;
1535 $$ = NULL;
1536 }
1537 }
1538 ;
1539
1540 const_type :
1541 integer_type
1542 | char_type
1543 | byte_type
1544 | boolean_type
1545 | floating_pt_type
1546 | scoped_name
1547 {
1548 AstScope* pScope = idlc()->scopes()->topNonNull();
1549 AstDeclaration const * type = 0;
1550
1551 /*
1552 * If the constant's type is a scoped name, it must resolve
1553 * to a scalar constant type
1554 */
1555 if ( pScope && (type = pScope->lookupByName(*$1)) ) {
1556 if (!idlc()->error()->checkPublished(type))
1557 {
1558 type = 0;
1559 }
1560 else
1561 {
1562 type = resolveTypedefs(type);
1563 if (type->getNodeType() == NT_predefined)
1564 {
1565 $$ = static_cast< AstBaseType const * >(type)->
1566 getExprType();
1567 } else
1568 $$ = ET_any;
1569 }
1570 } else
1571 $$ = ET_any;
1572 }
1573 ;
1574
1575 exception_header :
1576 IDL_EXCEPTION
1577 {
1578 idlc()->setParseState(PS_ExceptSeen);
1579 }
1580 identifier
1581 {
1582 idlc()->setParseState(PS_ExceptIDSeen);
1583 checkIdentifier($3);
1584 }
1585 inheritance_spec
1586 {
1587 idlc()->setParseState(PS_InheritSpecSeen);
1588
1589 $$ = new FeInheritanceHeader(NT_exception, $3, $5, 0);
1590 delete $5;
1591 }
1592 ;
1593
1594 exception_dcl :
1595 exception_header
1596 {
1597 idlc()->setParseState(PS_ExceptHeaderSeen);
1598
1599 AstScope* pScope = idlc()->scopes()->topNonNull();
1600 AstException* pExcept = NULL;
1601
1602 if ( pScope )
1603 {
1604 AstException* pBase = static_cast< AstException* >(
1605 $1->getInherits());
1606 pExcept = new AstException(*$1->getName(), pBase, pScope);
1607 pScope->addDeclaration(pExcept);
1608 }
1609 /*
1610 * Push the scope of the exception on the scopes stack
1611 */
1612 idlc()->scopes()->push(pExcept);
1613 delete $1;
1614 }
1615 '{'
1616 {
1617 idlc()->setParseState(PS_ExceptSqSeen);
1618 }
1619 members
1620 {
1621 idlc()->setParseState(PS_ExceptBodySeen);
1622 }
1623 '}'
1624 {
1625 idlc()->setParseState(PS_ExceptQsSeen);
1626 /* this exception is finished, pop its scope from the stack */
1627 idlc()->scopes()->pop();
1628 }
1629 ;
1630
1631 property :
1632 flag_header
1633 simple_type_spec
1634 {
1635 idlc()->setParseState(PS_PropertyTypeSeen);
1636 }
1637 at_least_one_declarator
1638 {
1639 idlc()->setParseState(PS_PropertyCompleted);
1640
1641 AstScope* pScope = idlc()->scopes()->topNonNull();
1642 AstAttribute* pAttr = NULL;
1643 FeDeclList* pList = $4;
1644 FeDeclarator* pDecl = NULL;
1645 AstType const * pType = NULL;
1646
1647 if ( pScope->getScopeNodeType() == NT_singleton )
1648 {
1649 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1650 } else
1651 {
1652 if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
1653 idlc()->error()->flagError(EIDL_WRONGATTRIBUTEKEYWORD, AF_ATTRIBUTE);
1654
1655 if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
1656 idlc()->error()->flagError(EIDL_MISSINGATTRIBUTEKEYWORD, AF_PROPERTY);
1657
1658 /*
1659 * Create nodes representing attributes and add them to the
1660 * enclosing scope
1661 */
1662 if ( pScope && $2 && pList )
1663 {
1664 FeDeclList::iterator iter = pList->begin();
1665 FeDeclList::iterator end = pList->end();
1666
1667 while (iter != end)
1668 {
1669 pDecl = (*iter);
1670 if ( !pDecl )
1671 {
1672 iter++;
1673 continue;
1674 }
1675
1676 pType = pDecl->compose($2);
1677
1678 if ( !pType )
1679 {
1680 iter++;
1681 continue;
1682 }
1683
1684 pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);
1685
1686 pScope->addDeclaration(pAttr);
1687 iter++;
1688 delete pDecl;
1689 }
1690 }
1691 }
1692
1693 if ( pList )
1694 delete pList;
1695 }
1696 | error ';'
1697 {
1698 yyerror("property");
1699 yyerrok;
1700 }
1701 ;
1702
1703 service_exports :
1704 service_exports service_export
1705 | /* EMPTY */
1706 ;
1707
1708 service_export :
1709 service_interface_header
1710 at_least_one_scoped_name
1711 ';'
1712 {
1713 idlc()->setParseState(PS_ServiceMemberSeen);
1714
1715 AstScope* pScope = idlc()->scopes()->topNonNull();
1716 AstDeclaration* pDecl = NULL;
1717 AstInterfaceMember* pIMember = NULL;
1718
1719 if ( pScope->getScopeNodeType() == NT_singleton )
1720 {
1721 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1722 } else
1723 {
1724 /*
1725 * Create a node representing a class member.
1726 * Store it in the enclosing scope
1727 */
1728 if ( pScope && $2 )
1729 {
1730 StringList::iterator iter = $2->begin();
1731 StringList::iterator end = $2->end();
1732
1733 while ( iter != end )
1734 {
1735 pDecl = pScope->lookupByName(*iter);
1736 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1737 {
1738 /* we relax the strict published check and allow to add new
1739 * interfaces if they are optional
1740 */
1741 bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
1742 if ( idlc()->error()->checkPublished(pDecl, bOptional) )
1743 {
1744 pIMember = new AstInterfaceMember(
1745 $1, (AstInterface*)pDecl, *iter, pScope);
1746 pScope->addDeclaration(pIMember);
1747 }
1748 } else
1749 {
1750 idlc()->error()->
1751 lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1752 }
1753 iter++;
1754 }
1755 }
1756 }
1757 delete $2;
1758 }
1759 | service_service_header
1760 at_least_one_scoped_name
1761 ';'
1762 {
1763 idlc()->setParseState(PS_ServiceMemberSeen);
1764
1765 AstScope* pScope = idlc()->scopes()->topNonNull();
1766 AstDeclaration* pDecl = NULL;
1767 AstServiceMember* pSMember = NULL;
1768
1769 /*
1770 * Create a node representing a class member.
1771 * Store it in the enclosing scope
1772 */
1773 if ( pScope && $2 )
1774 {
1775 StringList::iterator iter = $2->begin();
1776 StringList::iterator end = $2->end();
1777
1778 while ( iter != end )
1779 {
1780 pDecl = pScope->lookupByName(*iter);
1781 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1782 {
1783 if ( pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0 )
1784 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1785 else if ( idlc()->error()->checkPublished(pDecl) )
1786 {
1787 pSMember = new AstServiceMember(
1788 $1, (AstService*)pDecl, *iter, pScope);
1789 pScope->addDeclaration(pSMember);
1790 }
1791 } else
1792 {
1793 idlc()->error()->
1794 lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1795 }
1796 iter++;
1797 }
1798 }
1799 delete $2;
1800 }
1801 | IDL_OBSERVES
1802 at_least_one_scoped_name
1803 ';'
1804 {
1805 idlc()->setParseState(PS_ServiceMemberSeen);
1806
1807 AstScope* pScope = idlc()->scopes()->topNonNull();
1808 AstDeclaration* pDecl = NULL;
1809 AstObserves* pObserves = NULL;
1810
1811 if ( pScope->getScopeNodeType() == NT_singleton )
1812 {
1813 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1814 } else
1815 {
1816 /*
1817 * Create a node representing a class member.
1818 * Store it in the enclosing scope
1819 */
1820 if ( pScope && $2 )
1821 {
1822 StringList::iterator iter = $2->begin();
1823 StringList::iterator end = $2->end();
1824
1825 while ( iter != end )
1826 {
1827 pDecl = pScope->lookupByName(*iter);
1828 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1829 {
1830 pObserves = new AstObserves((AstInterface*)pDecl, *iter, pScope);
1831 pScope->addDeclaration(pObserves);
1832 } else
1833 {
1834 idlc()->error()->
1835 lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1836 }
1837 iter++;
1838 }
1839 }
1840 }
1841 delete $2;
1842 }
1843 | IDL_NEEDS
1844 at_least_one_scoped_name
1845 ';'
1846 {
1847 idlc()->setParseState(PS_ServiceMemberSeen);
1848
1849 AstScope* pScope = idlc()->scopes()->topNonNull();
1850 AstDeclaration* pDecl = NULL;
1851 AstNeeds* pNeeds = NULL;
1852
1853 if ( pScope->getScopeNodeType() == NT_singleton )
1854 {
1855 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1856 } else
1857 {
1858 /*
1859 * Create a node representing a class member.
1860 * Store it in the enclosing scope
1861 */
1862 if ( pScope && $2 )
1863 {
1864 StringList::iterator iter = $2->begin();
1865 StringList::iterator end = $2->end();
1866
1867 while ( iter != end )
1868 {
1869 pDecl = pScope->lookupByName(*iter);
1870 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1871 {
1872 pNeeds = new AstNeeds((AstService*)pDecl, *iter, pScope);
1873 pScope->addDeclaration(pNeeds);
1874 } else
1875 {
1876 idlc()->error()->
1877 lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1878 }
1879 iter++;
1880 }
1881 }
1882 }
1883 delete $2;
1884 }
1885 | property
1886 ';'
1887 {
1888 idlc()->setParseState(PS_PropertyDeclSeen);
1889 }
1890 ;
1891
1892 service_interface_header :
1893 IDL_INTERFACE
1894 {
1895 idlc()->setParseState(PS_ServiceIFHeadSeen);
1896 $$ = AF_INVALID;
1897 }
1898 | flag_header
1899 IDL_INTERFACE
1900 {
1901 idlc()->setParseState(PS_ServiceIFHeadSeen);
1902 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1903 idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1904 $$ = $1;
1905 }
1906 ;
1907
1908 service_service_header :
1909 IDL_SERVICE
1910 {
1911 idlc()->setParseState(PS_ServiceSHeadSeen);
1912 $$ = AF_INVALID;
1913 }
1914 | flag_header
1915 IDL_SERVICE
1916 {
1917 idlc()->setParseState(PS_ServiceSHeadSeen);
1918 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1919 idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1920 $$ = $1;
1921 }
1922 ;
1923
1924 service_dcl :
1925 IDL_SERVICE
1926 {
1927 idlc()->setParseState(PS_ServiceSeen);
1928 }
1929 identifier
1930 {
1931 idlc()->setParseState(PS_ServiceIDSeen);
1932 checkIdentifier($3);
1933
1934 AstScope* pScope = idlc()->scopes()->topNonNull();
1935 AstService* pService = NULL;
1936
1937 /*
1938 * Make a new service and add it to the enclosing scope
1939 */
1940 if (pScope != NULL)
1941 {
1942 pService = new AstService(*$3, pScope);
1943 pScope->addDeclaration(pService);
1944 }
1945 delete $3;
1946 /*
1947 * Push it on the stack
1948 */
1949 idlc()->scopes()->push(pService);
1950 }
1951 service_dfn
1952 {
1953 /* this service is finished, pop its scope from the stack */
1954 idlc()->scopes()->pop();
1955 }
1956 ;
1957
1958 service_dfn:
1959 service_interface_dfn
1960 | service_obsolete_dfn
1961 ;
1962
1963 service_interface_dfn:
1964 ':' scoped_name
1965 {
1966 AstScope * scope = idlc()->scopes()->nextToTop();
1967 // skip the scope pushed by service_dcl
1968 AstDeclaration * decl = scope->lookupByName(*$2);
1969 if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
1970 if (idlc()->error()->checkPublished(decl)) {
1971 idlc()->scopes()->top()->addDeclaration(decl);
1972 }
1973 } else {
1974 idlc()->error()->lookupError(
1975 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
1976 }
1977 delete $2;
1978 }
1979 opt_service_body
1980 {
1981 AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
1982 if (s != 0) {
1983 s->setDefaultConstructor(!$4);
1984 }
1985 }
1986 ;
1987
1988 opt_service_body:
1989 service_body { $$ = true; }
1990 | /* empty */ { $$ = false; }
1991 ;
1992
1993 service_body:
1994 '{'
1995 constructors
1996 '}'
1997 ;
1998
1999 constructors:
2000 constructors constructor
2001 | /* empty */
2002 ;
2003
2004 constructor:
2005 identifier
2006 {
2007 checkIdentifier($1);
2008 AstScope * scope = idlc()->scopes()->top();
2009 AstOperation * ctor = new AstOperation(OP_NONE, 0, *$1, scope);
2010 delete $1;
2011 scope->addDeclaration(ctor);
2012 idlc()->scopes()->push(ctor);
2013 }
2014 '('
2015 parameters
2016 ')'
2017 opt_raises
2018 {
2019 static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions(
2020 $6);
2021 delete $6;
2022 idlc()->scopes()->pop();
2023 if (static_cast< AstService * >(idlc()->scopes()->top())->
2024 checkLastConstructor())
2025 {
2026 idlc()->error()->error0(EIDL_SIMILAR_CONSTRUCTORS);
2027 }
2028 }
2029 ';'
2030 ;
2031
2032 singleton_dcl :
2033 IDL_SINGLETON
2034 {
2035 idlc()->setParseState(PS_SingletonSeen);
2036 }
2037 identifier
2038 {
2039 idlc()->setParseState(PS_SingletonIDSeen);
2040 checkIdentifier($3);
2041
2042 AstScope* pScope = idlc()->scopes()->topNonNull();
2043 AstService* pService = NULL;
2044
2045 /*
2046 * Make a new service and add it to the enclosing scope
2047 */
2048 if (pScope != NULL)
2049 {
2050 pService = new AstService(NT_singleton, *$3, pScope);
2051 pScope->addDeclaration(pService);
2052 }
2053 delete $3;
2054 /*
2055 * Push it on the stack
2056 */
2057 idlc()->scopes()->push(pService);
2058 }
2059 singleton_dfn
2060 {
2061 /* this singleton is finished, pop its scope from the stack */
2062 idlc()->scopes()->pop();
2063 }
2064 ;
2065
2066 singleton_dfn:
2067 singleton_interface_dfn
2068 | service_obsolete_dfn
2069 ;
2070
2071 singleton_interface_dfn:
2072 ':' scoped_name
2073 {
2074 AstScope * scope = idlc()->scopes()->nextToTop();
2075 // skip the scope (needlessly) pushed by singleton_dcl
2076 AstDeclaration * decl = scope->lookupByName(*$2);
2077 if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
2078 if (idlc()->error()->checkPublished(decl)) {
2079 idlc()->scopes()->top()->addDeclaration(decl);
2080 }
2081 } else {
2082 idlc()->error()->lookupError(
2083 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
2084 }
2085 delete $2;
2086 }
2087 ;
2088
2089 service_obsolete_dfn:
2090 '{'
2091 {
2092 idlc()->setParseState(
2093 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2094 ? PS_ServiceSqSeen : PS_SingletonSqSeen);
2095 }
2096 service_exports
2097 {
2098 idlc()->setParseState(
2099 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2100 ? PS_ServiceBodySeen : PS_SingletonBodySeen);
2101 }
2102 '}'
2103 {
2104 idlc()->setParseState(
2105 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2106 ? PS_ServiceQsSeen : PS_SingletonQsSeen);
2107 }
2108 ;
2109
2110 type_dcl :
2111 IDL_TYPEDEF
2112 {
2113 idlc()->setParseState(PS_TypedefSeen);
2114 }
2115 type_declarator {}
2116 | struct_type {}
2117 | union_type {}
2118 | enum_type {}
2119 ;
2120
2121 type_declarator :
2122 type_spec
2123 {
2124 idlc()->setParseState(PS_TypeSpecSeen);
2125 if ($1 != 0 && $1->getNodeType() == NT_instantiated_struct) {
2126 idlc()->error()->error0(EIDL_INSTANTIATED_STRUCT_TYPE_TYPEDEF);
2127 }
2128 }
2129 at_least_one_declarator
2130 {
2131 idlc()->setParseState(PS_DeclaratorsSeen);
2132
2133 AstScope* pScope = idlc()->scopes()->topNonNull();
2134 AstTypeDef* pTypeDef = NULL;
2135 FeDeclList* pList = $3;
2136 FeDeclarator* pDecl = NULL;
2137 AstType const * pType = NULL;
2138
2139 /*
2140 * Create nodes representing typedefs and add them to the
2141 * enclosing scope
2142 */
2143 if ( pScope && $1 && pList )
2144 {
2145 FeDeclList::iterator iter = pList->begin();
2146 FeDeclList::iterator end = pList->end();
2147
2148 while (iter != end)
2149 {
2150 pDecl = (*iter);
2151 if ( !pDecl )
2152 {
2153 iter++;
2154 continue;
2155 }
2156
2157 pType = pDecl->compose($1);
2158
2159 if ( !pType )
2160 {
2161 iter++;
2162 continue;
2163 }
2164
2165 pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);
2166
2167 pScope->addDeclaration(pTypeDef);
2168 iter++;
2169 delete pDecl;
2170 }
2171 delete pList;
2172 }
2173 }
2174 ;
2175
2176 at_least_one_declarator :
2177 declarator declarators
2178 {
2179 if ( $2 )
2180 {
2181 $2->push_back($1);
2182 $$ = $2;
2183 } else
2184 {
2185 FeDeclList* pList = new FeDeclList();
2186 pList->push_back($1);
2187 $$ = pList;
2188 }
2189 }
2190 ;
2191
2192 declarators :
2193 declarators
2194 ','
2195 {
2196 idlc()->setParseState(PS_DeclsCommaSeen);
2197 }
2198 declarator
2199 {
2200 idlc()->setParseState(PS_DeclsDeclSeen);
2201 if ( $1 )
2202 {
2203 $1->push_back($4);
2204 $$ = $1;
2205 } else
2206 {
2207 FeDeclList* pList = new FeDeclList();
2208 pList->push_back($4);
2209 $$ = pList;
2210 }
2211 }
2212 | /* EMPTY */
2213 {
2214 $$ = NULL;
2215 }
2216 ;
2217
2218 declarator :
2219 simple_declarator
2220 | complex_declarator
2221 ;
2222
2223 simple_declarator :
2224 identifier
2225 {
2226 // For historic reasons, the struct com.sun.star.uno.Uik contains
2227 // members with illegal names (of the form "m_DataN"); avoid useless
2228 // warnings about them:
2229 AstScope * scope = idlc()->scopes()->top();
2230 if (scope == 0 || scope->getScopeNodeType() != NT_struct
2231 || (scopeAsDecl(scope)->getScopedName()
2232 != "com::sun::star::uno::Uik"))
2233 {
2234 checkIdentifier($1);
2235 }
2236
2237 $$ = new FeDeclarator(*$1, FeDeclarator::FD_simple, NULL);
2238 delete $1;
2239 }
2240 ;
2241
2242 complex_declarator :
2243 array_declarator
2244 {
2245 $$ = new FeDeclarator($1->getLocalName(), FeDeclarator::FD_complex, $1);
2246 }
2247 ;
2248
2249 array_declarator :
2250 identifier
2251 {
2252 idlc()->setParseState(PS_ArrayIDSeen);
2253 checkIdentifier($1);
2254 }
2255 at_least_one_array_dim
2256 {
2257 idlc()->setParseState(PS_ArrayCompleted);
2258 $$ = new AstArray(*$1, NULL, *$3, idlc()->scopes()->bottom());
2259 delete $1;
2260 }
2261 ;
2262
2263 at_least_one_array_dim :
2264 array_dim array_dims
2265 {
2266 if( $2 )
2267 {
2268 $2->push_front($1);
2269 $$ = $2;
2270 } else
2271 {
2272 ExprList* pList = new ExprList();
2273 pList->push_back($1);
2274 $$ = pList;
2275 }
2276 }
2277 ;
2278
2279 array_dims :
2280 array_dims array_dim
2281 {
2282 if( $1 )
2283 {
2284 $1->push_back($2);
2285 $$ = $1;
2286 } else
2287 {
2288 ExprList* pList = new ExprList();
2289 pList->push_back($2);
2290 $$ = pList;
2291 }
2292 }
2293 | /* EMPTY */
2294 {
2295 $$ = NULL;
2296 }
2297 ;
2298
2299 array_dim :
2300 '['
2301 {
2302 idlc()->setParseState(PS_DimSqSeen);
2303 }
2304 positive_int_expr
2305 {
2306 idlc()->setParseState(PS_DimExprSeen);
2307 }
2308 ']'
2309 {
2310 idlc()->setParseState(PS_DimQsSeen);
2311 /*
2312 * Array dimensions are expressions which must be coerced to
2313 * positive integers
2314 */
2315 if ( !$3 || !$3->coerce(ET_uhyper) )
2316 {
2317 idlc()->error()->coercionError($3, ET_uhyper);
2318 $$ = NULL;
2319 } else
2320 $$ = $3;
2321 }
2322 ;
2323
2324 at_least_one_scoped_name :
2325 scoped_name scoped_names
2326 {
2327 if ($2)
2328 {
2329 $2->push_front(*$1);
2330 $$ = $2;
2331 } else
2332 {
2333 StringList* pNames = new StringList();
2334 pNames->push_back(*$1);
2335 $$ = pNames;
2336 }
2337 delete($1);
2338 }
2339 ;
2340
2341 scoped_names :
2342 scoped_names
2343 ','
2344 {
2345 idlc()->setParseState(PS_SNListCommaSeen);
2346 }
2347 scoped_name
2348 {
2349 idlc()->setParseState(PS_ScopedNameSeen);
2350 if ($1)
2351 {
2352 $1->push_back(*$4);
2353 $$ = $1;
2354 } else
2355 {
2356 StringList* pNames = new StringList();
2357 pNames->push_back(*$4);
2358 $$ = pNames;
2359 }
2360 delete($4);
2361 }
2362 | /* EMPTY */
2363 {
2364 $$ = NULL;
2365 }
2366 ;
2367
2368 scoped_name :
2369 identifier
2370 {
2371 idlc()->setParseState(PS_SN_IDSeen);
2372 checkIdentifier($1);
2373 $$ = $1;
2374 }
2375 | IDL_SCOPESEPARATOR
2376 {
2377 idlc()->setParseState(PS_ScopeDelimSeen);
2378 }
2379 identifier
2380 {
2381 checkIdentifier($3);
2382 OString* pName = new OString("::");
2383 *pName += *$3;
2384 delete $3;
2385 $$ = pName;
2386 }
2387 | scoped_name
2388 IDL_SCOPESEPARATOR
2389 {
2390 }
2391 identifier
2392 {
2393 checkIdentifier($4);
2394 *$1 += ::rtl::OString("::");
2395 *$1 += *$4;
2396 delete $4;
2397 $$ = $1;
2398 }
2399 ;
2400
2401 type_spec :
2402 simple_type_spec
2403 | constructed_type_spec
2404 ;
2405
2406 simple_type_spec :
2407 fundamental_type
2408 | scoped_name opt_type_args
2409 {
2410 $$ = createNamedType($1, $2);
2411 }
2412 ;
2413
2414 fundamental_type:
2415 base_type_spec
2416 {
2417 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2418 }
2419 | template_type_spec
2420 ;
2421
2422 opt_type_args:
2423 '<' type_args '>' { $$ = $2; }
2424 | /* empty */ { $$ = 0; }
2425 ;
2426
2427 type_args:
2428 type_arg
2429 {
2430 $$ = new DeclList;
2431 $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
2432 }
2433 | type_args ',' type_arg
2434 {
2435 $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
2436 $$ = $1;
2437 }
2438 ;
2439
2440 type_arg:
2441 simple_type_spec
2442 {
2443 if ($1 != 0 && static_cast< AstType const * >($1)->isUnsigned()) {
2444 idlc()->error()->error0(EIDL_UNSIGNED_TYPE_ARGUMENT);
2445 }
2446 $$ = $1;
2447 }
2448 ;
2449
2450 base_type_spec :
2451 integer_type
2452 | floating_pt_type
2453 | char_type
2454 | boolean_type
2455 | byte_type
2456 | any_type
2457 | type_type
2458 | string_type
2459 ;
2460
2461 integer_type :
2462 signed_int
2463 | unsigned_int
2464 ;
2465
2466 signed_int :
2467 IDL_LONG
2468 {
2469 $$ = ET_long;
2470 }
2471 | IDL_HYPER
2472 {
2473 $$ = ET_hyper;
2474 }
2475 | IDL_SHORT
2476 {
2477 $$ = ET_short;
2478 }
2479 ;
2480
2481 unsigned_int :
2482 IDL_UNSIGNED IDL_LONG
2483 {
2484 $$ = ET_ulong;
2485 }
2486 | IDL_UNSIGNED IDL_HYPER
2487 {
2488 $$ = ET_uhyper;
2489 }
2490 | IDL_UNSIGNED IDL_SHORT
2491 {
2492 $$ = ET_ushort;
2493 }
2494 ;
2495
2496 floating_pt_type :
2497 IDL_DOUBLE
2498 {
2499 $$ = ET_double;
2500 }
2501 | IDL_FLOAT
2502 {
2503 $$ = ET_float;
2504 }
2505 ;
2506
2507 char_type :
2508 IDL_CHAR
2509 {
2510 $$ = ET_char;
2511 }
2512 ;
2513
2514 byte_type :
2515 IDL_BYTE
2516 {
2517 $$ = ET_byte;
2518 }
2519 ;
2520
2521 boolean_type :
2522 IDL_BOOLEAN
2523 {
2524 $$ = ET_boolean;
2525 }
2526 ;
2527
2528 any_type :
2529 IDL_ANY
2530 {
2531 $$ = ET_any;
2532 }
2533 ;
2534
2535 type_type :
2536 IDL_TYPE
2537 {
2538 $$ = ET_type;
2539 }
2540 ;
2541
2542 string_type :
2543 IDL_STRING
2544 {
2545 $$ = ET_string;
2546 }
2547 ;
2548
2549 template_type_spec :
2550 sequence_type_spec
2551 | array_type
2552 ;
2553
2554 constructed_type_spec :
2555 struct_type
2556 | union_type
2557 | enum_type
2558 ;
2559
2560 array_type :
2561 simple_type_spec
2562 {
2563 idlc()->setParseState(PS_ArrayTypeSeen);
2564 }
2565 at_least_one_array_dim
2566 {
2567 idlc()->setParseState(PS_ArrayCompleted);
2568
2569 AstScope* pScope = idlc()->scopes()->bottom();
2570 AstDeclaration* pDecl = NULL;
2571 AstDeclaration* pArray = NULL;
2572
2573 if ( $1 )
2574 {
2575 pArray = new AstArray((AstType*)$1, *$3, idlc()->scopes()->bottom());
2576 if ( pScope )
2577 {
2578 pDecl = pScope->addDeclaration(pArray);
2579 if ( pArray != pDecl )
2580 {
2581 // if array type already defined then use it
2582 delete pArray;
2583 pArray = pDecl;
2584 }
2585 }
2586 }
2587 $$ = pArray;
2588 }
2589 ;
2590
2591 sequence_type_spec :
2592 IDL_SEQUENCE
2593 {
2594 idlc()->setParseState(PS_SequenceSeen);
2595 /*
2596 * Push a sequence marker on scopes stack
2597 */
2598 idlc()->scopes()->push(NULL);
2599 }
2600 '<'
2601 {
2602 idlc()->setParseState(PS_SequenceSqSeen);
2603 }
2604 simple_type_spec
2605 {
2606 idlc()->setParseState(PS_SequenceTypeSeen);
2607 }
2608 '>'
2609 {
2610 idlc()->setParseState(PS_SequenceQsSeen);
2611 /*
2612 * Remove sequence marker from scopes stack
2613 */
2614 if (idlc()->scopes()->top() == NULL)
2615 idlc()->scopes()->pop();
2616 /*
2617 * Create a node representing a sequence
2618 */
2619 AstScope* pScope = idlc()->scopes()->bottom();
2620 AstDeclaration* pDecl = NULL;
2621 AstDeclaration* pSeq = NULL;
2622
2623 if ( $5 )
2624 {
2625 AstType *pType = (AstType*)$5;
2626 if ( pType )
2627 {
2628 pSeq = new AstSequence(pType, pScope);
2629 /*
2630 * Add this AstSequence to the types defined in the global scope
2631 */
2632 pDecl = pScope->addDeclaration(pSeq);
2633 if ( pSeq != pDecl )
2634 {
2635 // if sequence type already defined then use it
2636 delete pSeq;
2637 pSeq = pDecl;
2638 }
2639 }
2640 }
2641 $$ = pSeq;
2642 }
2643 | error '>'
2644 {
2645 yyerror("sequence declaration");
2646 yyerrok;
2647 $$ = 0;
2648 }
2649 ;
2650
2651 struct_type :
2652 structure_header
2653 {
2654 idlc()->setParseState(PS_StructHeaderSeen);
2655
2656 AstScope* pScope = idlc()->scopes()->topNonNull();
2657 AstStruct* pStruct = NULL;
2658
2659 if ( pScope )
2660 {
2661 AstStruct* pBase= static_cast< AstStruct* >($1->getInherits());
2662 pStruct = new AstStruct(
2663 *$1->getName(), $1->getTypeParameters(), pBase, pScope);
2664 pScope->addDeclaration(pStruct);
2665 }
2666 /*
2667 * Push the scope of the struct on the scopes stack
2668 */
2669 idlc()->scopes()->push(pStruct);
2670 delete $1;
2671 }
2672 '{'
2673 {
2674 idlc()->setParseState(PS_StructSqSeen);
2675 }
2676 at_least_one_member
2677 {
2678 idlc()->setParseState(PS_StructBodySeen);
2679 }
2680 '}'
2681 {
2682 idlc()->setParseState(PS_StructQsSeen);
2683 /* this exception is finished, pop its scope from the stack */
2684 idlc()->scopes()->pop();
2685 }
2686 ;
2687
2688 structure_header :
2689 IDL_STRUCT
2690 {
2691 idlc()->setParseState(PS_StructSeen);
2692 }
2693 identifier
2694 {
2695 idlc()->setParseState(PS_StructIDSeen);
2696 checkIdentifier($3);
2697 }
2698 opt_type_params
2699 inheritance_spec
2700 {
2701 idlc()->setParseState(PS_InheritSpecSeen);
2702
2703 // Polymorphic struct type templates with base types would cause various
2704 // problems in language bindings, so forbid them here. For example,
2705 // GCC prior to version 3.4 fails with code like
2706 //
2707 // struct Base { ... };
2708 // template< typename typeparam_T > struct Derived: public Base {
2709 // int member1 CPPU_GCC3_ALIGN(Base);
2710 // ... };
2711 //
2712 // (Note that plain struct types with instantiated polymorphic struct
2713 // type bases, which might also cause problems in language bindings, are
2714 // already rejected on a syntactic level.)
2715 if ($5 != 0 && $6 != 0) {
2716 idlc()->error()->error0(EIDL_STRUCT_TYPE_TEMPLATE_WITH_BASE);
2717 }
2718
2719 $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
2720 delete $5;
2721 delete $6;
2722 }
2723 ;
2724
2725 opt_type_params:
2726 '<' type_params '>' { $$ = $2; }
2727 | /* empty */ { $$ = 0; }
2728 ;
2729
2730 type_params:
2731 identifier
2732 {
2733 $$ = new std::vector< rtl::OString >;
2734 $$->push_back(*$1);
2735 delete $1;
2736 }
2737 | type_params ',' identifier
2738 {
2739 if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
2740 idlc()->error()->error0(EIDL_IDENTICAL_TYPE_PARAMETERS);
2741 }
2742 $1->push_back(*$3);
2743 delete $3;
2744 $$ = $1;
2745 }
2746 ;
2747
2748 at_least_one_member : member members ;
2749
2750 members :
2751 members member
2752 | /* EMPTY */
2753 ;
2754
2755 member :
2756 type_or_parameter
2757 {
2758 idlc()->setParseState(PS_MemberTypeSeen);
2759 }
2760 at_least_one_declarator
2761 {
2762 idlc()->setParseState(PS_MemberDeclsSeen);
2763 }
2764 ';'
2765 {
2766 idlc()->setParseState(PS_MemberDeclsCompleted);
2767
2768 AstScope* pScope = idlc()->scopes()->topNonNull();
2769 AstMember* pMember = NULL;
2770 FeDeclList* pList = $3;
2771 FeDeclarator* pDecl = NULL;
2772 AstType const * pType = NULL;
2773
2774 // !!! check recursive type
2775
2776 if ( pScope && pList && $1 )
2777 {
2778 FeDeclList::iterator iter = pList->begin();
2779 FeDeclList::iterator end = pList->end();
2780 while (iter != end)
2781 {
2782 pDecl = (*iter);
2783 if ( !pDecl )
2784 {
2785 iter++;
2786 continue;
2787 }
2788
2789 pType = pDecl->compose($1);
2790
2791 if ( !pType )
2792 {
2793 iter++;
2794 continue;
2795 }
2796
2797 pMember = new AstMember(pType, pDecl->getName(), pScope);
2798
2799 if ( !pDecl->checkType($1) )
2800 {
2801 // WARNING
2802 }
2803
2804 pScope->addDeclaration(pMember);
2805 iter++;
2806 delete pDecl;
2807 }
2808 delete pList;
2809 }
2810 }
2811 | error ';'
2812 {
2813 yyerror("member definition");
2814 yyerrok;
2815 }
2816 ;
2817
2818 type_or_parameter:
2819 fundamental_type
2820 | scoped_name opt_type_args
2821 {
2822 AstDeclaration const * decl = 0;
2823 AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top());
2824 if (scope != 0 && $2 == 0) {
2825 decl = scope->findTypeParameter(*$1);
2826 }
2827 if (decl != 0) {
2828 delete $1;
2829 delete $2;
2830 } else {
2831 decl = createNamedType($1, $2);
2832 if (scope != 0 && includes(decl, scopeAsDecl(scope))) {
2833 idlc()->error()->error1(
2834 EIDL_RECURSIVE_TYPE, scopeAsDecl(scope));
2835 decl = 0;
2836 }
2837 }
2838 $$ = decl;
2839 }
2840 ;
2841
2842 enum_type :
2843 IDL_ENUM
2844 {
2845 idlc()->setParseState(PS_EnumSeen);
2846 }
2847 identifier
2848 {
2849 idlc()->setParseState(PS_EnumIDSeen);
2850 checkIdentifier($3);
2851
2852 AstScope* pScope = idlc()->scopes()->topNonNull();
2853 AstEnum* pEnum = NULL;
2854
2855 /*
2856 * Create a node representing an enum and add it to its
2857 * enclosing scope
2858 */
2859 if (pScope != NULL)
2860 {
2861 pEnum = new AstEnum(*$3, pScope);
2862 /*
2863 * Add it to its defining scope
2864 */
2865 pScope->addDeclaration(pEnum);
2866 }
2867 delete $3;
2868 /*
2869 * Push the enum scope on the scopes stack
2870 */
2871 idlc()->scopes()->push(pEnum);
2872
2873 }
2874 '{'
2875 {
2876 idlc()->setParseState(PS_EnumSqSeen);
2877 }
2878 at_least_one_enumerator
2879 {
2880 idlc()->setParseState(PS_EnumBodySeen);
2881 }
2882 '}'
2883 {
2884 idlc()->setParseState(PS_EnumQsSeen);
2885 /*
2886 * Done with this enum. Pop its scope from the scopes stack
2887 */
2888 if (idlc()->scopes()->top() == NULL)
2889 $$ = NULL;
2890 else
2891 {
2892 $$ = (AstEnum*)idlc()->scopes()->topNonNull();
2893 idlc()->scopes()->pop();
2894 }
2895 }
2896 ;
2897
2898 at_least_one_enumerator : enumerator enumerators ;
2899
2900 enumerators :
2901 enumerators
2902 ','
2903 {
2904 idlc()->setParseState(PS_EnumCommaSeen);
2905 }
2906 enumerator
2907 | /* EMPTY */
2908 | error ','
2909 {
2910 yyerror("enumerator definition");
2911 yyerrok;
2912 }
2913 ;
2914
2915 enumerator :
2916 identifier
2917 {
2918 checkIdentifier($1);
2919
2920 AstScope* pScope = idlc()->scopes()->topNonNull();
2921 AstEnum* pEnum = NULL;
2922 AstConstant* pEnumVal = NULL;
2923
2924 if ( pScope && pScope->getScopeNodeType() == NT_enum)
2925 {
2926 pEnum = (AstEnum*)pScope;
2927 if (pEnum && $1)
2928 {
2929 AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
2930 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2931 pExpr, *$1, pScope);
2932 }
2933 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2934 idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2935
2936 pScope->addDeclaration(pEnumVal);
2937 }
2938 delete $1;
2939 }
2940 | identifier
2941 '='
2942 const_expr
2943 {
2944 checkIdentifier($1);
2945
2946 AstScope* pScope = idlc()->scopes()->topNonNull();
2947 AstEnum* pEnum = NULL;
2948 AstConstant* pEnumVal = NULL;
2949
2950 if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
2951 {
2952 $3->evaluate(EK_const);
2953 if ( $3->coerce(ET_long) )
2954 {
2955 pEnum = (AstEnum*)pScope;
2956 if (pEnum)
2957 {
2958 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2959 $3, *$1, pScope);
2960 }
2961 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2962 idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2963
2964 pScope->addDeclaration(pEnumVal);
2965 } else
2966 {
2967 idlc()->error()->coercionError($3, ET_long);
2968 delete $3;
2969 }
2970 }
2971 delete $1;
2972 }
2973 ;
2974
2975 union_type :
2976 IDL_UNION
2977 {
2978 idlc()->setParseState(PS_UnionSeen);
2979 }
2980 identifier
2981 {
2982 idlc()->setParseState(PS_UnionIDSeen);
2983 checkIdentifier($3);
2984 }
2985 IDL_SWITCH
2986 {
2987 idlc()->setParseState(PS_SwitchSeen);
2988 }
2989 '('
2990 {
2991 idlc()->setParseState(PS_SwitchOpenParSeen);
2992 }
2993 switch_type_spec
2994 {
2995 idlc()->setParseState(PS_SwitchTypeSeen);
2996 }
2997 ')'
2998 {
2999 idlc()->setParseState(PS_SwitchCloseParSeen);
3000
3001 AstScope* pScope = idlc()->scopes()->topNonNull();
3002 AstUnion* pUnion = NULL;
3003
3004 /*
3005 * Create a node representing a union. Add it to its enclosing
3006 * scope
3007 */
3008 if ( $9 && pScope )
3009 {
3010 AstType* pType = (AstType*)$9;
3011 if ( !pType)
3012 {
3013 idlc()->error()->noTypeError($9);
3014 } else
3015 {
3016 pUnion = new AstUnion(*$3, pType, pScope);
3017 pScope->addDeclaration(pUnion);
3018 }
3019 }
3020 delete $3;
3021 /*
3022 * Push the scope of the union on the scopes stack
3023 */
3024 idlc()->scopes()->push(pUnion);
3025 }
3026 '{'
3027 {
3028 idlc()->setParseState(PS_UnionSqSeen);
3029 }
3030 at_least_one_case_branch
3031 {
3032 idlc()->setParseState(PS_UnionBodySeen);
3033 }
3034 '}'
3035 {
3036 idlc()->setParseState(PS_UnionQsSeen);
3037 /* this union is finished, pop its scope from the stack */
3038 idlc()->scopes()->pop();
3039 }
3040 ;
3041
3042 switch_type_spec :
3043 integer_type
3044 {
3045 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
3046 }
3047 | char_type
3048 {
3049 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
3050 }
3051 | boolean_type
3052 {
3053 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
3054 }
3055 | enum_type
3056 | scoped_name
3057 {
3058 AstScope* pScope = idlc()->scopes()->topNonNull();
3059 AstBaseType* pBaseType = NULL;
3060 AstDeclaration const * pDecl = NULL;
3061 AstTypeDef* pTypeDef = NULL;
3062 sal_Bool bFound = sal_False;
3063 /*
3064 * If the constant's type is a scoped name, it must resolve
3065 * to a scalar constant type
3066 */
3067 if ( pScope && (pDecl = pScope->lookupByName(*$1)) )
3068 {
3069 /*
3070 * Look through typedefs
3071 */
3072 while ( !bFound )
3073 {
3074 switch (pDecl->getNodeType())
3075 {
3076 case NT_enum:
3077 $$ = pDecl;
3078 bFound = sal_True;
3079 break;
3080 case NT_predefined:
3081 pBaseType = (AstBaseType*)pDecl;
3082 if ( pBaseType )
3083 {
3084 switch (pBaseType->getExprType())
3085 {
3086 case ET_short:
3087 case ET_ushort:
3088 case ET_long:
3089 case ET_ulong:
3090 case ET_hyper:
3091 case ET_uhyper:
3092 case ET_char:
3093 case ET_byte:
3094 case ET_boolean:
3095 $$ = pBaseType;
3096 bFound = sal_True;
3097 break;
3098 default:
3099 $$ = NULL;
3100 bFound = sal_True;
3101 break;
3102 }
3103 }
3104 break;
3105 case NT_typedef:
3106 pTypeDef = (AstTypeDef*)pDecl;
3107 if ( pTypeDef )
3108 pDecl = pTypeDef->getBaseType();
3109 break;
3110 default:
3111 $$ = NULL;
3112 bFound = sal_True;
3113 break;
3114 }
3115 }
3116 } else
3117 $$ = NULL;
3118
3119 if ($$ == NULL)
3120 idlc()->error()->lookupError(*$1);
3121 }
3122 ;
3123
3124 at_least_one_case_branch : case_branch case_branches ;
3125
3126 case_branches :
3127 case_branches case_branch
3128 | /* EMPTY */
3129 ;
3130
3131 case_branch :
3132 at_least_one_case_label
3133 {
3134 idlc()->setParseState(PS_UnionLabelSeen);
3135 }
3136 element_spec
3137 {
3138 idlc()->setParseState(PS_UnionElemSeen);
3139
3140 AstScope* pScope = idlc()->scopes()->topNonNull();
3141 AstUnionLabel* pLabel = NULL;
3142 AstUnionBranch* pBranch = NULL;
3143 AstMember* pMember = $3;
3144
3145 /*
3146 * Create several nodes representing branches of a union.
3147 * Add them to the enclosing scope (the union scope)
3148 */
3149 if ( pScope && $1 && $3 )
3150 {
3151 LabelList::iterator iter = $1->begin();
3152 LabelList::iterator end = $1->end();
3153 for (;iter != end; iter++)
3154 {
3155 pLabel = *iter;
3156 if ( !pLabel )
3157 {
3158 iter++;
3159 continue;
3160 }
3161 pBranch = new AstUnionBranch(pLabel, pMember->getType(),
3162 pMember->getLocalName(), pScope);
3163 pScope->addDeclaration(pBranch);
3164 }
3165 }
3166 if ( $1 ) delete($1);
3167 }
3168 ;
3169
3170 at_least_one_case_label :
3171 case_label case_labels
3172 {
3173 if ( $2 )
3174 {
3175 $2->push_front($1);
3176 $$ = $2;
3177 } else
3178 {
3179 LabelList* pLabels = new LabelList();
3180 pLabels->push_back($1);
3181 $$ = pLabels;
3182 }
3183 }
3184 ;
3185
3186 case_labels :
3187 case_labels case_label
3188 {
3189 if ( $1 )
3190 {
3191 $1->push_back($2);
3192 $$ = $1;
3193 } else
3194 {
3195 LabelList* pLabels = new LabelList();
3196 pLabels->push_back($2);
3197 $$ = pLabels;
3198 }
3199 }
3200 | /* EMPTY */
3201 {
3202 $$ = NULL;
3203 }
3204 ;
3205
3206 case_label :
3207 IDL_DEFAULT
3208 {
3209 idlc()->setParseState(PS_DefaultSeen);
3210 }
3211 ':'
3212 {
3213 idlc()->setParseState(PS_LabelColonSeen);
3214 $$ = new AstUnionLabel(UL_default, NULL);
3215 }
3216 | IDL_CASE
3217 {
3218 idlc()->setParseState(PS_CaseSeen);
3219 }
3220 const_expr
3221 {
3222 idlc()->setParseState(PS_LabelExprSeen);
3223 }
3224 ':'
3225 {
3226 idlc()->setParseState(PS_LabelColonSeen);
3227 $$ = new AstUnionLabel(UL_label, $3);
3228 }
3229 ;
3230
3231 element_spec :
3232 type_spec
3233 {
3234 idlc()->setParseState(PS_UnionElemTypeSeen);
3235 }
3236 declarator
3237 {
3238 idlc()->setParseState(PS_UnionElemDeclSeen);
3239 }
3240 ';'
3241 {
3242 idlc()->setParseState(PS_UnionElemCompleted);
3243
3244 AstScope* pScope = idlc()->scopes()->topNonNull();
3245 /*
3246 * Check for illegal recursive use of type
3247 */
3248 // if ( $1 && AST_illegal_recursive_type($1))
3249 // idlc()->error()->error1(EIDL_RECURSIVE_TYPE, $1);
3250 /*
3251 * Create a field in a union branch
3252 */
3253 if ( $1 && $3 )
3254 {
3255 AstType const * pType = $3->compose($1);
3256 if ( !pType )
3257 $$ = NULL;
3258 else
3259 $$ = new AstMember(pType, $3->getName(), pScope);
3260 } else
3261 $$ = NULL;
3262
3263 if ( $3 ) delete $3;
3264 }
3265 | error
3266 ';'
3267 {
3268 $$ = NULL;
3269 }
3270 ;
3271
3272 identifier:
3273 IDL_IDENTIFIER
3274 | IDL_GET { $$ = new OString("get"); }
3275 | IDL_SET { $$ = new OString("set"); }
3276 | IDL_PUBLISHED { $$ = new OString("published"); }
3277 ;
3278
3279 %%
3280
3281 /*
3282 * Report an error situation discovered in a production
3283 */
3284 void yyerror(char const *errmsg)
3285 {
3286 idlc()->error()->syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
3287 idlc()->setParseState(PS_NoState);
3288 }
3289