bump product version to 4.1.6.2
[LibreOffice.git] / idlc / source / parser.y
blob528bc966cd5ae7ab09924d65222843fa01b00b02
1 /*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 * parser.yy - BISON grammar for IDLC 1.0
24 #include <string.h>
26 #include <idlc/idlc.hxx>
27 #include <idlc/errorhandler.hxx>
28 #include <idlc/fehelper.hxx>
29 #include <idlc/astexpression.hxx>
30 #include <idlc/astconstants.hxx>
31 #include <idlc/astconstant.hxx>
32 #include <idlc/astarray.hxx>
33 #include <idlc/astbasetype.hxx>
34 #include <idlc/asttypedef.hxx>
35 #include <idlc/astexception.hxx>
36 #include <idlc/astmember.hxx>
37 #include <idlc/astenum.hxx>
38 #include <idlc/astsequence.hxx>
39 #include <idlc/astattribute.hxx>
40 #include <idlc/astoperation.hxx>
41 #include <idlc/astparameter.hxx>
42 #include <idlc/astinterfacemember.hxx>
43 #include <idlc/astservicemember.hxx>
44 #include <idlc/astobserves.hxx>
45 #include <idlc/astneeds.hxx>
46 #include <idlc/astunion.hxx>
48 #include "idlc/aststructinstance.hxx"
50 #include "attributeexceptions.hxx"
52 #include "rtl/strbuf.hxx"
54 #include <algorithm>
55 #include <vector>
58 #define YYDEBUG 1
59 #if !(defined MACOSX && defined PPC)
60 #define YYERROR_VERBOSE 1
61 #endif
63 using ::rtl::OUString;
64 using ::rtl::OString;
65 using ::rtl::OStringToOUString;
66 using ::rtl::OStringBuffer;
68 extern int yylex(void);
69 void yyerror(char const *);
71 void checkIdentifier(::rtl::OString* id)
73 static short check = 0;
74 if (check == 0) {
75 if (idlc()->getOptions()->isValid("-cid"))
76 check = 1;
77 else
78 check = 2;
81 if ( id->indexOf('_') >= 0 )
82 if ( (id->pData->buffer[0] >= 97 && id->pData->buffer[0] <= 122)
83 || id->pData->buffer[0] == '_') {
84 if (check == 1) {
85 ::rtl::OStringBuffer msg(25 + id->getLength());
86 msg.append("mismatched identifier '");
87 msg.append(*id);
88 msg.append("'");
89 idlc()->error()->syntaxError(idlc()->getParseState(),
90 idlc()->getLineNumber(),
91 msg.getStr());
93 else
94 idlc()->error()->warning0(WIDL_WRONG_NAMING_CONV, id->getStr());
98 void reportDoubleMemberDeclarations(
99 AstInterface::DoubleMemberDeclarations const & doubleMembers)
101 for (AstInterface::DoubleMemberDeclarations::const_iterator i(
102 doubleMembers.begin());
103 i != doubleMembers.end(); ++i)
105 idlc()->error()->error2(EIDL_DOUBLE_MEMBER, i->first, i->second);
109 void addInheritedInterface(
110 AstInterface * ifc, rtl::OString const & name, bool optional,
111 rtl::OUString const & documentation)
113 AstDeclaration * decl = ifc->lookupByName(name);
114 AstDeclaration const * resolved = resolveTypedefs(decl);
115 if (resolved != 0 && resolved->getNodeType() == NT_interface) {
116 if (idlc()->error()->checkPublished(decl)) {
117 if (!static_cast< AstInterface const * >(resolved)->isDefined()) {
118 idlc()->error()->inheritanceError(
119 NT_interface, &ifc->getScopedName(), decl);
120 } else {
121 AstInterface::DoubleDeclarations doubleDecls(
122 ifc->checkInheritedInterfaceClashes(
123 static_cast< AstInterface const * >(resolved),
124 optional));
125 if (doubleDecls.interfaces.empty()
126 && doubleDecls.members.empty())
128 ifc->addInheritedInterface(
129 static_cast< AstType * >(decl), optional,
130 documentation);
131 } else {
132 for (AstInterface::DoubleInterfaceDeclarations::iterator i(
133 doubleDecls.interfaces.begin());
134 i != doubleDecls.interfaces.end(); ++i)
136 idlc()->error()->error1(
137 EIDL_DOUBLE_INHERITANCE, *i);
139 reportDoubleMemberDeclarations(doubleDecls.members);
143 } else {
144 idlc()->error()->lookupError(
145 EIDL_INTERFACEMEMBER_LOOKUP, name, scopeAsDecl(ifc));
149 AstDeclaration const * createNamedType(
150 rtl::OString const * scopedName, DeclList const * typeArgs)
152 AstDeclaration * decl = idlc()->scopes()->topNonNull()->lookupByName(
153 *scopedName);
154 AstDeclaration const * resolved = resolveTypedefs(decl);
155 if (decl == 0) {
156 idlc()->error()->lookupError(*scopedName);
157 } else if (!idlc()->error()->checkPublished(decl)) {
158 decl = 0;
159 } else if (resolved->getNodeType() == NT_struct) {
160 if (static_cast< AstStruct const * >(resolved)->getTypeParameterCount()
161 != (typeArgs == 0 ? 0 : typeArgs->size()))
163 idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
164 decl = 0;
165 } else if (typeArgs != 0) {
166 AstScope * global = idlc()->scopes()->bottom();
167 AstDeclaration * inst = new AstStructInstance(
168 static_cast< AstType * >(decl), typeArgs, global);
169 decl = global->addDeclaration(inst);
170 if (decl != inst) {
171 delete inst;
174 } else if (decl->isType()) {
175 if (typeArgs != 0) {
176 idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
177 decl = 0;
179 } else {
180 idlc()->error()->noTypeError(decl);
181 decl = 0;
183 delete scopedName;
184 delete typeArgs;
185 return decl;
188 bool includes(AstDeclaration const * type1, AstDeclaration const * type2) {
189 OSL_ASSERT(type2 != 0);
190 if (type1 != 0) {
191 if (type1->getNodeType() == NT_instantiated_struct) {
192 AstStructInstance const * inst
193 = static_cast< AstStructInstance const * >(type1);
194 if (inst->getTypeTemplate() == type2) {
195 return true;
197 for (DeclList::const_iterator i(inst->getTypeArgumentsBegin());
198 i != inst->getTypeArgumentsEnd(); ++i)
200 if (includes(*i, type2)) {
201 return true;
204 } else if (type1 == type2) {
205 return true;
208 return false;
211 // Suppress any warnings from generated code:
212 #if defined __SUNPRO_CC
213 #pragma disable_warn
214 #elif defined _MSC_VER
215 #pragma warning(push, 1)
216 #pragma warning(disable: 4273 4701 4702 4706)
217 #endif
220 * Declare the type of values in the grammar
222 %union {
223 ExprType etval; /* Expression type */
224 AstDeclaration* dclval; /* Declaration */
225 AstDeclaration const * cdclval;
226 DeclList * dclsval;
227 AstExpression* exval; /* expression value */
228 ExprList* exlval; /* expression list value */
229 FeDeclarator* fdval; /* declarator value */
230 FeDeclList* dlval; /* declarator list value */
231 FeInheritanceHeader* ihval; /* inheritance header value */
232 ::rtl::OString* sval; /* OString value */
233 std::vector< rtl::OString > * svals;
234 sal_Char* strval; /* sal_Char* value */
235 bool bval; /* sal_Boolean* value */
236 sal_Int64 ival; /* sal_Int64 value */
237 sal_uInt64 uval; /* sal_uInt64 value */
238 sal_uInt32 ulval; /* sal_uInt32 value */
239 double dval; /* double value */
240 float fval; /* float value */
241 StringList* slval; /* StringList value */
242 LabelList* llval; /* LabelList value */
243 AstUnionLabel* lbval; /* union label value */
244 AstMember* mval; /* member value */
245 AttributeExceptions::Part attexcpval;
246 AttributeExceptions attexcval;
250 * Token types: These are returned by the lexer
253 %token <sval> IDL_IDENTIFIER
254 %token IDL_ATTRIBUTE
255 %token IDL_BOUND
256 %token IDL_CASE
257 %token IDL_CONST
258 %token IDL_CONSTANTS
259 %token IDL_CONSTRAINED
260 %token IDL_DEFAULT
261 %token IDL_ENUM
262 %token IDL_EXCEPTION
263 %token IDL_INTERFACE
264 %token IDL_MAYBEAMBIGUOUS
265 %token IDL_MAYBEDEFAULT
266 %token IDL_MAYBEVOID
267 %token IDL_MODULE
268 %token IDL_NEEDS
269 %token IDL_OBSERVES
270 %token IDL_OPTIONAL
271 %token IDL_PROPERTY
272 %token IDL_RAISES
273 %token IDL_READONLY
274 %token IDL_REMOVEABLE
275 %token IDL_SERVICE
276 %token IDL_SEQUENCE
277 %token IDL_SINGLETON
278 %token IDL_STRUCT
279 %token IDL_SWITCH
280 %token IDL_TYPEDEF
281 %token IDL_TRANSIENT
282 %token IDL_UNION
284 %token IDL_ANY
285 %token IDL_CHAR
286 %token IDL_BOOLEAN
287 %token IDL_BYTE
288 %token IDL_DOUBLE
289 %token IDL_FLOAT
290 %token IDL_HYPER
291 %token IDL_LONG
292 %token IDL_SHORT
293 %token IDL_VOID
294 %token IDL_STRING
295 %token IDL_TYPE
296 %token IDL_UNSIGNED
298 %token IDL_TRUE
299 %token IDL_FALSE
301 %token IDL_IN
302 %token IDL_OUT
303 %token IDL_INOUT
305 %token IDL_GET
306 %token IDL_SET
308 %token IDL_PUBLISHED
310 %token IDL_ELLIPSIS
312 %token <strval> IDL_LEFTSHIFT
313 %token <strval> IDL_RIGHTSHIFT
314 %token <strval> IDL_SCOPESEPARATOR
316 %token <ival> IDL_INTEGER_LITERAL
317 %token <uval> IDL_INTEGER_ULITERAL
318 %token <dval> IDL_FLOATING_PT_LITERAL
321 * These are production names:
323 %type <dclval> type_dcl
324 %type <dclval> array_declarator
325 %type <dclval> exception_name
326 %type <cdclval> array_type constructed_type_spec enum_type op_type_spec
327 %type <cdclval> sequence_type_spec simple_type_spec struct_type switch_type_spec
328 %type <cdclval> template_type_spec type_spec union_type
329 %type <cdclval> fundamental_type type_arg type_or_parameter
330 %type <dclsval> opt_raises raises exception_list
331 %type <attexcpval> opt_attribute_get_raises attribute_get_raises
332 %type <attexcpval> opt_attribute_set_raises attribute_set_raises
333 %type <dclsval> opt_type_args type_args
335 %type <sval> identifier
336 %type <sval> interface_decl
337 %type <sval> scoped_name inheritance_spec
338 %type <slval> scoped_names at_least_one_scoped_name
340 %type <etval> const_type integer_type char_type boolean_type
341 %type <etval> floating_pt_type any_type signed_int string_type
342 %type <etval> unsigned_int base_type_spec byte_type type_type
344 %type <exval> expression const_expr or_expr xor_expr and_expr
345 %type <exval> add_expr mult_expr unary_expr primary_expr shift_expr
346 %type <exval> literal positive_int_expr array_dim
348 %type <exlval> at_least_one_array_dim array_dims
350 %type <fdval> declarator simple_declarator complex_declarator
351 %type <dlval> declarators at_least_one_declarator
353 %type <ihval> exception_header structure_header interfaceheader
355 %type <ulval> flag_header opt_attrflags opt_attrflag
356 %type <ulval> direction service_interface_header service_service_header
358 %type <llval> case_labels at_least_one_case_label
359 %type <lbval> case_label
360 %type <mval> element_spec
362 %type <bval> optional_inherited_interface opt_rest opt_service_body
364 %type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises
366 %type <svals> opt_type_params type_params
370 * Grammar start here
372 start : definitions;
374 definitions :
375 definition definitions
376 | /* EMPTY */
379 definition :
380 opt_published publishable_definition
381 | module_dcl
383 idlc()->setParseState(PS_ModuleDeclSeen);
387 idlc()->setParseState(PS_NoState);
389 | error ';'
391 yyerror("definitions");
392 yyerrok;
396 opt_published:
397 IDL_PUBLISHED { idlc()->setPublished(true); }
398 | /* empty */ { idlc()->setPublished(false); }
401 publishable_definition:
402 type_dcl
404 idlc()->setParseState(PS_TypeDeclSeen);
408 idlc()->setParseState(PS_NoState);
410 | exception_dcl
412 idlc()->setParseState(PS_ExceptionDeclSeen);
416 idlc()->setParseState(PS_NoState);
418 | interface
420 idlc()->setParseState(PS_InterfaceDeclSeen);
424 idlc()->setParseState(PS_NoState);
426 | service_dcl
428 idlc()->setParseState(PS_ServiceDeclSeen);
432 idlc()->setParseState(PS_NoState);
434 | singleton_dcl
436 idlc()->setParseState(PS_SingletonDeclSeen);
440 idlc()->setParseState(PS_NoState);
442 | constants_dcl
444 idlc()->setParseState(PS_ConstantsDeclSeen);
448 idlc()->setParseState(PS_NoState);
452 module_dcl :
453 IDL_MODULE
455 idlc()->setParseState(PS_ModuleSeen);
456 idlc()->setPublished(false);
458 identifier
460 idlc()->setParseState(PS_ModuleIDSeen);
461 checkIdentifier($3);
463 AstScope* pScope = idlc()->scopes()->topNonNull();
464 AstModule* pModule = NULL;
465 AstDeclaration* pExists = NULL;
467 if ( pScope )
469 pModule = new AstModule(*$3, pScope);
470 if( (pExists = pScope->lookupForAdd(pModule)) )
472 pExists->setInMainfile(idlc()->isInMainFile());
473 pExists->setFileName(pModule->getFileName());
474 if (pExists->isPredefined())
476 pExists->setPredefined(false);
477 if (pExists->getDocumentation().getLength() == 0 &&
478 pModule->getDocumentation().getLength() > 0)
480 pExists->setDocumentation(pModule->getDocumentation());
483 delete(pModule);
484 pModule = (AstModule*)pExists;
485 } else
487 pScope->addDeclaration(pModule);
489 idlc()->scopes()->push(pModule);
491 delete $3;
495 idlc()->setParseState(PS_ModuleSqSeen);
497 definitions
499 idlc()->setParseState(PS_ModuleBodySeen);
503 idlc()->setParseState(PS_ModuleQsSeen);
505 * Finished with this module - pop it from the scope stack
507 idlc()->scopes()->pop();
511 interface :
512 interface_dcl
513 | forward_dcl
516 interface_decl :
517 IDL_INTERFACE
519 idlc()->setParseState(PS_InterfaceSeen);
521 identifier
523 idlc()->setParseState(PS_InterfaceIDSeen);
524 checkIdentifier($3);
525 $$ = $3;
529 forward_dcl :
530 interface_decl
532 idlc()->setParseState(PS_ForwardDeclSeen);
534 AstScope* pScope = idlc()->scopes()->topNonNull();
535 AstInterface* pForward = NULL;
536 AstDeclaration* pDecl = NULL;
539 * Make a new forward interface node and add it to its enclosing scope
541 if ( pScope && $1 )
543 pForward = new AstInterface(*$1, NULL, pScope);
545 pDecl = pScope->lookupByName(pForward->getScopedName());
546 if ( pDecl )
548 if ( (pDecl != pForward) &&
549 (pDecl->getNodeType() == NT_interface) )
551 delete pForward;
552 } else
554 idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(pScope), pDecl);
556 } else
559 * Add the interface to its definition scope
561 pScope->addDeclaration(pForward);
564 delete $1;
568 interface_dcl :
569 interfaceheader
571 idlc()->setParseState(PS_InterfaceHeadSeen);
573 AstScope* pScope = idlc()->scopes()->topNonNull();
574 AstInterface* pInterface = NULL;
575 AstInterface* pForward = NULL;
576 AstDeclaration* pDecl = NULL;
579 * Make a new interface node and add it to its enclosing scope
581 if ( pScope && $1 )
583 pInterface = new AstInterface(
584 *$1->getName(),
585 static_cast< AstInterface * >($1->getInherits()), pScope);
586 if ( pInterface &&
587 (pDecl = pScope->lookupByName(pInterface->getScopedName())) )
590 * See if we're defining a forward declared interface.
592 if (pDecl->getNodeType() == NT_interface)
594 pForward = (AstInterface*)pDecl;
595 if ( !pForward->isDefined() )
598 * Check if redefining in same scope
600 if ( pForward->getScope() != pScope )
602 if ( pForward->getScopedName() != pInterface->getScopedName() )
604 idlc()->error()->error3(EIDL_SCOPE_CONFLICT,
605 pInterface, pForward, scopeAsDecl(pScope));
608 else if ( !pInterface->isPublished()
609 && pForward->isPublished() )
611 idlc()->error()->error0(EIDL_PUBLISHED_FORWARD);
614 * All OK, set full definition
616 else
618 pForward->forwardDefined(*pInterface);
619 delete pInterface;
620 pInterface = pForward;
622 } else {
623 // special handling for XInterface because it is predefined
624 if ( pForward->isPredefined() &&
625 pForward->getScopedName() == "com::sun::star::uno::XInterface")
627 /* replace the predefined XInterface */
628 *pForward = *pInterface;
629 delete pInterface;
630 pInterface = pForward;
635 } else
638 * Add the interface to its definition scope
640 pScope->addDeclaration(pInterface);
644 * Push it on the scope stack
646 idlc()->scopes()->push(pInterface);
647 delete($1);
651 idlc()->setParseState(PS_InterfaceSqSeen);
653 exports
655 AstInterface * ifc = static_cast< AstInterface * >(
656 idlc()->scopes()->topNonNull());
657 if (!ifc->hasMandatoryInheritedInterfaces()
658 && ifc->getScopedName() != "com::sun::star::uno::XInterface")
660 addInheritedInterface(
661 ifc, rtl::OString("::com::sun::star::uno::XInterface"), false,
662 rtl::OUString());
664 ifc->setDefined();
665 idlc()->setParseState(PS_InterfaceBodySeen);
669 idlc()->setParseState(PS_InterfaceQsSeen);
671 * Done with this interface - pop it off the scopes stack
673 idlc()->scopes()->pop();
675 | error '}'
677 yyerror("interface definition");
678 yyerrok;
682 interfaceheader :
683 interface_decl inheritance_spec
685 idlc()->setParseState(PS_InheritSpecSeen);
687 $$ = new FeInheritanceHeader(NT_interface, $1, $2, 0);
688 delete $2;
692 inheritance_spec :
695 idlc()->setParseState(PS_InheritColonSeen);
697 scoped_name
699 $$ = $3;
701 | /* EMPTY */
703 $$ = NULL;
707 exports :
708 exports export
709 | /* EMPTY */
712 export :
713 attribute
715 idlc()->setParseState(PS_AttributeDeclSeen);
719 idlc()->setParseState(PS_NoState);
721 | operation
723 idlc()->setParseState(PS_OperationDeclSeen);
727 idlc()->setParseState(PS_NoState);
729 | interface_inheritance_decl
731 idlc()->setParseState(PS_InterfaceInheritanceDeclSeen);
735 idlc()->setParseState(PS_NoState);
739 attribute :
740 flag_header
741 simple_type_spec
743 idlc()->setParseState(PS_AttrTypeSeen);
745 simple_declarator
747 idlc()->setParseState(PS_AttrCompleted);
748 if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) {
749 idlc()->error()->flagError(EIDL_BAD_ATTRIBUTE_FLAGS, $1);
751 AstInterface * scope = static_cast< AstInterface * >(
752 idlc()->scopes()->top());
753 AstAttribute * attr = new AstAttribute(
754 $1, $4->compose($2), $4->getName(), scope);
755 delete $4;
756 AstInterface::DoubleMemberDeclarations doubleMembers(
757 scope->checkMemberClashes(attr));
758 if (doubleMembers.empty()) {
759 scope->addMember(attr);
760 } else {
761 reportDoubleMemberDeclarations(doubleMembers);
763 idlc()->scopes()->push(attr);
765 opt_attribute_block
767 static_cast< AstAttribute * >(idlc()->scopes()->top())->setExceptions(
768 $6.get.documentation, $6.get.exceptions, $6.set.documentation,
769 $6.set.exceptions);
770 delete $6.get.documentation;
771 delete $6.get.exceptions;
772 delete $6.set.documentation;
773 delete $6.set.exceptions;
774 idlc()->scopes()->pop();
778 flag_header :
779 '[' opt_attrflags ']'
781 idlc()->setParseState(PS_FlagHeaderSeen);
782 $$ = $2;
786 opt_attrflags :
787 opt_attrflags ',' opt_attrflag
789 if ( ($1 & $3) == $3 )
790 idlc()->error()->flagError(EIDL_DEFINED_ATTRIBUTEFLAG, $3);
792 $$ = $1 | $3;
794 | opt_attrflag
796 $$ = $1;
800 opt_attrflag :
801 IDL_ATTRIBUTE
803 idlc()->setParseState(PS_AttrSeen);
804 $$ = AF_ATTRIBUTE;
806 | IDL_PROPERTY
808 idlc()->setParseState(PS_PropertySeen);
809 $$ = AF_PROPERTY;
811 | IDL_READONLY
813 idlc()->setParseState(PS_ReadOnlySeen);
814 $$ = AF_READONLY;
816 | IDL_OPTIONAL
818 idlc()->setParseState(PS_OptionalSeen);
819 $$ = AF_OPTIONAL;
821 | IDL_MAYBEVOID
823 idlc()->setParseState(PS_MayBeVoidSeen);
824 $$ = AF_MAYBEVOID;
826 | IDL_BOUND
828 idlc()->setParseState(PS_BoundSeen);
829 $$ = AF_BOUND;
831 | IDL_CONSTRAINED
833 idlc()->setParseState(PS_ConstrainedSeen);
834 $$ = AF_CONSTRAINED;
836 | IDL_TRANSIENT
838 idlc()->setParseState(PS_TransientSeen);
839 $$ = AF_TRANSIENT;
841 | IDL_MAYBEAMBIGUOUS
843 idlc()->setParseState(PS_MayBeAmbigiousSeen);
844 $$ = AF_MAYBEAMBIGUOUS;
846 | IDL_MAYBEDEFAULT
848 idlc()->setParseState(PS_MayBeDefaultSeen);
849 $$ = AF_MAYBEDEFAULT;
851 | IDL_REMOVEABLE
853 idlc()->setParseState(PS_RemoveableSeen);
854 $$ = AF_REMOVEABLE;
856 | error ']'
858 yyerror("unknown property|attribute flag");
859 yyerrok;
863 opt_attribute_block:
864 '{' attribute_block_rest { $$ = $2; }
865 | /* empty */
867 $$.get.documentation = 0;
868 $$.get.exceptions = 0;
869 $$.set.documentation = 0;
870 $$.set.exceptions = 0;
874 attribute_block_rest:
875 opt_attribute_raises '}'
876 | error '}'
878 yyerror("bad attribute raises block");
879 yyerrok;
880 $$.get.documentation = 0;
881 $$.get.exceptions = 0;
882 $$.set.documentation = 0;
883 $$.set.exceptions = 0;
887 opt_attribute_raises:
888 attribute_get_raises
889 opt_attribute_set_raises
891 $$.get = $1;
892 $$.set = $2;
894 | attribute_set_raises
895 opt_attribute_get_raises
897 $$.get = $2;
898 $$.set = $1;
900 | /* empty */
902 $$.get.documentation = 0;
903 $$.get.exceptions = 0;
904 $$.set.documentation = 0;
905 $$.set.exceptions = 0;
909 opt_attribute_get_raises:
910 attribute_get_raises
911 | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
914 attribute_get_raises:
915 IDL_GET raises ';'
917 $$.documentation = new rtl::OUString(
918 rtl::OStringToOUString(
919 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
920 $$.exceptions = $2;
924 opt_attribute_set_raises:
925 attribute_set_raises
926 | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
929 attribute_set_raises:
930 IDL_SET
932 if (static_cast< AstAttribute * >(idlc()->scopes()->top())->
933 isReadonly())
935 idlc()->error()->error0(EIDL_READONLY_ATTRIBUTE_SET_EXCEPTIONS);
938 raises ';'
940 $$.documentation = new rtl::OUString(
941 rtl::OStringToOUString(
942 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
943 $$.exceptions = $3;
947 operation :
948 op_type_spec
950 idlc()->setParseState(PS_OpTypeSeen);
952 identifier
954 idlc()->setParseState(PS_OpIDSeen);
955 checkIdentifier($3);
957 AstInterface * pScope = static_cast< AstInterface * >(
958 idlc()->scopes()->top());
959 AstOperation* pOp = NULL;
962 * Create a node representing an operation on an interface
963 * and add it to its enclosing scope
965 if ( pScope && $1 )
967 AstType *pType = (AstType*)$1;
968 if ( !pType || (pType->getNodeType() == NT_exception) )
970 // type ERROR
971 } else
973 pOp = new AstOperation(pType, *$3, pScope);
975 AstInterface::DoubleMemberDeclarations doubleMembers(
976 pScope->checkMemberClashes(pOp));
977 if (doubleMembers.empty()) {
978 pScope->addMember(pOp);
979 } else {
980 reportDoubleMemberDeclarations(doubleMembers);
984 delete $3;
986 * Push the operation scope onto the scopes stack
988 idlc()->scopes()->push(pOp);
992 idlc()->setParseState(PS_OpSqSeen);
994 parameters
996 idlc()->setParseState(PS_OpParsCompleted);
1000 idlc()->setParseState(PS_OpQsSeen);
1002 opt_raises
1004 AstScope* pScope = idlc()->scopes()->topNonNull();
1005 AstOperation* pOp = NULL;
1007 * Add exceptions and context to the operation
1009 if ( pScope && pScope->getScopeNodeType() == NT_operation)
1011 pOp = (AstOperation*)pScope;
1013 if ( pOp )
1014 pOp->setExceptions($11);
1016 delete $11;
1018 * Done with this operation. Pop its scope from the scopes stack
1020 idlc()->scopes()->pop();
1024 op_type_spec :
1025 simple_type_spec
1026 | IDL_VOID
1028 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void);
1032 parameters :
1033 parameter
1034 | parameters
1037 idlc()->setParseState(PS_OpParCommaSeen);
1039 parameter
1040 | /* EMPTY */
1041 | error ','
1043 yyerror("parameter definition");
1044 yyerrok;
1048 parameter :
1050 direction
1053 idlc()->setParseState(PS_OpParDirSeen);
1055 simple_type_spec
1057 idlc()->setParseState(PS_OpParTypeSeen);
1059 opt_rest
1060 declarator
1062 idlc()->setParseState(PS_OpParDeclSeen);
1064 AstOperation * pScope = static_cast< AstOperation * >(
1065 idlc()->scopes()->top());
1066 AstParameter* pParam = NULL;
1069 * Create a node representing an argument to an operation
1070 * Add it to the enclosing scope (the operation scope)
1072 if ( pScope && $5 && $8 )
1074 AstType const * pType = $8->compose($5);
1075 if ( pType )
1077 if (pScope->isConstructor() && $2 != DIR_IN) {
1078 idlc()->error()->error0(EIDL_CONSTRUCTOR_PARAMETER_NOT_IN);
1080 if (pScope->isVariadic()) {
1081 idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_LAST);
1083 if ($7) {
1084 AstDeclaration const * type = resolveTypedefs(pType);
1085 if (type->getNodeType() != NT_predefined
1086 || (static_cast< AstBaseType const * >(type)->
1087 getExprType() != ET_any))
1089 idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_ANY);
1091 if (pScope->isConstructor()) {
1092 if (pScope->getIteratorBegin()
1093 != pScope->getIteratorEnd())
1095 idlc()->error()->error0(
1096 EIDL_CONSTRUCTOR_REST_PARAMETER_NOT_FIRST);
1098 } else {
1099 idlc()->error()->error0(EIDL_METHOD_HAS_REST_PARAMETER);
1103 pParam = new AstParameter(
1104 static_cast< Direction >($2), $7, pType, $8->getName(),
1105 pScope);
1107 if ( !$8->checkType($5) )
1109 // WARNING
1112 pScope->addDeclaration(pParam);
1116 | error
1117 simple_type_spec
1119 idlc()->setParseState(PS_NoState);
1120 yyerrok;
1124 direction :
1125 IDL_IN
1127 $$ = DIR_IN;
1129 | IDL_OUT
1131 $$ = DIR_OUT;
1133 | IDL_INOUT
1135 $$ = DIR_INOUT;
1139 opt_rest:
1140 IDL_ELLIPSIS
1142 $$ = true;
1144 | /* empty */
1146 $$ = false;
1150 opt_raises:
1151 raises
1152 | /* empty */
1154 $$ = 0;
1158 raises:
1159 IDL_RAISES
1161 idlc()->setParseState(PS_RaiseSeen);
1165 idlc()->setParseState(PS_RaiseSqSeen);
1167 exception_list
1170 idlc()->setParseState(PS_RaiseQsSeen);
1171 $$ = $5;
1175 exception_list:
1176 exception_name
1178 $$ = new DeclList;
1179 $$->push_back($1);
1181 | exception_list ',' exception_name
1183 $1->push_back($3);
1184 $$ = $1;
1188 exception_name:
1189 scoped_name
1191 // The topmost scope is either an AstOperation (for interface methods
1192 // and service constructors) or an AstAttribute (for interface
1193 // attributes), so look up exception names in the next-to-topmost scope:
1194 AstDeclaration * decl = idlc()->scopes()->nextToTop()->lookupByName(
1195 *$1);
1196 if (decl == 0) {
1197 idlc()->error()->lookupError(*$1);
1198 } else if (!idlc()->error()->checkPublished(decl)) {
1199 decl = 0;
1200 } else if (decl->getNodeType() != NT_exception) {
1201 idlc()->error()->error1(EIDL_ILLEGAL_RAISES, decl);
1202 decl = 0;
1204 delete $1;
1205 $$ = decl;
1209 interface_inheritance_decl:
1210 optional_inherited_interface
1211 IDL_INTERFACE
1213 idlc()->setParseState(PS_ServiceIFHeadSeen);
1215 scoped_name
1217 AstInterface * ifc = static_cast< AstInterface * >(
1218 idlc()->scopes()->top());
1219 if (ifc->usesSingleInheritance()) {
1220 idlc()->error()->error0(EIDL_MIXED_INHERITANCE);
1221 } else {
1222 addInheritedInterface(
1223 ifc, *$4, $1,
1224 rtl::OStringToOUString(
1225 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
1227 delete $4;
1231 optional_inherited_interface:
1232 '[' IDL_OPTIONAL ']' { $$ = true; }
1233 | /* EMPTY */ { $$ = false; }
1236 constants_exports :
1237 constants_export constants_exports
1238 | /* EMPTY */
1241 constants_export :
1242 IDL_CONST
1244 idlc()->setParseState(PS_ConstSeen);
1246 const_type
1248 idlc()->setParseState(PS_ConstTypeSeen);
1250 identifier
1252 idlc()->setParseState(PS_ConstIDSeen);
1253 checkIdentifier($5);
1257 idlc()->setParseState(PS_ConstAssignSeen);
1259 expression
1261 idlc()->setParseState(PS_ConstExprSeen);
1263 AstScope* pScope = idlc()->scopes()->topNonNull();
1264 AstConstant* pConstant = NULL;
1266 if ( $9 && pScope )
1268 if ( !$9->coerce($3) )
1270 idlc()->error()->coercionError($9, $3);
1271 } else
1273 pConstant = new AstConstant($3, $9, *$5, pScope);
1274 pScope->addDeclaration(pConstant);
1277 delete $5;
1279 idlc()->setParseState(PS_ConstantDeclSeen);
1281 ';' {};
1284 constants_dcl :
1285 IDL_CONSTANTS
1287 idlc()->setParseState(PS_ConstantsSeen);
1289 identifier
1291 idlc()->setParseState(PS_ConstantsIDSeen);
1292 checkIdentifier($3);
1296 idlc()->setParseState(PS_ConstantsSqSeen);
1298 AstScope* pScope = idlc()->scopes()->topNonNull();
1299 AstConstants* pConstants = NULL;
1300 AstDeclaration* pExists = NULL;
1302 if ( pScope )
1304 pConstants = new AstConstants(*$3, pScope);
1305 if( (pExists = pScope->lookupForAdd(pConstants)) )
1307 pExists->setInMainfile(idlc()->isInMainFile());
1308 delete(pConstants);
1309 pConstants = (AstConstants*)pExists;
1310 } else
1312 pScope->addDeclaration(pConstants);
1314 idlc()->scopes()->push(pConstants);
1316 delete $3;
1318 constants_exports
1320 idlc()->setParseState(PS_ConstantsBodySeen);
1324 idlc()->setParseState(PS_ConstantsQsSeen);
1326 * Finished with this constants - pop it from the scope stack
1328 idlc()->scopes()->pop();
1332 expression : const_expr ;
1334 const_expr : or_expr ;
1336 or_expr :
1337 xor_expr
1338 | or_expr '|' xor_expr
1340 $$ = new AstExpression(EC_or, $1, $3);
1344 xor_expr :
1345 and_expr
1346 | xor_expr '^' and_expr
1348 $$ = new AstExpression(EC_xor, $1, $3);
1352 and_expr :
1353 shift_expr
1354 | and_expr '&' shift_expr
1356 $$ = new AstExpression(EC_and, $1, $3);
1360 shift_expr :
1361 add_expr
1362 | shift_expr IDL_LEFTSHIFT add_expr
1364 $$ = new AstExpression(EC_left, $1, $3);
1366 | shift_expr IDL_RIGHTSHIFT add_expr
1368 $$ = new AstExpression(EC_right, $1, $3);
1372 add_expr :
1373 mult_expr
1374 | add_expr '+' mult_expr
1376 $$ = new AstExpression(EC_add, $1, $3);
1378 | add_expr '-' mult_expr
1380 $$ = new AstExpression(EC_minus, $1, $3);
1384 mult_expr :
1385 unary_expr
1386 | mult_expr '*' unary_expr
1388 $$ = new AstExpression(EC_mul, $1, $3);
1390 | mult_expr '/' unary_expr
1392 $$ = new AstExpression(EC_div, $1, $3);
1394 | mult_expr '%' unary_expr
1396 $$ = new AstExpression(EC_mod, $1, $3);
1400 unary_expr :
1401 primary_expr
1402 | '+' primary_expr
1404 $$ = new AstExpression(EC_u_plus, $2, NULL);
1406 | '-' primary_expr
1408 $$ = new AstExpression(EC_u_minus, $2, NULL);
1410 | '~' primary_expr
1415 primary_expr :
1416 scoped_name
1419 * An expression which is a scoped name is not resolved now,
1420 * but only when it is evaluated (such as when it is assigned
1421 * as a constant value)
1423 $$ = new AstExpression($1);
1425 | literal
1426 | '(' const_expr ')'
1428 $$ = $2;
1432 literal :
1433 IDL_INTEGER_LITERAL
1435 $$ = new AstExpression($1);
1437 | IDL_INTEGER_ULITERAL
1439 $$ = new AstExpression($1);
1441 | IDL_FLOATING_PT_LITERAL
1443 $$ = new AstExpression($1);
1445 | IDL_TRUE
1447 $$ = new AstExpression((sal_Int32)1, ET_boolean);
1449 | IDL_FALSE
1451 $$ = new AstExpression((sal_Int32)0, ET_boolean);
1455 positive_int_expr :
1456 const_expr
1458 $1->evaluate(EK_const);
1459 if ( !$1->coerce(ET_ulong) )
1461 idlc()->error()->coercionError($1, ET_ulong);
1462 delete $1;
1463 $$ = NULL;
1468 const_type :
1469 integer_type
1470 | byte_type
1471 | boolean_type
1472 | floating_pt_type
1473 | scoped_name
1475 AstScope* pScope = idlc()->scopes()->topNonNull();
1476 AstDeclaration const * type = 0;
1479 * If the constant's type is a scoped name, it must resolve
1480 * to a scalar constant type
1482 if ( pScope && (type = pScope->lookupByName(*$1)) ) {
1483 if (!idlc()->error()->checkPublished(type))
1485 type = 0;
1487 else
1489 type = resolveTypedefs(type);
1490 if (type->getNodeType() == NT_predefined)
1492 $$ = static_cast< AstBaseType const * >(type)->
1493 getExprType();
1494 } else
1495 $$ = ET_any;
1497 } else
1498 $$ = ET_any;
1502 exception_header :
1503 IDL_EXCEPTION
1505 idlc()->setParseState(PS_ExceptSeen);
1507 identifier
1509 idlc()->setParseState(PS_ExceptIDSeen);
1510 checkIdentifier($3);
1512 inheritance_spec
1514 idlc()->setParseState(PS_InheritSpecSeen);
1516 $$ = new FeInheritanceHeader(NT_exception, $3, $5, 0);
1517 delete $5;
1521 exception_dcl :
1522 exception_header
1524 idlc()->setParseState(PS_ExceptHeaderSeen);
1526 AstScope* pScope = idlc()->scopes()->topNonNull();
1527 AstException* pExcept = NULL;
1529 if ( pScope )
1531 AstException* pBase = static_cast< AstException* >(
1532 $1->getInherits());
1533 pExcept = new AstException(*$1->getName(), pBase, pScope);
1534 pScope->addDeclaration(pExcept);
1537 * Push the scope of the exception on the scopes stack
1539 idlc()->scopes()->push(pExcept);
1540 delete $1;
1544 idlc()->setParseState(PS_ExceptSqSeen);
1546 members
1548 idlc()->setParseState(PS_ExceptBodySeen);
1552 idlc()->setParseState(PS_ExceptQsSeen);
1553 /* this exception is finished, pop its scope from the stack */
1554 idlc()->scopes()->pop();
1558 property :
1559 flag_header
1560 simple_type_spec
1562 idlc()->setParseState(PS_PropertyTypeSeen);
1564 at_least_one_declarator
1566 idlc()->setParseState(PS_PropertyCompleted);
1568 AstScope* pScope = idlc()->scopes()->topNonNull();
1569 AstAttribute* pAttr = NULL;
1570 FeDeclList* pList = $4;
1571 FeDeclarator* pDecl = NULL;
1572 AstType const * pType = NULL;
1574 if ( pScope->getScopeNodeType() == NT_singleton )
1576 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1577 } else
1579 if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
1580 idlc()->error()->flagError(EIDL_WRONGATTRIBUTEKEYWORD, AF_ATTRIBUTE);
1582 if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
1583 idlc()->error()->flagError(EIDL_MISSINGATTRIBUTEKEYWORD, AF_PROPERTY);
1586 * Create nodes representing attributes and add them to the
1587 * enclosing scope
1589 if ( pScope && $2 && pList )
1591 FeDeclList::iterator iter = pList->begin();
1592 FeDeclList::iterator end = pList->end();
1594 while (iter != end)
1596 pDecl = (*iter);
1597 if ( !pDecl )
1599 iter++;
1600 continue;
1603 pType = pDecl->compose($2);
1605 if ( !pType )
1607 iter++;
1608 continue;
1611 pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);
1613 pScope->addDeclaration(pAttr);
1614 iter++;
1615 delete pDecl;
1620 if ( pList )
1621 delete pList;
1623 | error ';'
1625 yyerror("property");
1626 yyerrok;
1630 service_exports :
1631 service_exports service_export
1632 | /* EMPTY */
1635 service_export :
1636 service_interface_header
1637 at_least_one_scoped_name
1640 idlc()->setParseState(PS_ServiceMemberSeen);
1642 AstScope* pScope = idlc()->scopes()->topNonNull();
1643 AstDeclaration* pDecl = NULL;
1644 AstInterfaceMember* pIMember = NULL;
1646 if ( pScope->getScopeNodeType() == NT_singleton )
1648 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1649 } else
1652 * Create a node representing a class member.
1653 * Store it in the enclosing scope
1655 if ( pScope && $2 )
1657 StringList::iterator iter = $2->begin();
1658 StringList::iterator end = $2->end();
1660 while ( iter != end )
1662 pDecl = pScope->lookupByName(*iter);
1663 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1665 /* we relax the strict published check and allow to add new
1666 * interfaces if they are optional
1668 bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
1669 if ( idlc()->error()->checkPublished(pDecl, bOptional) )
1671 pIMember = new AstInterfaceMember(
1672 $1, (AstInterface*)pDecl, *iter, pScope);
1673 pScope->addDeclaration(pIMember);
1675 } else
1677 idlc()->error()->
1678 lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1680 iter++;
1684 delete $2;
1686 | service_service_header
1687 at_least_one_scoped_name
1690 idlc()->setParseState(PS_ServiceMemberSeen);
1692 AstScope* pScope = idlc()->scopes()->topNonNull();
1693 AstDeclaration* pDecl = NULL;
1694 AstServiceMember* pSMember = NULL;
1697 * Create a node representing a class member.
1698 * Store it in the enclosing scope
1700 if ( pScope && $2 )
1702 StringList::iterator iter = $2->begin();
1703 StringList::iterator end = $2->end();
1705 while ( iter != end )
1707 pDecl = pScope->lookupByName(*iter);
1708 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1710 if ( static_cast< AstService * >(pDecl)->isSingleInterfaceBasedService() || (pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0) )
1711 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1712 else if ( idlc()->error()->checkPublished(pDecl) )
1714 pSMember = new AstServiceMember(
1715 $1, (AstService*)pDecl, *iter, pScope);
1716 pScope->addDeclaration(pSMember);
1718 } else
1720 idlc()->error()->
1721 lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1723 iter++;
1726 delete $2;
1728 | IDL_OBSERVES
1729 at_least_one_scoped_name
1732 idlc()->setParseState(PS_ServiceMemberSeen);
1734 AstScope* pScope = idlc()->scopes()->topNonNull();
1735 AstDeclaration* pDecl = NULL;
1736 AstObserves* pObserves = NULL;
1738 if ( pScope->getScopeNodeType() == NT_singleton )
1740 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1741 } else
1744 * Create a node representing a class member.
1745 * Store it in the enclosing scope
1747 if ( pScope && $2 )
1749 StringList::iterator iter = $2->begin();
1750 StringList::iterator end = $2->end();
1752 while ( iter != end )
1754 pDecl = pScope->lookupByName(*iter);
1755 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1757 pObserves = new AstObserves((AstInterface*)pDecl, *iter, pScope);
1758 pScope->addDeclaration(pObserves);
1759 } else
1761 idlc()->error()->
1762 lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1764 iter++;
1768 delete $2;
1770 | IDL_NEEDS
1771 at_least_one_scoped_name
1774 idlc()->setParseState(PS_ServiceMemberSeen);
1776 AstScope* pScope = idlc()->scopes()->topNonNull();
1777 AstDeclaration* pDecl = NULL;
1778 AstNeeds* pNeeds = NULL;
1780 if ( pScope->getScopeNodeType() == NT_singleton )
1782 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1783 } else
1786 * Create a node representing a class member.
1787 * Store it in the enclosing scope
1789 if ( pScope && $2 )
1791 StringList::iterator iter = $2->begin();
1792 StringList::iterator end = $2->end();
1794 while ( iter != end )
1796 pDecl = pScope->lookupByName(*iter);
1797 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1799 pNeeds = new AstNeeds((AstService*)pDecl, *iter, pScope);
1800 pScope->addDeclaration(pNeeds);
1801 } else
1803 idlc()->error()->
1804 lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1806 iter++;
1810 delete $2;
1812 | property
1815 idlc()->setParseState(PS_PropertyDeclSeen);
1819 service_interface_header :
1820 IDL_INTERFACE
1822 idlc()->setParseState(PS_ServiceIFHeadSeen);
1823 $$ = AF_INVALID;
1825 | flag_header
1826 IDL_INTERFACE
1828 idlc()->setParseState(PS_ServiceIFHeadSeen);
1829 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1830 idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1831 $$ = $1;
1835 service_service_header :
1836 IDL_SERVICE
1838 idlc()->setParseState(PS_ServiceSHeadSeen);
1839 $$ = AF_INVALID;
1841 | flag_header
1842 IDL_SERVICE
1844 idlc()->setParseState(PS_ServiceSHeadSeen);
1845 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1846 idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1847 $$ = $1;
1851 service_dcl :
1852 IDL_SERVICE
1854 idlc()->setParseState(PS_ServiceSeen);
1856 identifier
1858 idlc()->setParseState(PS_ServiceIDSeen);
1859 checkIdentifier($3);
1861 AstScope* pScope = idlc()->scopes()->topNonNull();
1862 AstService* pService = NULL;
1865 * Make a new service and add it to the enclosing scope
1867 if (pScope != NULL)
1869 pService = new AstService(*$3, pScope);
1870 pScope->addDeclaration(pService);
1872 delete $3;
1874 * Push it on the stack
1876 idlc()->scopes()->push(pService);
1878 service_dfn
1880 /* this service is finished, pop its scope from the stack */
1881 idlc()->scopes()->pop();
1885 service_dfn:
1886 service_interface_dfn
1887 | service_obsolete_dfn
1890 service_interface_dfn:
1891 ':' scoped_name
1893 AstScope * scope = idlc()->scopes()->nextToTop();
1894 // skip the scope pushed by service_dcl
1895 AstDeclaration * decl = scope->lookupByName(*$2);
1896 if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
1897 if (idlc()->error()->checkPublished(decl)) {
1898 idlc()->scopes()->top()->addDeclaration(decl);
1900 } else {
1901 idlc()->error()->lookupError(
1902 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
1904 delete $2;
1906 opt_service_body
1908 AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
1909 if (s != 0) {
1910 s->setSingleInterfaceBasedService();
1911 s->setDefaultConstructor(!$4);
1916 opt_service_body:
1917 service_body { $$ = true; }
1918 | /* empty */ { $$ = false; }
1921 service_body:
1923 constructors
1927 constructors:
1928 constructors constructor
1929 | /* empty */
1932 constructor:
1933 identifier
1935 checkIdentifier($1);
1936 AstScope * scope = idlc()->scopes()->top();
1937 AstOperation * ctor = new AstOperation(0, *$1, scope);
1938 delete $1;
1939 scope->addDeclaration(ctor);
1940 idlc()->scopes()->push(ctor);
1943 parameters
1945 opt_raises
1947 static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions(
1948 $6);
1949 delete $6;
1950 idlc()->scopes()->pop();
1951 if (static_cast< AstService * >(idlc()->scopes()->top())->
1952 checkLastConstructor())
1954 idlc()->error()->error0(EIDL_SIMILAR_CONSTRUCTORS);
1960 singleton_dcl :
1961 IDL_SINGLETON
1963 idlc()->setParseState(PS_SingletonSeen);
1965 identifier
1967 idlc()->setParseState(PS_SingletonIDSeen);
1968 checkIdentifier($3);
1970 AstScope* pScope = idlc()->scopes()->topNonNull();
1971 AstService* pService = NULL;
1974 * Make a new service and add it to the enclosing scope
1976 if (pScope != NULL)
1978 pService = new AstService(NT_singleton, *$3, pScope);
1979 pScope->addDeclaration(pService);
1981 delete $3;
1983 * Push it on the stack
1985 idlc()->scopes()->push(pService);
1987 singleton_dfn
1989 /* this singelton is finished, pop its scope from the stack */
1990 idlc()->scopes()->pop();
1994 singleton_dfn:
1995 singleton_interface_dfn
1996 | service_obsolete_dfn
1999 singleton_interface_dfn:
2000 ':' scoped_name
2002 AstScope * scope = idlc()->scopes()->nextToTop();
2003 // skip the scope (needlessly) pushed by singleton_dcl
2004 AstDeclaration * decl = scope->lookupByName(*$2);
2005 if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
2006 if (idlc()->error()->checkPublished(decl)) {
2007 idlc()->scopes()->top()->addDeclaration(decl);
2009 } else {
2010 idlc()->error()->lookupError(
2011 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
2013 delete $2;
2017 service_obsolete_dfn:
2020 idlc()->setParseState(
2021 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2022 ? PS_ServiceSqSeen : PS_SingletonSqSeen);
2024 service_exports
2026 idlc()->setParseState(
2027 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2028 ? PS_ServiceBodySeen : PS_SingletonBodySeen);
2032 idlc()->setParseState(
2033 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2034 ? PS_ServiceQsSeen : PS_SingletonQsSeen);
2038 type_dcl :
2039 IDL_TYPEDEF
2041 idlc()->setParseState(PS_TypedefSeen);
2043 type_declarator {}
2044 | struct_type {}
2045 | union_type {}
2046 | enum_type {}
2049 type_declarator :
2050 type_spec
2052 idlc()->setParseState(PS_TypeSpecSeen);
2053 if ($1 != 0 && $1->getNodeType() == NT_instantiated_struct) {
2054 idlc()->error()->error0(EIDL_INSTANTIATED_STRUCT_TYPE_TYPEDEF);
2057 at_least_one_declarator
2059 idlc()->setParseState(PS_DeclaratorsSeen);
2061 AstScope* pScope = idlc()->scopes()->topNonNull();
2062 AstTypeDef* pTypeDef = NULL;
2063 FeDeclList* pList = $3;
2064 FeDeclarator* pDecl = NULL;
2065 AstType const * pType = NULL;
2068 * Create nodes representing typedefs and add them to the
2069 * enclosing scope
2071 if ( pScope && $1 && pList )
2073 FeDeclList::iterator iter = pList->begin();
2074 FeDeclList::iterator end = pList->end();
2076 while (iter != end)
2078 pDecl = (*iter);
2079 if ( !pDecl )
2081 iter++;
2082 continue;
2085 pType = pDecl->compose($1);
2087 if ( !pType )
2089 iter++;
2090 continue;
2093 pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);
2095 pScope->addDeclaration(pTypeDef);
2096 iter++;
2097 delete pDecl;
2099 delete pList;
2104 at_least_one_declarator :
2105 declarator declarators
2107 if ( $2 )
2109 $2->push_back($1);
2110 $$ = $2;
2111 } else
2113 FeDeclList* pList = new FeDeclList();
2114 pList->push_back($1);
2115 $$ = pList;
2120 declarators :
2121 declarators
2124 idlc()->setParseState(PS_DeclsCommaSeen);
2126 declarator
2128 idlc()->setParseState(PS_DeclsDeclSeen);
2129 if ( $1 )
2131 $1->push_back($4);
2132 $$ = $1;
2133 } else
2135 FeDeclList* pList = new FeDeclList();
2136 pList->push_back($4);
2137 $$ = pList;
2140 | /* EMPTY */
2142 $$ = NULL;
2146 declarator :
2147 simple_declarator
2148 | complex_declarator
2151 simple_declarator :
2152 identifier
2154 // For historic reasons, the struct com.sun.star.uno.Uik contains
2155 // members with illegal names (of the form "m_DataN"); avoid useless
2156 // warnings about them:
2157 AstScope * scope = idlc()->scopes()->top();
2158 if (scope == 0 || scope->getScopeNodeType() != NT_struct
2159 || (scopeAsDecl(scope)->getScopedName()
2160 != "com::sun::star::uno::Uik"))
2162 checkIdentifier($1);
2165 $$ = new FeDeclarator(*$1, FeDeclarator::FD_simple, NULL);
2166 delete $1;
2170 complex_declarator :
2171 array_declarator
2173 $$ = new FeDeclarator($1->getLocalName(), FeDeclarator::FD_complex, $1);
2177 array_declarator :
2178 identifier
2180 idlc()->setParseState(PS_ArrayIDSeen);
2181 checkIdentifier($1);
2183 at_least_one_array_dim
2185 idlc()->setParseState(PS_ArrayCompleted);
2186 $$ = new AstArray(*$1, NULL, *$3, idlc()->scopes()->bottom());
2187 delete $1;
2191 at_least_one_array_dim :
2192 array_dim array_dims
2194 if( $2 )
2196 $2->push_front($1);
2197 $$ = $2;
2198 } else
2200 ExprList* pList = new ExprList();
2201 pList->push_back($1);
2202 $$ = pList;
2207 array_dims :
2208 array_dims array_dim
2210 if( $1 )
2212 $1->push_back($2);
2213 $$ = $1;
2214 } else
2216 ExprList* pList = new ExprList();
2217 pList->push_back($2);
2218 $$ = pList;
2221 | /* EMPTY */
2223 $$ = NULL;
2227 array_dim :
2230 idlc()->setParseState(PS_DimSqSeen);
2232 positive_int_expr
2234 idlc()->setParseState(PS_DimExprSeen);
2238 idlc()->setParseState(PS_DimQsSeen);
2240 * Array dimensions are expressions which must be coerced to
2241 * positive integers
2243 if ( !$3 || !$3->coerce(ET_uhyper) )
2245 idlc()->error()->coercionError($3, ET_uhyper);
2246 $$ = NULL;
2247 } else
2248 $$ = $3;
2252 at_least_one_scoped_name :
2253 scoped_name scoped_names
2255 if ($2)
2257 $2->push_front(*$1);
2258 $$ = $2;
2259 } else
2261 StringList* pNames = new StringList();
2262 pNames->push_back(*$1);
2263 $$ = pNames;
2265 delete($1);
2269 scoped_names :
2270 scoped_names
2273 idlc()->setParseState(PS_SNListCommaSeen);
2275 scoped_name
2277 idlc()->setParseState(PS_ScopedNameSeen);
2278 if ($1)
2280 $1->push_back(*$4);
2281 $$ = $1;
2282 } else
2284 StringList* pNames = new StringList();
2285 pNames->push_back(*$4);
2286 $$ = pNames;
2288 delete($4);
2290 | /* EMPTY */
2292 $$ = NULL;
2296 scoped_name :
2297 identifier
2299 idlc()->setParseState(PS_SN_IDSeen);
2300 checkIdentifier($1);
2301 $$ = $1;
2303 | IDL_SCOPESEPARATOR
2305 idlc()->setParseState(PS_ScopeDelimSeen);
2307 identifier
2309 checkIdentifier($3);
2310 OString* pName = new OString("::");
2311 *pName += *$3;
2312 delete $3;
2313 $$ = pName;
2315 | scoped_name
2316 IDL_SCOPESEPARATOR
2319 identifier
2321 checkIdentifier($4);
2322 *$1 += ::rtl::OString("::");
2323 *$1 += *$4;
2324 delete $4;
2325 $$ = $1;
2329 type_spec :
2330 simple_type_spec
2331 | constructed_type_spec
2334 simple_type_spec :
2335 fundamental_type
2336 | scoped_name opt_type_args
2338 $$ = createNamedType($1, $2);
2342 fundamental_type:
2343 base_type_spec
2345 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2347 | template_type_spec
2350 opt_type_args:
2351 '<' type_args '>' { $$ = $2; }
2352 | /* empty */ { $$ = 0; }
2355 type_args:
2356 type_arg
2358 $$ = new DeclList;
2359 $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
2361 | type_args ',' type_arg
2363 $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
2364 $$ = $1;
2368 type_arg:
2369 simple_type_spec
2371 if ($1 != 0 && static_cast< AstType const * >($1)->isUnsigned()) {
2372 idlc()->error()->error0(EIDL_UNSIGNED_TYPE_ARGUMENT);
2374 $$ = $1;
2378 base_type_spec :
2379 integer_type
2380 | floating_pt_type
2381 | char_type
2382 | boolean_type
2383 | byte_type
2384 | any_type
2385 | type_type
2386 | string_type
2389 integer_type :
2390 signed_int
2391 | unsigned_int
2394 signed_int :
2395 IDL_LONG
2397 $$ = ET_long;
2399 | IDL_HYPER
2401 $$ = ET_hyper;
2403 | IDL_SHORT
2405 $$ = ET_short;
2409 unsigned_int :
2410 IDL_UNSIGNED IDL_LONG
2412 $$ = ET_ulong;
2414 | IDL_UNSIGNED IDL_HYPER
2416 $$ = ET_uhyper;
2418 | IDL_UNSIGNED IDL_SHORT
2420 $$ = ET_ushort;
2424 floating_pt_type :
2425 IDL_DOUBLE
2427 $$ = ET_double;
2429 | IDL_FLOAT
2431 $$ = ET_float;
2435 char_type :
2436 IDL_CHAR
2438 $$ = ET_char;
2442 byte_type :
2443 IDL_BYTE
2445 $$ = ET_byte;
2449 boolean_type :
2450 IDL_BOOLEAN
2452 $$ = ET_boolean;
2456 any_type :
2457 IDL_ANY
2459 $$ = ET_any;
2463 type_type :
2464 IDL_TYPE
2466 $$ = ET_type;
2470 string_type :
2471 IDL_STRING
2473 $$ = ET_string;
2477 template_type_spec :
2478 sequence_type_spec
2479 | array_type
2482 constructed_type_spec :
2483 struct_type
2484 | union_type
2485 | enum_type
2488 array_type :
2489 simple_type_spec
2491 idlc()->setParseState(PS_ArrayTypeSeen);
2493 at_least_one_array_dim
2495 idlc()->setParseState(PS_ArrayCompleted);
2497 AstScope* pScope = idlc()->scopes()->bottom();
2498 AstDeclaration* pDecl = NULL;
2499 AstDeclaration* pArray = NULL;
2501 if ( $1 )
2503 pArray = new AstArray((AstType*)$1, *$3, idlc()->scopes()->bottom());
2504 if ( pScope )
2506 pDecl = pScope->addDeclaration(pArray);
2507 if ( pArray != pDecl )
2509 // if array type already defined then use it
2510 delete pArray;
2511 pArray = pDecl;
2515 $$ = pArray;
2519 sequence_type_spec :
2520 IDL_SEQUENCE
2522 idlc()->setParseState(PS_SequenceSeen);
2524 * Push a sequence marker on scopes stack
2526 idlc()->scopes()->push(NULL);
2530 idlc()->setParseState(PS_SequenceSqSeen);
2532 simple_type_spec
2534 idlc()->setParseState(PS_SequenceTypeSeen);
2538 idlc()->setParseState(PS_SequenceQsSeen);
2540 * Remove sequence marker from scopes stack
2542 if (idlc()->scopes()->top() == NULL)
2543 idlc()->scopes()->pop();
2545 * Create a node representing a sequence
2547 AstScope* pScope = idlc()->scopes()->bottom();
2548 AstDeclaration* pDecl = NULL;
2549 AstDeclaration* pSeq = NULL;
2551 if ( $5 )
2553 AstType *pType = (AstType*)$5;
2554 if ( pType )
2556 pSeq = new AstSequence(pType, pScope);
2558 * Add this AstSequence to the types defined in the global scope
2560 pDecl = pScope->addDeclaration(pSeq);
2561 if ( pSeq != pDecl )
2563 // if sequence type already defined then use it
2564 delete pSeq;
2565 pSeq = pDecl;
2569 $$ = pSeq;
2571 | error '>'
2573 yyerror("sequence declaration");
2574 yyerrok;
2575 $$ = 0;
2579 struct_type :
2580 structure_header
2582 idlc()->setParseState(PS_StructHeaderSeen);
2584 AstScope* pScope = idlc()->scopes()->topNonNull();
2585 AstStruct* pStruct = NULL;
2587 if ( pScope )
2589 AstStruct* pBase= static_cast< AstStruct* >($1->getInherits());
2590 pStruct = new AstStruct(
2591 *$1->getName(), $1->getTypeParameters(), pBase, pScope);
2592 pScope->addDeclaration(pStruct);
2595 * Push the scope of the struct on the scopes stack
2597 idlc()->scopes()->push(pStruct);
2598 delete $1;
2602 idlc()->setParseState(PS_StructSqSeen);
2604 at_least_one_member
2606 idlc()->setParseState(PS_StructBodySeen);
2610 idlc()->setParseState(PS_StructQsSeen);
2611 /* this exception is finished, pop its scope from the stack */
2612 idlc()->scopes()->pop();
2616 structure_header :
2617 IDL_STRUCT
2619 idlc()->setParseState(PS_StructSeen);
2621 identifier
2623 idlc()->setParseState(PS_StructIDSeen);
2624 checkIdentifier($3);
2626 opt_type_params
2627 inheritance_spec
2629 idlc()->setParseState(PS_InheritSpecSeen);
2631 // Polymorphic struct type templates with base types would cause various
2632 // problems in language bindings, so forbid them here. For example,
2633 // GCC prior to version 3.4 fails with code like
2635 // struct Base { ... };
2636 // template< typename typeparam_T > struct Derived: public Base {
2637 // int member1 CPPU_GCC3_ALIGN(Base);
2638 // ... };
2640 // (Note that plain struct types with instantiated polymorphic struct
2641 // type bases, which might also cause problems in language bindings, are
2642 // already rejected on a syntactic level.)
2643 if ($5 != 0 && $6 != 0) {
2644 idlc()->error()->error0(EIDL_STRUCT_TYPE_TEMPLATE_WITH_BASE);
2647 $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
2648 delete $5;
2649 delete $6;
2653 opt_type_params:
2654 '<' type_params '>' { $$ = $2; }
2655 | /* empty */ { $$ = 0; }
2658 type_params:
2659 identifier
2661 $$ = new std::vector< rtl::OString >;
2662 $$->push_back(*$1);
2663 delete $1;
2665 | type_params ',' identifier
2667 if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
2668 idlc()->error()->error0(EIDL_IDENTICAL_TYPE_PARAMETERS);
2670 $1->push_back(*$3);
2671 delete $3;
2672 $$ = $1;
2676 at_least_one_member : member members ;
2678 members :
2679 members member
2680 | /* EMPTY */
2683 member :
2684 type_or_parameter
2686 idlc()->setParseState(PS_MemberTypeSeen);
2688 at_least_one_declarator
2690 idlc()->setParseState(PS_MemberDeclsSeen);
2694 idlc()->setParseState(PS_MemberDeclsCompleted);
2696 AstScope* pScope = idlc()->scopes()->topNonNull();
2697 AstMember* pMember = NULL;
2698 FeDeclList* pList = $3;
2699 FeDeclarator* pDecl = NULL;
2700 AstType const * pType = NULL;
2702 // !!! check recursive type
2704 if ( pScope && pList && $1 )
2706 FeDeclList::iterator iter = pList->begin();
2707 FeDeclList::iterator end = pList->end();
2708 while (iter != end)
2710 pDecl = (*iter);
2711 if ( !pDecl )
2713 iter++;
2714 continue;
2717 pType = pDecl->compose($1);
2719 if ( !pType )
2721 iter++;
2722 continue;
2725 pMember = new AstMember(pType, pDecl->getName(), pScope);
2727 if ( !pDecl->checkType($1) )
2729 // WARNING
2732 pScope->addDeclaration(pMember);
2733 iter++;
2734 delete pDecl;
2736 delete pList;
2739 | error ';'
2741 yyerror("member definition");
2742 yyerrok;
2746 type_or_parameter:
2747 fundamental_type
2748 | scoped_name opt_type_args
2750 AstDeclaration const * decl = 0;
2751 AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top());
2752 if (scope != 0 && $2 == 0) {
2753 decl = scope->findTypeParameter(*$1);
2755 if (decl != 0) {
2756 delete $1;
2757 delete $2;
2758 } else {
2759 decl = createNamedType($1, $2);
2760 if (scope != 0 && includes(decl, scopeAsDecl(scope))) {
2761 idlc()->error()->error1(
2762 EIDL_RECURSIVE_TYPE, scopeAsDecl(scope));
2763 decl = 0;
2766 $$ = decl;
2770 enum_type :
2771 IDL_ENUM
2773 idlc()->setParseState(PS_EnumSeen);
2775 identifier
2777 idlc()->setParseState(PS_EnumIDSeen);
2778 checkIdentifier($3);
2780 AstScope* pScope = idlc()->scopes()->topNonNull();
2781 AstEnum* pEnum = NULL;
2784 * Create a node representing an enum and add it to its
2785 * enclosing scope
2787 if (pScope != NULL)
2789 pEnum = new AstEnum(*$3, pScope);
2791 * Add it to its defining scope
2793 pScope->addDeclaration(pEnum);
2795 delete $3;
2797 * Push the enum scope on the scopes stack
2799 idlc()->scopes()->push(pEnum);
2804 idlc()->setParseState(PS_EnumSqSeen);
2806 at_least_one_enumerator
2808 idlc()->setParseState(PS_EnumBodySeen);
2812 idlc()->setParseState(PS_EnumQsSeen);
2814 * Done with this enum. Pop its scope from the scopes stack
2816 if (idlc()->scopes()->top() == NULL)
2817 $$ = NULL;
2818 else
2820 $$ = (AstEnum*)idlc()->scopes()->topNonNull();
2821 idlc()->scopes()->pop();
2826 at_least_one_enumerator : enumerator enumerators ;
2828 enumerators :
2829 enumerators
2832 idlc()->setParseState(PS_EnumCommaSeen);
2834 enumerator
2835 | /* EMPTY */
2836 | error ','
2838 yyerror("enumerator definition");
2839 yyerrok;
2843 enumerator :
2844 identifier
2846 checkIdentifier($1);
2848 AstScope* pScope = idlc()->scopes()->topNonNull();
2849 AstEnum* pEnum = NULL;
2850 AstConstant* pEnumVal = NULL;
2852 if ( pScope && pScope->getScopeNodeType() == NT_enum)
2854 pEnum = (AstEnum*)pScope;
2855 if (pEnum && $1)
2857 AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
2858 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2859 pExpr, *$1, pScope);
2861 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2862 idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2864 pScope->addDeclaration(pEnumVal);
2866 delete $1;
2868 | identifier
2870 const_expr
2872 checkIdentifier($1);
2874 AstScope* pScope = idlc()->scopes()->topNonNull();
2875 AstEnum* pEnum = NULL;
2876 AstConstant* pEnumVal = NULL;
2878 if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
2880 $3->evaluate(EK_const);
2881 if ( $3->coerce(ET_long) )
2883 pEnum = (AstEnum*)pScope;
2884 if (pEnum)
2886 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2887 $3, *$1, pScope);
2889 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2890 idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2892 pScope->addDeclaration(pEnumVal);
2893 } else
2895 idlc()->error()->coercionError($3, ET_long);
2896 delete $3;
2899 delete $1;
2903 union_type :
2904 IDL_UNION
2906 idlc()->setParseState(PS_UnionSeen);
2908 identifier
2910 idlc()->setParseState(PS_UnionIDSeen);
2911 checkIdentifier($3);
2913 IDL_SWITCH
2915 idlc()->setParseState(PS_SwitchSeen);
2919 idlc()->setParseState(PS_SwitchOpenParSeen);
2921 switch_type_spec
2923 idlc()->setParseState(PS_SwitchTypeSeen);
2927 idlc()->setParseState(PS_SwitchCloseParSeen);
2929 AstScope* pScope = idlc()->scopes()->topNonNull();
2930 AstUnion* pUnion = NULL;
2933 * Create a node representing a union. Add it to its enclosing
2934 * scope
2936 if ( $9 && pScope )
2938 AstType* pType = (AstType*)$9;
2939 if ( !pType)
2941 idlc()->error()->noTypeError($9);
2942 } else
2944 pUnion = new AstUnion(*$3, pType, pScope);
2945 pScope->addDeclaration(pUnion);
2948 delete $3;
2950 * Push the scope of the union on the scopes stack
2952 idlc()->scopes()->push(pUnion);
2956 idlc()->setParseState(PS_UnionSqSeen);
2958 at_least_one_case_branch
2960 idlc()->setParseState(PS_UnionBodySeen);
2964 idlc()->setParseState(PS_UnionQsSeen);
2965 /* this union is finished, pop its scope from the stack */
2966 idlc()->scopes()->pop();
2970 switch_type_spec :
2971 integer_type
2973 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2975 | char_type
2977 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2979 | boolean_type
2981 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2983 | enum_type
2984 | scoped_name
2986 AstScope* pScope = idlc()->scopes()->topNonNull();
2987 AstBaseType* pBaseType = NULL;
2988 AstDeclaration const * pDecl = NULL;
2989 AstTypeDef* pTypeDef = NULL;
2990 sal_Bool bFound = sal_False;
2992 * If the constant's type is a scoped name, it must resolve
2993 * to a scalar constant type
2995 if ( pScope && (pDecl = pScope->lookupByName(*$1)) )
2998 * Look through typedefs
3000 while ( !bFound )
3002 switch (pDecl->getNodeType())
3004 case NT_enum:
3005 $$ = pDecl;
3006 bFound = sal_True;
3007 break;
3008 case NT_predefined:
3009 pBaseType = (AstBaseType*)pDecl;
3010 if ( pBaseType )
3012 switch (pBaseType->getExprType())
3014 case ET_short:
3015 case ET_ushort:
3016 case ET_long:
3017 case ET_ulong:
3018 case ET_hyper:
3019 case ET_uhyper:
3020 case ET_char:
3021 case ET_byte:
3022 case ET_boolean:
3023 $$ = pBaseType;
3024 bFound = sal_True;
3025 break;
3026 default:
3027 $$ = NULL;
3028 bFound = sal_True;
3029 break;
3032 break;
3033 case NT_typedef:
3034 pTypeDef = (AstTypeDef*)pDecl;
3035 if ( pTypeDef )
3036 pDecl = pTypeDef->getBaseType();
3037 break;
3038 default:
3039 $$ = NULL;
3040 bFound = sal_True;
3041 break;
3044 } else
3045 $$ = NULL;
3047 if ($$ == NULL)
3048 idlc()->error()->lookupError(*$1);
3052 at_least_one_case_branch : case_branch case_branches ;
3054 case_branches :
3055 case_branches case_branch
3056 | /* EMPTY */
3059 case_branch :
3060 at_least_one_case_label
3062 idlc()->setParseState(PS_UnionLabelSeen);
3064 element_spec
3066 idlc()->setParseState(PS_UnionElemSeen);
3068 AstScope* pScope = idlc()->scopes()->topNonNull();
3069 AstUnionLabel* pLabel = NULL;
3070 AstUnionBranch* pBranch = NULL;
3071 AstMember* pMember = $3;
3074 * Create several nodes representing branches of a union.
3075 * Add them to the enclosing scope (the union scope)
3077 if ( pScope && $1 && $3 )
3079 LabelList::iterator iter = $1->begin();
3080 LabelList::iterator end = $1->end();
3081 for (;iter != end; iter++)
3083 pLabel = *iter;
3084 if ( !pLabel )
3086 iter++;
3087 continue;
3089 pBranch = new AstUnionBranch(pLabel, pMember->getType(),
3090 pMember->getLocalName(), pScope);
3091 pScope->addDeclaration(pBranch);
3094 if ( $1 ) delete($1);
3098 at_least_one_case_label :
3099 case_label case_labels
3101 if ( $2 )
3103 $2->push_front($1);
3104 $$ = $2;
3105 } else
3107 LabelList* pLabels = new LabelList();
3108 pLabels->push_back($1);
3109 $$ = pLabels;
3114 case_labels :
3115 case_labels case_label
3117 if ( $1 )
3119 $1->push_back($2);
3120 $$ = $1;
3121 } else
3123 LabelList* pLabels = new LabelList();
3124 pLabels->push_back($2);
3125 $$ = pLabels;
3128 | /* EMPTY */
3130 $$ = NULL;
3134 case_label :
3135 IDL_DEFAULT
3137 idlc()->setParseState(PS_DefaultSeen);
3141 idlc()->setParseState(PS_LabelColonSeen);
3142 $$ = new AstUnionLabel(UL_default, NULL);
3144 | IDL_CASE
3146 idlc()->setParseState(PS_CaseSeen);
3148 const_expr
3150 idlc()->setParseState(PS_LabelExprSeen);
3154 idlc()->setParseState(PS_LabelColonSeen);
3155 $$ = new AstUnionLabel(UL_label, $3);
3159 element_spec :
3160 type_spec
3162 idlc()->setParseState(PS_UnionElemTypeSeen);
3164 declarator
3166 idlc()->setParseState(PS_UnionElemDeclSeen);
3170 idlc()->setParseState(PS_UnionElemCompleted);
3172 AstScope* pScope = idlc()->scopes()->topNonNull();
3174 * Check for illegal recursive use of type
3176 // if ( $1 && AST_illegal_recursive_type($1))
3177 // idlc()->error()->error1(EIDL_RECURSIVE_TYPE, $1);
3179 * Create a field in a union branch
3181 if ( $1 && $3 )
3183 AstType const * pType = $3->compose($1);
3184 if ( !pType )
3185 $$ = NULL;
3186 else
3187 $$ = new AstMember(pType, $3->getName(), pScope);
3188 } else
3189 $$ = NULL;
3191 if ( $3 ) delete $3;
3193 | error
3196 $$ = NULL;
3200 identifier:
3201 IDL_IDENTIFIER
3202 | IDL_GET { $$ = new OString("get"); }
3203 | IDL_SET { $$ = new OString("set"); }
3204 | IDL_PUBLISHED { $$ = new OString("published"); }
3210 * Report an error situation discovered in a production
3212 void yyerror(char const *errmsg)
3214 idlc()->error()->syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
3215 idlc()->setParseState(PS_NoState);