Update ooo320-m1
[ooovba.git] / idlc / source / parser.y
blob51df5943ea7265a5d5283a8e293c5b09673c6ec3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: parser.y,v $
10 * $Revision: 1.18.10.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 * parser.yy - BISON grammar for IDLC 1.0
36 #include <string.h>
38 #ifndef _IDLC_IDLC_HXX_
39 #include <idlc/idlc.hxx>
40 #endif
41 #ifndef _IDLC_ERRORHANDLER_HXX_
42 #include <idlc/errorhandler.hxx>
43 #endif
44 #ifndef _IDLC_FEHELPER_HXX_
45 #include <idlc/fehelper.hxx>
46 #endif
47 #ifndef _IDLC_EXPRESSION_HXX_
48 #include <idlc/astexpression.hxx>
49 #endif
50 #ifndef _IDLC_ASTCONSTANTS_HXX_
51 #include <idlc/astconstants.hxx>
52 #endif
53 #ifndef _IDLC_ASTCONSTANT_HXX_
54 #include <idlc/astconstant.hxx>
55 #endif
56 #ifndef _IDLC_ASTARRAY_HXX_
57 #include <idlc/astarray.hxx>
58 #endif
59 #ifndef _IDLC_ASTBASETYPE_HXX_
60 #include <idlc/astbasetype.hxx>
61 #endif
62 #ifndef _IDLC_ASTTYPEDEF_HXX_
63 #include <idlc/asttypedef.hxx>
64 #endif
65 #ifndef _IDLC_ASTEXCEPTION_HXX_
66 #include <idlc/astexception.hxx>
67 #endif
68 #ifndef _IDLC_ASTMEMBER_HXX_
69 #include <idlc/astmember.hxx>
70 #endif
71 #ifndef _IDLC_ASTENUM_HXX_
72 #include <idlc/astenum.hxx>
73 #endif
74 #ifndef _IDLC_ASTSEQUENCE_HXX_
75 #include <idlc/astsequence.hxx>
76 #endif
77 #ifndef _IDLC_ASTATTRIBUTE_HXX_
78 #include <idlc/astattribute.hxx>
79 #endif
80 #ifndef _IDLC_ASTOPERATION_HXX_
81 #include <idlc/astoperation.hxx>
82 #endif
83 #ifndef _IDLC_ASTPARAMETER_HXX_
84 #include <idlc/astparameter.hxx>
85 #endif
86 #ifndef _IDLC_ASTINTERFACEMEMBER_HXX_
87 #include <idlc/astinterfacemember.hxx>
88 #endif
89 #ifndef _IDLC_ASTSERVICEMEMBER_HXX_
90 #include <idlc/astservicemember.hxx>
91 #endif
92 #ifndef _IDLC_ASTOBSERVES_HXX_
93 #include <idlc/astobserves.hxx>
94 #endif
95 #ifndef _IDLC_ASTNEEDS_HXX_
96 #include <idlc/astneeds.hxx>
97 #endif
98 #ifndef _IDLC_ASTUNION_HXX_
99 #include <idlc/astunion.hxx>
100 #endif
101 #include "idlc/aststructinstance.hxx"
103 #include "attributeexceptions.hxx"
105 #include "rtl/strbuf.hxx"
107 #include <algorithm>
108 #include <vector>
110 using namespace ::rtl;
112 #define YYDEBUG 1
113 #define YYERROR_VERBOSE 1
115 extern int yylex(void);
116 void yyerror(char const *);
118 void checkIdentifier(::rtl::OString* id)
120 static short check = 0;
121 if (check == 0) {
122 if (idlc()->getOptions()->isValid("-cid"))
123 check = 1;
124 else
125 check = 2;
128 if ( id->indexOf('_') >= 0 )
129 if ( (id->pData->buffer[0] >= 97 && id->pData->buffer[0] <= 122)
130 || id->pData->buffer[0] == '_') {
131 if (check == 1) {
132 ::rtl::OStringBuffer msg(25 + id->getLength());
133 msg.append("mismatched identifier '");
134 msg.append(*id);
135 msg.append("'");
136 idlc()->error()->syntaxError(idlc()->getParseState(),
137 idlc()->getLineNumber(),
138 msg.getStr());
140 else
141 idlc()->error()->warning0(WIDL_WRONG_NAMING_CONV, id->getStr());
145 void reportDoubleMemberDeclarations(
146 AstInterface::DoubleMemberDeclarations const & doubleMembers)
148 for (AstInterface::DoubleMemberDeclarations::const_iterator i(
149 doubleMembers.begin());
150 i != doubleMembers.end(); ++i)
152 idlc()->error()->error2(EIDL_DOUBLE_MEMBER, i->first, i->second);
156 void addInheritedInterface(
157 AstInterface * ifc, rtl::OString const & name, bool optional,
158 rtl::OUString const & documentation)
160 AstDeclaration * decl = ifc->lookupByName(name);
161 AstDeclaration const * resolved = resolveTypedefs(decl);
162 if (resolved != 0 && resolved->getNodeType() == NT_interface) {
163 if (idlc()->error()->checkPublished(decl)) {
164 if (!static_cast< AstInterface const * >(resolved)->isDefined()) {
165 idlc()->error()->inheritanceError(
166 NT_interface, &ifc->getScopedName(), decl);
167 } else {
168 AstInterface::DoubleDeclarations doubleDecls(
169 ifc->checkInheritedInterfaceClashes(
170 static_cast< AstInterface const * >(resolved),
171 optional));
172 if (doubleDecls.interfaces.empty()
173 && doubleDecls.members.empty())
175 ifc->addInheritedInterface(
176 static_cast< AstType * >(decl), optional,
177 documentation);
178 } else {
179 for (AstInterface::DoubleInterfaceDeclarations::iterator i(
180 doubleDecls.interfaces.begin());
181 i != doubleDecls.interfaces.end(); ++i)
183 idlc()->error()->error1(
184 EIDL_DOUBLE_INHERITANCE, *i);
186 reportDoubleMemberDeclarations(doubleDecls.members);
190 } else {
191 idlc()->error()->lookupError(
192 EIDL_INTERFACEMEMBER_LOOKUP, name, scopeAsDecl(ifc));
196 AstDeclaration const * createNamedType(
197 rtl::OString const * scopedName, DeclList const * typeArgs)
199 AstDeclaration * decl = idlc()->scopes()->topNonNull()->lookupByName(
200 *scopedName);
201 AstDeclaration const * resolved = resolveTypedefs(decl);
202 if (decl == 0) {
203 idlc()->error()->lookupError(*scopedName);
204 } else if (!idlc()->error()->checkPublished(decl)) {
205 decl = 0;
206 } else if (resolved->getNodeType() == NT_struct) {
207 if (static_cast< AstStruct const * >(resolved)->getTypeParameterCount()
208 != (typeArgs == 0 ? 0 : typeArgs->size()))
210 idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
211 decl = 0;
212 } else if (typeArgs != 0) {
213 AstScope * global = idlc()->scopes()->bottom();
214 AstDeclaration * inst = new AstStructInstance(
215 static_cast< AstType * >(decl), typeArgs, global);
216 decl = global->addDeclaration(inst);
217 if (decl != inst) {
218 delete inst;
221 } else if (decl->isType()) {
222 if (typeArgs != 0) {
223 idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
224 decl = 0;
226 } else {
227 idlc()->error()->noTypeError(decl);
228 decl = 0;
230 delete scopedName;
231 delete typeArgs;
232 return decl;
235 bool includes(AstDeclaration const * type1, AstDeclaration const * type2) {
236 OSL_ASSERT(type2 != 0);
237 if (type1 != 0) {
238 if (type1->getNodeType() == NT_instantiated_struct) {
239 AstStructInstance const * inst
240 = static_cast< AstStructInstance const * >(type1);
241 if (inst->getTypeTemplate() == type2) {
242 return true;
244 for (DeclList::const_iterator i(inst->getTypeArgumentsBegin());
245 i != inst->getTypeArgumentsEnd(); ++i)
247 if (includes(*i, type2)) {
248 return true;
251 } else if (type1 == type2) {
252 return true;
255 return false;
258 // Suppress any warnings from generated code:
259 #if defined __GNUC__
260 #pragma GCC system_header
261 #elif defined __SUNPRO_CC
262 #pragma disable_warn
263 #elif defined _MSC_VER
264 #pragma warning(push, 1)
265 #pragma warning(disable: 4273 4701 4706)
266 #endif
269 * Declare the type of values in the grammar
271 %union {
272 ExprType etval; /* Expression type */
273 AstDeclaration* dclval; /* Declaration */
274 AstDeclaration const * cdclval;
275 DeclList * dclsval;
276 AstExpression* exval; /* expression value */
277 ExprList* exlval; /* expression list value */
278 FeDeclarator* fdval; /* declarator value */
279 FeDeclList* dlval; /* declarator list value */
280 FeInheritanceHeader* ihval; /* inheritance header value */
281 ::rtl::OString* sval; /* OString value */
282 std::vector< rtl::OString > * svals;
283 sal_Char* strval; /* sal_Char* value */
284 sal_Bool bval; /* sal_Boolean* value */
285 sal_Int64 ival; /* sal_Int64 value */
286 sal_uInt64 uval; /* sal_uInt64 value */
287 sal_uInt32 ulval; /* sal_uInt32 value */
288 double dval; /* double value */
289 float fval; /* float value */
290 StringList* slval; /* StringList value */
291 LabelList* llval; /* LabelList value */
292 AstUnionLabel* lbval; /* union label value */
293 AstMember* mval; /* member value */
294 AttributeExceptions::Part attexcpval;
295 AttributeExceptions attexcval;
299 * Token types: These are returned by the lexer
302 %token <sval> IDL_IDENTIFIER
303 %token IDL_ATTRIBUTE
304 %token IDL_BOUND
305 %token IDL_CASE
306 %token IDL_CONST
307 %token IDL_CONSTANTS
308 %token IDL_CONSTRAINED
309 %token IDL_DEFAULT
310 %token IDL_ENUM
311 %token IDL_EXCEPTION
312 %token IDL_INTERFACE
313 %token IDL_MAYBEAMBIGUOUS
314 %token IDL_MAYBEDEFAULT
315 %token IDL_MAYBEVOID
316 %token IDL_MODULE
317 %token IDL_NEEDS
318 %token IDL_OBSERVES
319 %token IDL_OPTIONAL
320 %token IDL_PROPERTY
321 %token IDL_RAISES
322 %token IDL_READONLY
323 %token IDL_REMOVEABLE
324 %token IDL_SERVICE
325 %token IDL_SEQUENCE
326 %token IDL_SINGLETON
327 %token IDL_STRUCT
328 %token IDL_SWITCH
329 %token IDL_TYPEDEF
330 %token IDL_TRANSIENT
331 %token IDL_UNION
333 %token IDL_ANY
334 %token IDL_CHAR
335 %token IDL_BOOLEAN
336 %token IDL_BYTE
337 %token IDL_DOUBLE
338 %token IDL_FLOAT
339 %token IDL_HYPER
340 %token IDL_LONG
341 %token IDL_SHORT
342 %token IDL_VOID
343 %token IDL_STRING
344 %token IDL_TYPE
345 %token IDL_UNSIGNED
347 %token IDL_TRUE
348 %token IDL_FALSE
350 %token IDL_IN
351 %token IDL_OUT
352 %token IDL_INOUT
353 %token IDL_ONEWAY
355 %token IDL_GET
356 %token IDL_SET
358 %token IDL_PUBLISHED
360 %token IDL_ELLIPSIS
362 %token <strval> IDL_LEFTSHIFT
363 %token <strval> IDL_RIGHTSHIFT
364 %token <strval> IDL_SCOPESEPARATOR
366 %token <ival> IDL_INTEGER_LITERAL
367 %token <uval> IDL_INTEGER_ULITERAL
368 %token <dval> IDL_FLOATING_PT_LITERAL
371 * These are production names:
373 %type <dclval> type_dcl const_dcl
374 %type <dclval> array_declarator
375 %type <dclval> exception_name
376 %type <cdclval> array_type constructed_type_spec enum_type op_type_spec
377 %type <cdclval> sequence_type_spec simple_type_spec struct_type switch_type_spec
378 %type <cdclval> template_type_spec type_spec union_type
379 %type <cdclval> fundamental_type type_arg type_or_parameter
380 %type <dclsval> opt_raises raises exception_list
381 %type <attexcpval> opt_attribute_get_raises attribute_get_raises
382 %type <attexcpval> opt_attribute_set_raises attribute_set_raises
383 %type <dclsval> opt_type_args type_args
385 %type <sval> identifier
386 %type <sval> interface_decl
387 %type <sval> scoped_name inheritance_spec
388 %type <slval> scoped_names at_least_one_scoped_name
390 %type <etval> const_type integer_type char_type boolean_type
391 %type <etval> floating_pt_type any_type signed_int string_type
392 %type <etval> unsigned_int base_type_spec byte_type type_type
394 %type <exval> expression const_expr or_expr xor_expr and_expr
395 %type <exval> add_expr mult_expr unary_expr primary_expr shift_expr
396 %type <exval> literal positive_int_expr array_dim
398 %type <exlval> at_least_one_array_dim array_dims
400 %type <fdval> declarator simple_declarator complex_declarator
401 %type <dlval> declarators at_least_one_declarator
403 %type <ihval> exception_header structure_header interfaceheader
405 %type <ulval> flag_header opt_attrflags opt_attrflag operation_head
406 %type <ulval> direction service_interface_header service_service_header
408 %type <llval> case_labels at_least_one_case_label
409 %type <lbval> case_label
410 %type <mval> element_spec
412 %type <bval> optional_inherited_interface opt_rest opt_service_body
414 %type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises
416 %type <svals> opt_type_params type_params
420 * Grammar start here
422 start : definitions;
424 definitions :
425 definition definitions
426 | /* EMPTY */
429 definition :
430 opt_published publishable_definition
431 | module_dcl
433 idlc()->setParseState(PS_ModuleDeclSeen);
437 idlc()->setParseState(PS_NoState);
439 | error ';'
441 yyerror("definitions");
442 yyerrok;
446 opt_published:
447 IDL_PUBLISHED { idlc()->setPublished(true); }
448 | /* empty */ { idlc()->setPublished(false); }
451 publishable_definition:
452 type_dcl
454 idlc()->setParseState(PS_TypeDeclSeen);
458 idlc()->setParseState(PS_NoState);
460 | const_dcl
462 idlc()->setParseState(PS_ConstantDeclSeen);
466 idlc()->setParseState(PS_NoState);
468 | exception_dcl
470 idlc()->setParseState(PS_ExceptionDeclSeen);
474 idlc()->setParseState(PS_NoState);
476 | interface
478 idlc()->setParseState(PS_InterfaceDeclSeen);
482 idlc()->setParseState(PS_NoState);
484 | service_dcl
486 idlc()->setParseState(PS_ServiceDeclSeen);
490 idlc()->setParseState(PS_NoState);
492 | singleton_dcl
494 idlc()->setParseState(PS_SingletonDeclSeen);
498 idlc()->setParseState(PS_NoState);
500 | constants_dcl
502 idlc()->setParseState(PS_ConstantsDeclSeen);
506 idlc()->setParseState(PS_NoState);
510 module_dcl :
511 IDL_MODULE
513 idlc()->setParseState(PS_ModuleSeen);
514 idlc()->setPublished(false);
516 identifier
518 idlc()->setParseState(PS_ModuleIDSeen);
519 checkIdentifier($3);
521 AstScope* pScope = idlc()->scopes()->topNonNull();
522 AstModule* pModule = NULL;
523 AstDeclaration* pExists = NULL;
525 if ( pScope )
527 pModule = new AstModule(*$3, pScope);
528 if( (pExists = pScope->lookupForAdd(pModule)) )
530 pExists->setInMainfile(idlc()->isInMainFile());
531 pExists->setFileName(pModule->getFileName());
532 if (pExists->isPredefined())
534 pExists->setPredefined(false);
535 if (pExists->getDocumentation().getLength() == 0 &&
536 pModule->getDocumentation().getLength() > 0)
538 pExists->setDocumentation(pModule->getDocumentation());
541 delete(pModule);
542 pModule = (AstModule*)pExists;
543 } else
545 pScope->addDeclaration(pModule);
547 idlc()->scopes()->push(pModule);
549 delete $3;
553 idlc()->setParseState(PS_ModuleSqSeen);
555 definitions
557 idlc()->setParseState(PS_ModuleBodySeen);
561 idlc()->setParseState(PS_ModuleQsSeen);
563 * Finished with this module - pop it from the scope stack
565 idlc()->scopes()->pop();
569 interface :
570 interface_dcl
571 | forward_dcl
574 interface_decl :
575 IDL_INTERFACE
577 idlc()->setParseState(PS_InterfaceSeen);
579 identifier
581 idlc()->setParseState(PS_InterfaceIDSeen);
582 checkIdentifier($3);
583 $$ = $3;
587 forward_dcl :
588 interface_decl
590 idlc()->setParseState(PS_ForwardDeclSeen);
592 AstScope* pScope = idlc()->scopes()->topNonNull();
593 AstInterface* pForward = NULL;
594 AstDeclaration* pDecl = NULL;
597 * Make a new forward interface node and add it to its enclosing scope
599 if ( pScope && $1 )
601 pForward = new AstInterface(*$1, NULL, pScope);
603 if ( pDecl = pScope->lookupByName(pForward->getScopedName()) )
605 if ( (pDecl != pForward) &&
606 (pDecl->getNodeType() == NT_interface) )
608 delete pForward;
609 } else
611 idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(pScope), pDecl);
613 } else
616 * Add the interface to its definition scope
618 pScope->addDeclaration(pForward);
621 delete $1;
625 interface_dcl :
626 interfaceheader
628 idlc()->setParseState(PS_InterfaceHeadSeen);
630 AstScope* pScope = idlc()->scopes()->topNonNull();
631 AstInterface* pInterface = NULL;
632 AstInterface* pForward = NULL;
633 AstDeclaration* pDecl = NULL;
636 * Make a new interface node and add it to its enclosing scope
638 if ( pScope && $1 )
640 pInterface = new AstInterface(
641 *$1->getName(),
642 static_cast< AstInterface * >($1->getInherits()), pScope);
643 if ( pInterface &&
644 (pDecl = pScope->lookupByName(pInterface->getScopedName())) )
647 * See if we're defining a forward declared interface.
649 if (pDecl->getNodeType() == NT_interface)
651 pForward = (AstInterface*)pDecl;
652 if ( !pForward->isDefined() )
655 * Check if redefining in same scope
657 if ( pForward->getScope() != pScope )
659 if ( pForward->getScopedName() != pInterface->getScopedName() )
661 idlc()->error()->error3(EIDL_SCOPE_CONFLICT,
662 pInterface, pForward, scopeAsDecl(pScope));
665 else if ( !pInterface->isPublished()
666 && pForward->isPublished() )
668 idlc()->error()->error0(EIDL_PUBLISHED_FORWARD);
671 * All OK, set full definition
673 else
675 pForward->forwardDefined(*pInterface);
676 delete pInterface;
677 pInterface = pForward;
679 } else {
680 // special handling for XInterface because it is predefined
681 if ( pForward->isPredefined() &&
682 pForward->getScopedName() == "com::sun::star::uno::XInterface")
684 /* replace the predefined XInterface */
685 *pForward = *pInterface;
686 delete pInterface;
687 pInterface = pForward;
692 } else
695 * Add the interface to its definition scope
697 pScope->addDeclaration(pInterface);
701 * Push it on the scope stack
703 idlc()->scopes()->push(pInterface);
704 delete($1);
708 idlc()->setParseState(PS_InterfaceSqSeen);
710 exports
712 AstInterface * ifc = static_cast< AstInterface * >(
713 idlc()->scopes()->topNonNull());
714 if (!ifc->hasMandatoryInheritedInterfaces()
715 && ifc->getScopedName() != "com::sun::star::uno::XInterface")
717 addInheritedInterface(
718 ifc, rtl::OString("::com::sun::star::uno::XInterface"), false,
719 rtl::OUString());
721 ifc->setDefined();
722 idlc()->setParseState(PS_InterfaceBodySeen);
726 idlc()->setParseState(PS_InterfaceQsSeen);
728 * Done with this interface - pop it off the scopes stack
730 idlc()->scopes()->pop();
732 | error '}'
734 yyerror("interface definition");
735 yyerrok;
739 interfaceheader :
740 interface_decl inheritance_spec
742 idlc()->setParseState(PS_InheritSpecSeen);
744 $$ = new FeInheritanceHeader(NT_interface, $1, $2, 0);
745 delete $2;
749 inheritance_spec :
752 idlc()->setParseState(PS_InheritColonSeen);
754 scoped_name
756 $$ = $3;
758 | /* EMPTY */
760 $$ = NULL;
764 exports :
765 exports export
766 | /* EMPTY */
769 export :
770 attribute
772 idlc()->setParseState(PS_AttributeDeclSeen);
776 idlc()->setParseState(PS_NoState);
778 | operation
780 idlc()->setParseState(PS_OperationDeclSeen);
784 idlc()->setParseState(PS_NoState);
786 | interface_inheritance_decl
788 idlc()->setParseState(PS_InterfaceInheritanceDeclSeen);
792 idlc()->setParseState(PS_NoState);
796 attribute :
797 flag_header
798 simple_type_spec
800 idlc()->setParseState(PS_AttrTypeSeen);
802 simple_declarator
804 idlc()->setParseState(PS_AttrCompleted);
805 if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) {
806 idlc()->error()->flagError(EIDL_BAD_ATTRIBUTE_FLAGS, $1);
808 AstInterface * scope = static_cast< AstInterface * >(
809 idlc()->scopes()->top());
810 AstAttribute * attr = new AstAttribute(
811 $1, $4->compose($2), $4->getName(), scope);
812 delete $4;
813 AstInterface::DoubleMemberDeclarations doubleMembers(
814 scope->checkMemberClashes(attr));
815 if (doubleMembers.empty()) {
816 scope->addMember(attr);
817 } else {
818 reportDoubleMemberDeclarations(doubleMembers);
820 idlc()->scopes()->push(attr);
822 opt_attribute_block
824 static_cast< AstAttribute * >(idlc()->scopes()->top())->setExceptions(
825 $6.get.documentation, $6.get.exceptions, $6.set.documentation,
826 $6.set.exceptions);
827 delete $6.get.documentation;
828 delete $6.get.exceptions;
829 delete $6.set.documentation;
830 delete $6.set.exceptions;
831 idlc()->scopes()->pop();
835 flag_header :
836 '[' opt_attrflags ']'
838 idlc()->setParseState(PS_FlagHeaderSeen);
839 $$ = $2;
843 opt_attrflags :
844 opt_attrflags ',' opt_attrflag
846 if ( ($1 & $3) == $3 )
847 idlc()->error()->flagError(EIDL_DEFINED_ATTRIBUTEFLAG, $3);
849 $$ = $1 | $3;
851 | opt_attrflag
853 $$ = $1;
857 opt_attrflag :
858 IDL_ATTRIBUTE
860 idlc()->setParseState(PS_AttrSeen);
861 $$ = AF_ATTRIBUTE;
863 | IDL_PROPERTY
865 idlc()->setParseState(PS_PropertySeen);
866 $$ = AF_PROPERTY;
868 | IDL_READONLY
870 idlc()->setParseState(PS_ReadOnlySeen);
871 $$ = AF_READONLY;
873 | IDL_OPTIONAL
875 idlc()->setParseState(PS_OptionalSeen);
876 $$ = AF_OPTIONAL;
878 | IDL_MAYBEVOID
880 idlc()->setParseState(PS_MayBeVoidSeen);
881 $$ = AF_MAYBEVOID;
883 | IDL_BOUND
885 idlc()->setParseState(PS_BoundSeen);
886 $$ = AF_BOUND;
888 | IDL_CONSTRAINED
890 idlc()->setParseState(PS_ConstrainedSeen);
891 $$ = AF_CONSTRAINED;
893 | IDL_TRANSIENT
895 idlc()->setParseState(PS_TransientSeen);
896 $$ = AF_TRANSIENT;
898 | IDL_MAYBEAMBIGUOUS
900 idlc()->setParseState(PS_MayBeAmbigiousSeen);
901 $$ = AF_MAYBEAMBIGUOUS;
903 | IDL_MAYBEDEFAULT
905 idlc()->setParseState(PS_MayBeDefaultSeen);
906 $$ = AF_MAYBEDEFAULT;
908 | IDL_REMOVEABLE
910 idlc()->setParseState(PS_RemoveableSeen);
911 $$ = AF_REMOVEABLE;
913 | error ']'
915 yyerror("unknown property|attribute flag");
916 yyerrok;
920 opt_attribute_block:
921 '{' attribute_block_rest { $$ = $2; }
922 | /* empty */
924 $$.get.documentation = 0;
925 $$.get.exceptions = 0;
926 $$.set.documentation = 0;
927 $$.set.exceptions = 0;
931 attribute_block_rest:
932 opt_attribute_raises '}'
933 | error '}'
935 yyerror("bad attribute raises block");
936 yyerrok;
937 $$.get.documentation = 0;
938 $$.get.exceptions = 0;
939 $$.set.documentation = 0;
940 $$.set.exceptions = 0;
944 opt_attribute_raises:
945 attribute_get_raises
946 opt_attribute_set_raises
948 $$.get = $1;
949 $$.set = $2;
951 | attribute_set_raises
952 opt_attribute_get_raises
954 $$.get = $2;
955 $$.set = $1;
957 | /* empty */
959 $$.get.documentation = 0;
960 $$.get.exceptions = 0;
961 $$.set.documentation = 0;
962 $$.set.exceptions = 0;
966 opt_attribute_get_raises:
967 attribute_get_raises
968 | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
971 attribute_get_raises:
972 IDL_GET raises ';'
974 $$.documentation = new rtl::OUString(
975 rtl::OStringToOUString(
976 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
977 $$.exceptions = $2;
981 opt_attribute_set_raises:
982 attribute_set_raises
983 | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
986 attribute_set_raises:
987 IDL_SET
989 if (static_cast< AstAttribute * >(idlc()->scopes()->top())->
990 isReadonly())
992 idlc()->error()->error0(EIDL_READONLY_ATTRIBUTE_SET_EXCEPTIONS);
995 raises ';'
997 $$.documentation = new rtl::OUString(
998 rtl::OStringToOUString(
999 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
1000 $$.exceptions = $3;
1004 operation :
1005 operation_head
1006 op_type_spec
1008 idlc()->setParseState(PS_OpTypeSeen);
1010 identifier
1012 idlc()->setParseState(PS_OpIDSeen);
1013 checkIdentifier($4);
1015 AstInterface * pScope = static_cast< AstInterface * >(
1016 idlc()->scopes()->top());
1017 AstOperation* pOp = NULL;
1020 * Create a node representing an operation on an interface
1021 * and add it to its enclosing scope
1023 if ( pScope && $2 )
1025 AstType *pType = (AstType*)$2;
1026 if ( !pType || (pType->getNodeType() == NT_exception) )
1028 // type ERROR
1029 } else
1031 pOp = new AstOperation($1, pType, *$4, pScope);
1033 AstInterface::DoubleMemberDeclarations doubleMembers(
1034 pScope->checkMemberClashes(pOp));
1035 if (doubleMembers.empty()) {
1036 pScope->addMember(pOp);
1037 } else {
1038 reportDoubleMemberDeclarations(doubleMembers);
1042 delete $4;
1044 * Push the operation scope onto the scopes stack
1046 idlc()->scopes()->push(pOp);
1050 idlc()->setParseState(PS_OpSqSeen);
1052 parameters
1054 idlc()->setParseState(PS_OpParsCompleted);
1058 idlc()->setParseState(PS_OpQsSeen);
1060 opt_raises
1062 AstScope* pScope = idlc()->scopes()->topNonNull();
1063 AstOperation* pOp = NULL;
1065 * Add exceptions and context to the operation
1067 if ( pScope && pScope->getScopeNodeType() == NT_operation)
1069 pOp = (AstOperation*)pScope;
1071 if ( pOp )
1072 pOp->setExceptions($12);
1074 delete $12;
1076 * Done with this operation. Pop its scope from the scopes stack
1078 idlc()->scopes()->pop();
1082 operation_head :
1084 IDL_ONEWAY
1086 idlc()->setParseState(PS_OpOnewaySeen);
1090 idlc()->setParseState(PS_OpHeadSeen);
1091 $$ = OP_ONEWAY;
1093 | /* EMPTY */
1095 $$ = OP_NONE;
1099 op_type_spec :
1100 simple_type_spec
1101 | IDL_VOID
1103 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void);
1107 parameters :
1108 parameter
1109 | parameters
1112 idlc()->setParseState(PS_OpParCommaSeen);
1114 parameter
1115 | /* EMPTY */
1116 | error ','
1118 yyerror("parameter definition");
1119 yyerrok;
1123 parameter :
1125 direction
1128 idlc()->setParseState(PS_OpParDirSeen);
1130 simple_type_spec
1132 idlc()->setParseState(PS_OpParTypeSeen);
1134 opt_rest
1135 declarator
1137 idlc()->setParseState(PS_OpParDeclSeen);
1139 AstOperation * pScope = static_cast< AstOperation * >(
1140 idlc()->scopes()->top());
1141 AstParameter* pParam = NULL;
1144 * Create a node representing an argument to an operation
1145 * Add it to the enclosing scope (the operation scope)
1147 if ( pScope && $5 && $8 )
1149 AstType const * pType = $8->compose($5);
1150 if ( pType )
1152 if (pScope->isConstructor() && $2 != DIR_IN) {
1153 idlc()->error()->error0(EIDL_CONSTRUCTOR_PARAMETER_NOT_IN);
1155 if (pScope->isVariadic()) {
1156 idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_LAST);
1158 if ($7) {
1159 AstDeclaration const * type = resolveTypedefs(pType);
1160 if (type->getNodeType() != NT_predefined
1161 || (static_cast< AstBaseType const * >(type)->
1162 getExprType() != ET_any))
1164 idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_ANY);
1166 if (pScope->isConstructor()) {
1167 if (pScope->getIteratorBegin()
1168 != pScope->getIteratorEnd())
1170 idlc()->error()->error0(
1171 EIDL_CONSTRUCTOR_REST_PARAMETER_NOT_FIRST);
1173 } else {
1174 idlc()->error()->error0(EIDL_METHOD_HAS_REST_PARAMETER);
1178 pParam = new AstParameter(
1179 static_cast< Direction >($2), $7, pType, $8->getName(),
1180 pScope);
1182 if ( !$8->checkType($5) )
1184 // WARNING
1187 pScope->addDeclaration(pParam);
1191 | error
1192 simple_type_spec
1194 idlc()->setParseState(PS_NoState);
1195 yyerrok;
1199 direction :
1200 IDL_IN
1202 $$ = DIR_IN;
1204 | IDL_OUT
1206 $$ = DIR_OUT;
1208 | IDL_INOUT
1210 $$ = DIR_INOUT;
1214 opt_rest:
1215 IDL_ELLIPSIS
1217 $$ = true;
1219 | /* empty */
1221 $$ = false;
1225 opt_raises:
1226 raises
1227 | /* empty */
1229 $$ = 0;
1233 raises:
1234 IDL_RAISES
1236 idlc()->setParseState(PS_RaiseSeen);
1240 idlc()->setParseState(PS_RaiseSqSeen);
1242 exception_list
1245 idlc()->setParseState(PS_RaiseQsSeen);
1246 $$ = $5;
1250 exception_list:
1251 exception_name
1253 $$ = new DeclList;
1254 $$->push_back($1);
1256 | exception_list ',' exception_name
1258 $1->push_back($3);
1259 $$ = $1;
1263 exception_name:
1264 scoped_name
1266 // The topmost scope is either an AstOperation (for interface methods
1267 // and service constructors) or an AstAttribute (for interface
1268 // attributes), so look up exception names in the next-to-topmost scope:
1269 AstDeclaration * decl = idlc()->scopes()->nextToTop()->lookupByName(
1270 *$1);
1271 if (decl == 0) {
1272 idlc()->error()->lookupError(*$1);
1273 } else if (!idlc()->error()->checkPublished(decl)) {
1274 decl = 0;
1275 } else if (decl->getNodeType() != NT_exception) {
1276 idlc()->error()->error1(EIDL_ILLEGAL_RAISES, decl);
1277 decl = 0;
1279 delete $1;
1280 $$ = decl;
1284 interface_inheritance_decl:
1285 optional_inherited_interface
1286 IDL_INTERFACE
1288 idlc()->setParseState(PS_ServiceIFHeadSeen);
1290 scoped_name
1292 AstInterface * ifc = static_cast< AstInterface * >(
1293 idlc()->scopes()->top());
1294 if (ifc->usesSingleInheritance()) {
1295 idlc()->error()->error0(EIDL_MIXED_INHERITANCE);
1296 } else {
1297 addInheritedInterface(
1298 ifc, *$4, $1,
1299 rtl::OStringToOUString(
1300 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
1302 delete $4;
1306 optional_inherited_interface:
1307 '[' IDL_OPTIONAL ']' { $$ = true; }
1308 | /* EMPTY */ { $$ = false; }
1311 constants_exports :
1312 constants_export constants_exports
1313 | /* EMPTY */
1316 constants_export :
1317 const_dcl
1319 idlc()->setParseState(PS_ConstantDeclSeen);
1321 ';' {};
1323 const_dcl :
1324 IDL_CONST
1326 idlc()->setParseState(PS_ConstSeen);
1328 const_type
1330 idlc()->setParseState(PS_ConstTypeSeen);
1332 identifier
1334 idlc()->setParseState(PS_ConstIDSeen);
1335 checkIdentifier($5);
1339 idlc()->setParseState(PS_ConstAssignSeen);
1341 expression
1343 idlc()->setParseState(PS_ConstExprSeen);
1345 AstScope* pScope = idlc()->scopes()->topNonNull();
1346 AstConstant* pConstant = NULL;
1348 if ( $9 && pScope )
1350 if ( !$9->coerce($3) )
1352 idlc()->error()->coercionError($9, $3);
1353 } else
1355 pConstant = new AstConstant($3, $9, *$5, pScope);
1356 pScope->addDeclaration(pConstant);
1359 delete $5;
1363 constants_dcl :
1364 IDL_CONSTANTS
1366 idlc()->setParseState(PS_ConstantsSeen);
1368 identifier
1370 idlc()->setParseState(PS_ConstantsIDSeen);
1371 checkIdentifier($3);
1375 idlc()->setParseState(PS_ConstantsSqSeen);
1377 AstScope* pScope = idlc()->scopes()->topNonNull();
1378 AstConstants* pConstants = NULL;
1379 AstDeclaration* pExists = NULL;
1381 if ( pScope )
1383 pConstants = new AstConstants(*$3, pScope);
1384 if( (pExists = pScope->lookupForAdd(pConstants)) )
1386 pExists->setInMainfile(idlc()->isInMainFile());
1387 delete(pConstants);
1388 pConstants = (AstConstants*)pExists;
1389 } else
1391 pScope->addDeclaration(pConstants);
1393 idlc()->scopes()->push(pConstants);
1395 delete $3;
1397 constants_exports
1399 idlc()->setParseState(PS_ConstantsBodySeen);
1403 idlc()->setParseState(PS_ConstantsQsSeen);
1405 * Finished with this constants - pop it from the scope stack
1407 idlc()->scopes()->pop();
1411 expression : const_expr ;
1413 const_expr : or_expr ;
1415 or_expr :
1416 xor_expr
1417 | or_expr '|' xor_expr
1419 $$ = new AstExpression(EC_or, $1, $3);
1423 xor_expr :
1424 and_expr
1425 | xor_expr '^' and_expr
1427 $$ = new AstExpression(EC_xor, $1, $3);
1431 and_expr :
1432 shift_expr
1433 | and_expr '&' shift_expr
1435 $$ = new AstExpression(EC_and, $1, $3);
1439 shift_expr :
1440 add_expr
1441 | shift_expr IDL_LEFTSHIFT add_expr
1443 $$ = new AstExpression(EC_left, $1, $3);
1445 | shift_expr IDL_RIGHTSHIFT add_expr
1447 $$ = new AstExpression(EC_right, $1, $3);
1451 add_expr :
1452 mult_expr
1453 | add_expr '+' mult_expr
1455 $$ = new AstExpression(EC_add, $1, $3);
1457 | add_expr '-' mult_expr
1459 $$ = new AstExpression(EC_minus, $1, $3);
1463 mult_expr :
1464 unary_expr
1465 | mult_expr '*' unary_expr
1467 $$ = new AstExpression(EC_mul, $1, $3);
1469 | mult_expr '/' unary_expr
1471 $$ = new AstExpression(EC_div, $1, $3);
1473 | mult_expr '%' unary_expr
1475 $$ = new AstExpression(EC_mod, $1, $3);
1479 unary_expr :
1480 primary_expr
1481 | '+' primary_expr
1483 $$ = new AstExpression(EC_u_plus, $2, NULL);
1485 | '-' primary_expr
1487 $$ = new AstExpression(EC_u_minus, $2, NULL);
1489 | '~' primary_expr
1494 primary_expr :
1495 scoped_name
1498 * An expression which is a scoped name is not resolved now,
1499 * but only when it is evaluated (such as when it is assigned
1500 * as a constant value)
1502 $$ = new AstExpression($1);
1504 | literal
1505 | '(' const_expr ')'
1507 $$ = $2;
1511 literal :
1512 IDL_INTEGER_LITERAL
1514 $$ = new AstExpression($1);
1516 | IDL_INTEGER_ULITERAL
1518 $$ = new AstExpression($1);
1520 | IDL_FLOATING_PT_LITERAL
1522 $$ = new AstExpression($1);
1524 | IDL_TRUE
1526 $$ = new AstExpression((sal_Int32)1, ET_boolean);
1528 | IDL_FALSE
1530 $$ = new AstExpression((sal_Int32)0, ET_boolean);
1534 positive_int_expr :
1535 const_expr
1537 $1->evaluate(EK_const);
1538 if ( !$1->coerce(ET_ulong) )
1540 idlc()->error()->coercionError($1, ET_ulong);
1541 delete $1;
1542 $$ = NULL;
1547 const_type :
1548 integer_type
1549 | char_type
1550 | byte_type
1551 | boolean_type
1552 | floating_pt_type
1553 | scoped_name
1555 AstScope* pScope = idlc()->scopes()->topNonNull();
1556 AstDeclaration const * type = 0;
1559 * If the constant's type is a scoped name, it must resolve
1560 * to a scalar constant type
1562 if ( pScope && (type = pScope->lookupByName(*$1)) ) {
1563 if (!idlc()->error()->checkPublished(type))
1565 type = 0;
1567 else
1569 type = resolveTypedefs(type);
1570 if (type->getNodeType() == NT_predefined)
1572 $$ = static_cast< AstBaseType const * >(type)->
1573 getExprType();
1574 } else
1575 $$ = ET_any;
1577 } else
1578 $$ = ET_any;
1582 exception_header :
1583 IDL_EXCEPTION
1585 idlc()->setParseState(PS_ExceptSeen);
1587 identifier
1589 idlc()->setParseState(PS_ExceptIDSeen);
1590 checkIdentifier($3);
1592 inheritance_spec
1594 idlc()->setParseState(PS_InheritSpecSeen);
1596 $$ = new FeInheritanceHeader(NT_exception, $3, $5, 0);
1597 delete $5;
1601 exception_dcl :
1602 exception_header
1604 idlc()->setParseState(PS_ExceptHeaderSeen);
1606 AstScope* pScope = idlc()->scopes()->topNonNull();
1607 AstException* pExcept = NULL;
1609 if ( pScope )
1611 AstException* pBase = static_cast< AstException* >(
1612 $1->getInherits());
1613 pExcept = new AstException(*$1->getName(), pBase, pScope);
1614 pScope->addDeclaration(pExcept);
1617 * Push the scope of the exception on the scopes stack
1619 idlc()->scopes()->push(pExcept);
1620 delete $1;
1624 idlc()->setParseState(PS_ExceptSqSeen);
1626 members
1628 idlc()->setParseState(PS_ExceptBodySeen);
1632 idlc()->setParseState(PS_ExceptQsSeen);
1633 /* this exception is finished, pop its scope from the stack */
1634 idlc()->scopes()->pop();
1638 property :
1639 flag_header
1640 simple_type_spec
1642 idlc()->setParseState(PS_PropertyTypeSeen);
1644 at_least_one_declarator
1646 idlc()->setParseState(PS_PropertyCompleted);
1648 AstScope* pScope = idlc()->scopes()->topNonNull();
1649 AstAttribute* pAttr = NULL;
1650 FeDeclList* pList = $4;
1651 FeDeclarator* pDecl = NULL;
1652 AstType const * pType = NULL;
1654 if ( pScope->getScopeNodeType() == NT_singleton )
1656 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1657 } else
1659 if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
1660 idlc()->error()->flagError(EIDL_WRONGATTRIBUTEKEYWORD, AF_ATTRIBUTE);
1662 if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
1663 idlc()->error()->flagError(EIDL_MISSINGATTRIBUTEKEYWORD, AF_PROPERTY);
1666 * Create nodes representing attributes and add them to the
1667 * enclosing scope
1669 if ( pScope && $2 && pList )
1671 FeDeclList::iterator iter = pList->begin();
1672 FeDeclList::iterator end = pList->end();
1674 while (iter != end)
1676 pDecl = (*iter);
1677 if ( !pDecl )
1679 iter++;
1680 continue;
1683 pType = pDecl->compose($2);
1685 if ( !pType )
1687 iter++;
1688 continue;
1691 pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);
1693 pScope->addDeclaration(pAttr);
1694 iter++;
1695 delete pDecl;
1700 if ( pList )
1701 delete pList;
1703 | error ';'
1705 yyerror("property");
1706 yyerrok;
1710 service_exports :
1711 service_exports service_export
1712 | /* EMPTY */
1715 service_export :
1716 service_interface_header
1717 at_least_one_scoped_name
1720 idlc()->setParseState(PS_ServiceMemberSeen);
1722 AstScope* pScope = idlc()->scopes()->topNonNull();
1723 AstDeclaration* pDecl = NULL;
1724 AstInterfaceMember* pIMember = NULL;
1726 if ( pScope->getScopeNodeType() == NT_singleton )
1728 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1729 } else
1732 * Create a node representing a class member.
1733 * Store it in the enclosing scope
1735 if ( pScope && $2 )
1737 StringList::iterator iter = $2->begin();
1738 StringList::iterator end = $2->end();
1740 while ( iter != end )
1742 pDecl = pScope->lookupByName(*iter);
1743 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1745 /* we relax the strict published check and allow to add new
1746 * interfaces if they are optional
1748 bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
1749 if ( idlc()->error()->checkPublished(pDecl, bOptional) )
1751 pIMember = new AstInterfaceMember(
1752 $1, (AstInterface*)pDecl, *iter, pScope);
1753 pScope->addDeclaration(pIMember);
1755 } else
1757 idlc()->error()->
1758 lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1760 iter++;
1764 delete $2;
1766 | service_service_header
1767 at_least_one_scoped_name
1770 idlc()->setParseState(PS_ServiceMemberSeen);
1772 AstScope* pScope = idlc()->scopes()->topNonNull();
1773 AstDeclaration* pDecl = NULL;
1774 AstServiceMember* pSMember = NULL;
1777 * Create a node representing a class member.
1778 * Store it in the enclosing scope
1780 if ( pScope && $2 )
1782 StringList::iterator iter = $2->begin();
1783 StringList::iterator end = $2->end();
1785 while ( iter != end )
1787 pDecl = pScope->lookupByName(*iter);
1788 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1790 if ( pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0 )
1791 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1792 else if ( idlc()->error()->checkPublished(pDecl) )
1794 pSMember = new AstServiceMember(
1795 $1, (AstService*)pDecl, *iter, pScope);
1796 pScope->addDeclaration(pSMember);
1798 } else
1800 idlc()->error()->
1801 lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1803 iter++;
1806 delete $2;
1808 | IDL_OBSERVES
1809 at_least_one_scoped_name
1812 idlc()->setParseState(PS_ServiceMemberSeen);
1814 AstScope* pScope = idlc()->scopes()->topNonNull();
1815 AstDeclaration* pDecl = NULL;
1816 AstObserves* pObserves = NULL;
1818 if ( pScope->getScopeNodeType() == NT_singleton )
1820 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1821 } else
1824 * Create a node representing a class member.
1825 * Store it in the enclosing scope
1827 if ( pScope && $2 )
1829 StringList::iterator iter = $2->begin();
1830 StringList::iterator end = $2->end();
1832 while ( iter != end )
1834 pDecl = pScope->lookupByName(*iter);
1835 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1837 pObserves = new AstObserves((AstInterface*)pDecl, *iter, pScope);
1838 pScope->addDeclaration(pObserves);
1839 } else
1841 idlc()->error()->
1842 lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1844 iter++;
1848 delete $2;
1850 | IDL_NEEDS
1851 at_least_one_scoped_name
1854 idlc()->setParseState(PS_ServiceMemberSeen);
1856 AstScope* pScope = idlc()->scopes()->topNonNull();
1857 AstDeclaration* pDecl = NULL;
1858 AstNeeds* pNeeds = NULL;
1860 if ( pScope->getScopeNodeType() == NT_singleton )
1862 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1863 } else
1866 * Create a node representing a class member.
1867 * Store it in the enclosing scope
1869 if ( pScope && $2 )
1871 StringList::iterator iter = $2->begin();
1872 StringList::iterator end = $2->end();
1874 while ( iter != end )
1876 pDecl = pScope->lookupByName(*iter);
1877 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1879 pNeeds = new AstNeeds((AstService*)pDecl, *iter, pScope);
1880 pScope->addDeclaration(pNeeds);
1881 } else
1883 idlc()->error()->
1884 lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1886 iter++;
1890 delete $2;
1892 | property
1895 idlc()->setParseState(PS_PropertyDeclSeen);
1899 service_interface_header :
1900 IDL_INTERFACE
1902 idlc()->setParseState(PS_ServiceIFHeadSeen);
1903 $$ = AF_INVALID;
1905 | flag_header
1906 IDL_INTERFACE
1908 idlc()->setParseState(PS_ServiceIFHeadSeen);
1909 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1910 idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1911 $$ = $1;
1915 service_service_header :
1916 IDL_SERVICE
1918 idlc()->setParseState(PS_ServiceSHeadSeen);
1919 $$ = AF_INVALID;
1921 | flag_header
1922 IDL_SERVICE
1924 idlc()->setParseState(PS_ServiceSHeadSeen);
1925 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1926 idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1927 $$ = $1;
1931 service_dcl :
1932 IDL_SERVICE
1934 idlc()->setParseState(PS_ServiceSeen);
1936 identifier
1938 idlc()->setParseState(PS_ServiceIDSeen);
1939 checkIdentifier($3);
1941 AstScope* pScope = idlc()->scopes()->topNonNull();
1942 AstService* pService = NULL;
1945 * Make a new service and add it to the enclosing scope
1947 if (pScope != NULL)
1949 pService = new AstService(*$3, pScope);
1950 pScope->addDeclaration(pService);
1952 delete $3;
1954 * Push it on the stack
1956 idlc()->scopes()->push(pService);
1958 service_dfn
1960 /* this service is finished, pop its scope from the stack */
1961 idlc()->scopes()->pop();
1965 service_dfn:
1966 service_interface_dfn
1967 | service_obsolete_dfn
1970 service_interface_dfn:
1971 ':' scoped_name
1973 AstScope * scope = idlc()->scopes()->nextToTop();
1974 // skip the scope pushed by service_dcl
1975 AstDeclaration * decl = scope->lookupByName(*$2);
1976 if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
1977 if (idlc()->error()->checkPublished(decl)) {
1978 idlc()->scopes()->top()->addDeclaration(decl);
1980 } else {
1981 idlc()->error()->lookupError(
1982 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
1984 delete $2;
1986 opt_service_body
1988 AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
1989 if (s != 0) {
1990 s->setDefaultConstructor(!$4);
1995 opt_service_body:
1996 service_body { $$ = true; }
1997 | /* empty */ { $$ = false; }
2000 service_body:
2002 constructors
2006 constructors:
2007 constructors constructor
2008 | /* empty */
2011 constructor:
2012 identifier
2014 checkIdentifier($1);
2015 AstScope * scope = idlc()->scopes()->top();
2016 AstOperation * ctor = new AstOperation(OP_NONE, 0, *$1, scope);
2017 delete $1;
2018 scope->addDeclaration(ctor);
2019 idlc()->scopes()->push(ctor);
2022 parameters
2024 opt_raises
2026 static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions(
2027 $6);
2028 delete $6;
2029 idlc()->scopes()->pop();
2030 if (static_cast< AstService * >(idlc()->scopes()->top())->
2031 checkLastConstructor())
2033 idlc()->error()->error0(EIDL_SIMILAR_CONSTRUCTORS);
2039 singleton_dcl :
2040 IDL_SINGLETON
2042 idlc()->setParseState(PS_SingletonSeen);
2044 identifier
2046 idlc()->setParseState(PS_SingletonIDSeen);
2047 checkIdentifier($3);
2049 AstScope* pScope = idlc()->scopes()->topNonNull();
2050 AstService* pService = NULL;
2053 * Make a new service and add it to the enclosing scope
2055 if (pScope != NULL)
2057 pService = new AstService(NT_singleton, *$3, pScope);
2058 pScope->addDeclaration(pService);
2060 delete $3;
2062 * Push it on the stack
2064 idlc()->scopes()->push(pService);
2066 singleton_dfn
2068 /* this singelton is finished, pop its scope from the stack */
2069 idlc()->scopes()->pop();
2073 singleton_dfn:
2074 singleton_interface_dfn
2075 | service_obsolete_dfn
2078 singleton_interface_dfn:
2079 ':' scoped_name
2081 AstScope * scope = idlc()->scopes()->nextToTop();
2082 // skip the scope (needlessly) pushed by singleton_dcl
2083 AstDeclaration * decl = scope->lookupByName(*$2);
2084 if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
2085 if (idlc()->error()->checkPublished(decl)) {
2086 idlc()->scopes()->top()->addDeclaration(decl);
2088 } else {
2089 idlc()->error()->lookupError(
2090 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
2092 delete $2;
2096 service_obsolete_dfn:
2099 idlc()->setParseState(
2100 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2101 ? PS_ServiceSqSeen : PS_SingletonSqSeen);
2103 service_exports
2105 idlc()->setParseState(
2106 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2107 ? PS_ServiceBodySeen : PS_SingletonBodySeen);
2111 idlc()->setParseState(
2112 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2113 ? PS_ServiceQsSeen : PS_SingletonQsSeen);
2117 type_dcl :
2118 IDL_TYPEDEF
2120 idlc()->setParseState(PS_TypedefSeen);
2122 type_declarator {}
2123 | struct_type {}
2124 | union_type {}
2125 | enum_type {}
2128 type_declarator :
2129 type_spec
2131 idlc()->setParseState(PS_TypeSpecSeen);
2132 if ($1 != 0 && $1->getNodeType() == NT_instantiated_struct) {
2133 idlc()->error()->error0(EIDL_INSTANTIATED_STRUCT_TYPE_TYPEDEF);
2136 at_least_one_declarator
2138 idlc()->setParseState(PS_DeclaratorsSeen);
2140 AstScope* pScope = idlc()->scopes()->topNonNull();
2141 AstTypeDef* pTypeDef = NULL;
2142 FeDeclList* pList = $3;
2143 FeDeclarator* pDecl = NULL;
2144 AstType const * pType = NULL;
2147 * Create nodes representing typedefs and add them to the
2148 * enclosing scope
2150 if ( pScope && $1 && pList )
2152 FeDeclList::iterator iter = pList->begin();
2153 FeDeclList::iterator end = pList->end();
2155 while (iter != end)
2157 pDecl = (*iter);
2158 if ( !pDecl )
2160 iter++;
2161 continue;
2164 pType = pDecl->compose($1);
2166 if ( !pType )
2168 iter++;
2169 continue;
2172 pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);
2174 pScope->addDeclaration(pTypeDef);
2175 iter++;
2176 delete pDecl;
2178 delete pList;
2183 at_least_one_declarator :
2184 declarator declarators
2186 if ( $2 )
2188 $2->push_back($1);
2189 $$ = $2;
2190 } else
2192 FeDeclList* pList = new FeDeclList();
2193 pList->push_back($1);
2194 $$ = pList;
2199 declarators :
2200 declarators
2203 idlc()->setParseState(PS_DeclsCommaSeen);
2205 declarator
2207 idlc()->setParseState(PS_DeclsDeclSeen);
2208 if ( $1 )
2210 $1->push_back($4);
2211 $$ = $1;
2212 } else
2214 FeDeclList* pList = new FeDeclList();
2215 pList->push_back($4);
2216 $$ = pList;
2219 | /* EMPTY */
2221 $$ = NULL;
2225 declarator :
2226 simple_declarator
2227 | complex_declarator
2230 simple_declarator :
2231 identifier
2233 // For historic reasons, the struct com.sun.star.uno.Uik contains
2234 // members with illegal names (of the form "m_DataN"); avoid useless
2235 // warnings about them:
2236 AstScope * scope = idlc()->scopes()->top();
2237 if (scope == 0 || scope->getScopeNodeType() != NT_struct
2238 || (scopeAsDecl(scope)->getScopedName()
2239 != "com::sun::star::uno::Uik"))
2241 checkIdentifier($1);
2244 $$ = new FeDeclarator(*$1, FeDeclarator::FD_simple, NULL);
2245 delete $1;
2249 complex_declarator :
2250 array_declarator
2252 $$ = new FeDeclarator($1->getLocalName(), FeDeclarator::FD_complex, $1);
2256 array_declarator :
2257 identifier
2259 idlc()->setParseState(PS_ArrayIDSeen);
2260 checkIdentifier($1);
2262 at_least_one_array_dim
2264 idlc()->setParseState(PS_ArrayCompleted);
2265 $$ = new AstArray(*$1, NULL, *$3, idlc()->scopes()->bottom());
2266 delete $1;
2270 at_least_one_array_dim :
2271 array_dim array_dims
2273 if( $2 )
2275 $2->push_front($1);
2276 $$ = $2;
2277 } else
2279 ExprList* pList = new ExprList();
2280 pList->push_back($1);
2281 $$ = pList;
2286 array_dims :
2287 array_dims array_dim
2289 if( $1 )
2291 $1->push_back($2);
2292 $$ = $1;
2293 } else
2295 ExprList* pList = new ExprList();
2296 pList->push_back($2);
2297 $$ = pList;
2300 | /* EMPTY */
2302 $$ = NULL;
2306 array_dim :
2309 idlc()->setParseState(PS_DimSqSeen);
2311 positive_int_expr
2313 idlc()->setParseState(PS_DimExprSeen);
2317 idlc()->setParseState(PS_DimQsSeen);
2319 * Array dimensions are expressions which must be coerced to
2320 * positive integers
2322 if ( !$3 || !$3->coerce(ET_uhyper) )
2324 idlc()->error()->coercionError($3, ET_uhyper);
2325 $$ = NULL;
2326 } else
2327 $$ = $3;
2331 at_least_one_scoped_name :
2332 scoped_name scoped_names
2334 if ($2)
2336 $2->push_front(*$1);
2337 $$ = $2;
2338 } else
2340 StringList* pNames = new StringList();
2341 pNames->push_back(*$1);
2342 $$ = pNames;
2344 delete($1);
2348 scoped_names :
2349 scoped_names
2352 idlc()->setParseState(PS_SNListCommaSeen);
2354 scoped_name
2356 idlc()->setParseState(PS_ScopedNameSeen);
2357 if ($1)
2359 $1->push_back(*$4);
2360 $$ = $1;
2361 } else
2363 StringList* pNames = new StringList();
2364 pNames->push_back(*$4);
2365 $$ = pNames;
2367 delete($4);
2369 | /* EMPTY */
2371 $$ = NULL;
2375 scoped_name :
2376 identifier
2378 idlc()->setParseState(PS_SN_IDSeen);
2379 checkIdentifier($1);
2380 $$ = $1;
2382 | IDL_SCOPESEPARATOR
2384 idlc()->setParseState(PS_ScopeDelimSeen);
2386 identifier
2388 checkIdentifier($3);
2389 OString* pName = new OString("::");
2390 *pName += *$3;
2391 delete $3;
2392 $$ = pName;
2394 | scoped_name
2395 IDL_SCOPESEPARATOR
2398 identifier
2400 checkIdentifier($4);
2401 *$1 += ::rtl::OString("::");
2402 *$1 += *$4;
2403 delete $4;
2404 $$ = $1;
2408 type_spec :
2409 simple_type_spec
2410 | constructed_type_spec
2413 simple_type_spec :
2414 fundamental_type
2415 | scoped_name opt_type_args
2417 $$ = createNamedType($1, $2);
2421 fundamental_type:
2422 base_type_spec
2424 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2426 | template_type_spec
2429 opt_type_args:
2430 '<' type_args '>' { $$ = $2; }
2431 | /* empty */ { $$ = 0; }
2434 type_args:
2435 type_arg
2437 $$ = new DeclList;
2438 $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
2440 | type_args ',' type_arg
2442 $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
2443 $$ = $1;
2447 type_arg:
2448 simple_type_spec
2450 if ($1 != 0 && static_cast< AstType const * >($1)->isUnsigned()) {
2451 idlc()->error()->error0(EIDL_UNSIGNED_TYPE_ARGUMENT);
2453 $$ = $1;
2457 base_type_spec :
2458 integer_type
2459 | floating_pt_type
2460 | char_type
2461 | boolean_type
2462 | byte_type
2463 | any_type
2464 | type_type
2465 | string_type
2468 integer_type :
2469 signed_int
2470 | unsigned_int
2473 signed_int :
2474 IDL_LONG
2476 $$ = ET_long;
2478 | IDL_HYPER
2480 $$ = ET_hyper;
2482 | IDL_SHORT
2484 $$ = ET_short;
2488 unsigned_int :
2489 IDL_UNSIGNED IDL_LONG
2491 $$ = ET_ulong;
2493 | IDL_UNSIGNED IDL_HYPER
2495 $$ = ET_uhyper;
2497 | IDL_UNSIGNED IDL_SHORT
2499 $$ = ET_ushort;
2503 floating_pt_type :
2504 IDL_DOUBLE
2506 $$ = ET_double;
2508 | IDL_FLOAT
2510 $$ = ET_float;
2514 char_type :
2515 IDL_CHAR
2517 $$ = ET_char;
2521 byte_type :
2522 IDL_BYTE
2524 $$ = ET_byte;
2528 boolean_type :
2529 IDL_BOOLEAN
2531 $$ = ET_boolean;
2535 any_type :
2536 IDL_ANY
2538 $$ = ET_any;
2542 type_type :
2543 IDL_TYPE
2545 $$ = ET_type;
2549 string_type :
2550 IDL_STRING
2552 $$ = ET_string;
2556 template_type_spec :
2557 sequence_type_spec
2558 | array_type
2561 constructed_type_spec :
2562 struct_type
2563 | union_type
2564 | enum_type
2567 array_type :
2568 simple_type_spec
2570 idlc()->setParseState(PS_ArrayTypeSeen);
2572 at_least_one_array_dim
2574 idlc()->setParseState(PS_ArrayCompleted);
2576 AstScope* pScope = idlc()->scopes()->bottom();
2577 AstDeclaration* pDecl = NULL;
2578 AstDeclaration* pArray = NULL;
2580 if ( $1 )
2582 pArray = new AstArray((AstType*)$1, *$3, idlc()->scopes()->bottom());
2583 if ( pScope )
2585 pDecl = pScope->addDeclaration(pArray);
2586 if ( pArray != pDecl )
2588 // if array type already defined then use it
2589 delete pArray;
2590 pArray = pDecl;
2594 $$ = pArray;
2598 sequence_type_spec :
2599 IDL_SEQUENCE
2601 idlc()->setParseState(PS_SequenceSeen);
2603 * Push a sequence marker on scopes stack
2605 idlc()->scopes()->push(NULL);
2609 idlc()->setParseState(PS_SequenceSqSeen);
2611 simple_type_spec
2613 idlc()->setParseState(PS_SequenceTypeSeen);
2617 idlc()->setParseState(PS_SequenceQsSeen);
2619 * Remove sequence marker from scopes stack
2621 if (idlc()->scopes()->top() == NULL)
2622 idlc()->scopes()->pop();
2624 * Create a node representing a sequence
2626 AstScope* pScope = idlc()->scopes()->bottom();
2627 AstDeclaration* pDecl = NULL;
2628 AstDeclaration* pSeq = NULL;
2630 if ( $5 )
2632 AstType *pType = (AstType*)$5;
2633 if ( pType )
2635 pSeq = new AstSequence(pType, pScope);
2637 * Add this AstSequence to the types defined in the global scope
2639 pDecl = pScope->addDeclaration(pSeq);
2640 if ( pSeq != pDecl )
2642 // if sequence type already defined then use it
2643 delete pSeq;
2644 pSeq = pDecl;
2648 $$ = pSeq;
2650 | error '>'
2652 yyerror("sequence declaration");
2653 yyerrok;
2654 $$ = 0;
2658 struct_type :
2659 structure_header
2661 idlc()->setParseState(PS_StructHeaderSeen);
2663 AstScope* pScope = idlc()->scopes()->topNonNull();
2664 AstStruct* pStruct = NULL;
2666 if ( pScope )
2668 AstStruct* pBase= static_cast< AstStruct* >($1->getInherits());
2669 pStruct = new AstStruct(
2670 *$1->getName(), $1->getTypeParameters(), pBase, pScope);
2671 pScope->addDeclaration(pStruct);
2674 * Push the scope of the struct on the scopes stack
2676 idlc()->scopes()->push(pStruct);
2677 delete $1;
2681 idlc()->setParseState(PS_StructSqSeen);
2683 at_least_one_member
2685 idlc()->setParseState(PS_StructBodySeen);
2689 idlc()->setParseState(PS_StructQsSeen);
2690 /* this exception is finished, pop its scope from the stack */
2691 idlc()->scopes()->pop();
2695 structure_header :
2696 IDL_STRUCT
2698 idlc()->setParseState(PS_StructSeen);
2700 identifier
2702 idlc()->setParseState(PS_StructIDSeen);
2703 checkIdentifier($3);
2705 opt_type_params
2706 inheritance_spec
2708 idlc()->setParseState(PS_InheritSpecSeen);
2710 // Polymorphic struct type templates with base types would cause various
2711 // problems in language bindings, so forbid them here. For example,
2712 // GCC prior to version 3.4 fails with code like
2714 // struct Base { ... };
2715 // template< typename typeparam_T > struct Derived: public Base {
2716 // int member1 CPPU_GCC3_ALIGN(Base);
2717 // ... };
2719 // (Note that plain struct types with instantiated polymorphic struct
2720 // type bases, which might also cause problems in language bindings, are
2721 // already rejected on a syntactic level.)
2722 if ($5 != 0 && $6 != 0) {
2723 idlc()->error()->error0(EIDL_STRUCT_TYPE_TEMPLATE_WITH_BASE);
2726 $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
2727 delete $5;
2728 delete $6;
2732 opt_type_params:
2733 '<' type_params '>' { $$ = $2; }
2734 | /* empty */ { $$ = 0; }
2737 type_params:
2738 identifier
2740 $$ = new std::vector< rtl::OString >;
2741 $$->push_back(*$1);
2742 delete $1;
2744 | type_params ',' identifier
2746 if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
2747 idlc()->error()->error0(EIDL_IDENTICAL_TYPE_PARAMETERS);
2749 $1->push_back(*$3);
2750 delete $3;
2751 $$ = $1;
2755 at_least_one_member : member members ;
2757 members :
2758 members member
2759 | /* EMPTY */
2762 member :
2763 type_or_parameter
2765 idlc()->setParseState(PS_MemberTypeSeen);
2767 at_least_one_declarator
2769 idlc()->setParseState(PS_MemberDeclsSeen);
2773 idlc()->setParseState(PS_MemberDeclsCompleted);
2775 AstScope* pScope = idlc()->scopes()->topNonNull();
2776 AstMember* pMember = NULL;
2777 FeDeclList* pList = $3;
2778 FeDeclarator* pDecl = NULL;
2779 AstType const * pType = NULL;
2781 // !!! check recursive type
2783 if ( pScope && pList && $1 )
2785 FeDeclList::iterator iter = pList->begin();
2786 FeDeclList::iterator end = pList->end();
2787 while (iter != end)
2789 pDecl = (*iter);
2790 if ( !pDecl )
2792 iter++;
2793 continue;
2796 pType = pDecl->compose($1);
2798 if ( !pType )
2800 iter++;
2801 continue;
2804 pMember = new AstMember(pType, pDecl->getName(), pScope);
2806 if ( !pDecl->checkType($1) )
2808 // WARNING
2811 pScope->addDeclaration(pMember);
2812 iter++;
2813 delete pDecl;
2815 delete pList;
2818 | error ';'
2820 yyerror("member definition");
2821 yyerrok;
2825 type_or_parameter:
2826 fundamental_type
2827 | scoped_name opt_type_args
2829 AstDeclaration const * decl = 0;
2830 AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top());
2831 if (scope != 0 && $2 == 0) {
2832 decl = scope->findTypeParameter(*$1);
2834 if (decl != 0) {
2835 delete $1;
2836 delete $2;
2837 } else {
2838 decl = createNamedType($1, $2);
2839 if (scope != 0 && includes(decl, scopeAsDecl(scope))) {
2840 idlc()->error()->error1(
2841 EIDL_RECURSIVE_TYPE, scopeAsDecl(scope));
2842 decl = 0;
2845 $$ = decl;
2849 enum_type :
2850 IDL_ENUM
2852 idlc()->setParseState(PS_EnumSeen);
2854 identifier
2856 idlc()->setParseState(PS_EnumIDSeen);
2857 checkIdentifier($3);
2859 AstScope* pScope = idlc()->scopes()->topNonNull();
2860 AstEnum* pEnum = NULL;
2863 * Create a node representing an enum and add it to its
2864 * enclosing scope
2866 if (pScope != NULL)
2868 pEnum = new AstEnum(*$3, pScope);
2870 * Add it to its defining scope
2872 pScope->addDeclaration(pEnum);
2874 delete $3;
2876 * Push the enum scope on the scopes stack
2878 idlc()->scopes()->push(pEnum);
2883 idlc()->setParseState(PS_EnumSqSeen);
2885 at_least_one_enumerator
2887 idlc()->setParseState(PS_EnumBodySeen);
2891 idlc()->setParseState(PS_EnumQsSeen);
2893 * Done with this enum. Pop its scope from the scopes stack
2895 if (idlc()->scopes()->top() == NULL)
2896 $$ = NULL;
2897 else
2899 $$ = (AstEnum*)idlc()->scopes()->topNonNull();
2900 idlc()->scopes()->pop();
2905 at_least_one_enumerator : enumerator enumerators ;
2907 enumerators :
2908 enumerators
2911 idlc()->setParseState(PS_EnumCommaSeen);
2913 enumerator
2914 | /* EMPTY */
2915 | error ','
2917 yyerror("enumerator definition");
2918 yyerrok;
2922 enumerator :
2923 identifier
2925 checkIdentifier($1);
2927 AstScope* pScope = idlc()->scopes()->topNonNull();
2928 AstEnum* pEnum = NULL;
2929 AstConstant* pEnumVal = NULL;
2931 if ( pScope && pScope->getScopeNodeType() == NT_enum)
2933 pEnum = (AstEnum*)pScope;
2934 if (pEnum && $1)
2936 AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
2937 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2938 pExpr, *$1, pScope);
2940 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2941 idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2943 pScope->addDeclaration(pEnumVal);
2945 delete $1;
2947 | identifier
2949 const_expr
2951 checkIdentifier($1);
2953 AstScope* pScope = idlc()->scopes()->topNonNull();
2954 AstEnum* pEnum = NULL;
2955 AstConstant* pEnumVal = NULL;
2957 if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
2959 $3->evaluate(EK_const);
2960 if ( $3->coerce(ET_long) )
2962 pEnum = (AstEnum*)pScope;
2963 if (pEnum)
2965 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2966 $3, *$1, pScope);
2968 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2969 idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2971 pScope->addDeclaration(pEnumVal);
2972 } else
2974 idlc()->error()->coercionError($3, ET_long);
2975 delete $3;
2978 delete $1;
2982 union_type :
2983 IDL_UNION
2985 idlc()->setParseState(PS_UnionSeen);
2987 identifier
2989 idlc()->setParseState(PS_UnionIDSeen);
2990 checkIdentifier($3);
2992 IDL_SWITCH
2994 idlc()->setParseState(PS_SwitchSeen);
2998 idlc()->setParseState(PS_SwitchOpenParSeen);
3000 switch_type_spec
3002 idlc()->setParseState(PS_SwitchTypeSeen);
3006 idlc()->setParseState(PS_SwitchCloseParSeen);
3008 AstScope* pScope = idlc()->scopes()->topNonNull();
3009 AstUnion* pUnion = NULL;
3012 * Create a node representing a union. Add it to its enclosing
3013 * scope
3015 if ( $9 && pScope )
3017 AstType* pType = (AstType*)$9;
3018 if ( !pType)
3020 idlc()->error()->noTypeError($9);
3021 } else
3023 pUnion = new AstUnion(*$3, pType, pScope);
3024 pScope->addDeclaration(pUnion);
3027 delete $3;
3029 * Push the scope of the union on the scopes stack
3031 idlc()->scopes()->push(pUnion);
3035 idlc()->setParseState(PS_UnionSqSeen);
3037 at_least_one_case_branch
3039 idlc()->setParseState(PS_UnionBodySeen);
3043 idlc()->setParseState(PS_UnionQsSeen);
3044 /* this union is finished, pop its scope from the stack */
3045 idlc()->scopes()->pop();
3049 switch_type_spec :
3050 integer_type
3052 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
3054 | char_type
3056 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
3058 | boolean_type
3060 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
3062 | enum_type
3063 | scoped_name
3065 AstScope* pScope = idlc()->scopes()->topNonNull();
3066 AstBaseType* pBaseType = NULL;
3067 AstDeclaration const * pDecl = NULL;
3068 AstTypeDef* pTypeDef = NULL;
3069 sal_Bool bFound = sal_False;
3071 * If the constant's type is a scoped name, it must resolve
3072 * to a scalar constant type
3074 if ( pScope && (pDecl = pScope->lookupByName(*$1)) )
3077 * Look through typedefs
3079 while ( !bFound )
3081 switch (pDecl->getNodeType())
3083 case NT_enum:
3084 $$ = pDecl;
3085 bFound = sal_True;
3086 break;
3087 case NT_predefined:
3088 pBaseType = (AstBaseType*)pDecl;
3089 if ( pBaseType )
3091 switch (pBaseType->getExprType())
3093 case ET_short:
3094 case ET_ushort:
3095 case ET_long:
3096 case ET_ulong:
3097 case ET_hyper:
3098 case ET_uhyper:
3099 case ET_char:
3100 case ET_byte:
3101 case ET_boolean:
3102 $$ = pBaseType;
3103 bFound = sal_True;
3104 break;
3105 default:
3106 $$ = NULL;
3107 bFound = sal_True;
3108 break;
3111 break;
3112 case NT_typedef:
3113 pTypeDef = (AstTypeDef*)pDecl;
3114 if ( pTypeDef )
3115 pDecl = pTypeDef->getBaseType();
3116 break;
3117 default:
3118 $$ = NULL;
3119 bFound = sal_True;
3120 break;
3123 } else
3124 $$ = NULL;
3126 if ($$ == NULL)
3127 idlc()->error()->lookupError(*$1);
3131 at_least_one_case_branch : case_branch case_branches ;
3133 case_branches :
3134 case_branches case_branch
3135 | /* EMPTY */
3138 case_branch :
3139 at_least_one_case_label
3141 idlc()->setParseState(PS_UnionLabelSeen);
3143 element_spec
3145 idlc()->setParseState(PS_UnionElemSeen);
3147 AstScope* pScope = idlc()->scopes()->topNonNull();
3148 AstUnionLabel* pLabel = NULL;
3149 AstUnionBranch* pBranch = NULL;
3150 AstMember* pMember = $3;
3153 * Create several nodes representing branches of a union.
3154 * Add them to the enclosing scope (the union scope)
3156 if ( pScope && $1 && $3 )
3158 LabelList::iterator iter = $1->begin();
3159 LabelList::iterator end = $1->end();
3160 for (;iter != end; iter++)
3162 pLabel = *iter;
3163 if ( !pLabel )
3165 iter++;
3166 continue;
3168 pBranch = new AstUnionBranch(pLabel, pMember->getType(),
3169 pMember->getLocalName(), pScope);
3170 pScope->addDeclaration(pBranch);
3173 if ( $1 ) delete($1);
3177 at_least_one_case_label :
3178 case_label case_labels
3180 if ( $2 )
3182 $2->push_front($1);
3183 $$ = $2;
3184 } else
3186 LabelList* pLabels = new LabelList();
3187 pLabels->push_back($1);
3188 $$ = pLabels;
3193 case_labels :
3194 case_labels case_label
3196 if ( $1 )
3198 $1->push_back($2);
3199 $$ = $1;
3200 } else
3202 LabelList* pLabels = new LabelList();
3203 pLabels->push_back($2);
3204 $$ = pLabels;
3207 | /* EMPTY */
3209 $$ = NULL;
3213 case_label :
3214 IDL_DEFAULT
3216 idlc()->setParseState(PS_DefaultSeen);
3220 idlc()->setParseState(PS_LabelColonSeen);
3221 $$ = new AstUnionLabel(UL_default, NULL);
3223 | IDL_CASE
3225 idlc()->setParseState(PS_CaseSeen);
3227 const_expr
3229 idlc()->setParseState(PS_LabelExprSeen);
3233 idlc()->setParseState(PS_LabelColonSeen);
3234 $$ = new AstUnionLabel(UL_label, $3);
3238 element_spec :
3239 type_spec
3241 idlc()->setParseState(PS_UnionElemTypeSeen);
3243 declarator
3245 idlc()->setParseState(PS_UnionElemDeclSeen);
3249 idlc()->setParseState(PS_UnionElemCompleted);
3251 AstScope* pScope = idlc()->scopes()->topNonNull();
3253 * Check for illegal recursive use of type
3255 // if ( $1 && AST_illegal_recursive_type($1))
3256 // idlc()->error()->error1(EIDL_RECURSIVE_TYPE, $1);
3258 * Create a field in a union branch
3260 if ( $1 && $3 )
3262 AstType const * pType = $3->compose($1);
3263 if ( !pType )
3264 $$ = NULL;
3265 else
3266 $$ = new AstMember(pType, $3->getName(), pScope);
3267 } else
3268 $$ = NULL;
3270 if ( $3 ) delete $3;
3272 | error
3275 $$ = NULL;
3279 identifier:
3280 IDL_IDENTIFIER
3281 | IDL_GET { $$ = new OString("get"); }
3282 | IDL_SET { $$ = new OString("set"); }
3283 | IDL_PUBLISHED { $$ = new OString("published"); }
3289 * Report an error situation discovered in a production
3291 void yyerror(char const *errmsg)
3293 idlc()->error()->syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
3294 idlc()->setParseState(PS_NoState);