Stop leaking all ScPostIt instances.
[LibreOffice.git] / idlc / source / parser.y
blobda3853e3d161c758474c1c89b6f958c26805e1a6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 * parser.yy - BISON grammar for IDLC 1.0
25 #include <string.h>
27 #include <idlc/idlc.hxx>
28 #include <idlc/errorhandler.hxx>
29 #include <idlc/fehelper.hxx>
30 #include <idlc/astexpression.hxx>
31 #include <idlc/astconstants.hxx>
32 #include <idlc/astconstant.hxx>
33 #include <idlc/astarray.hxx>
34 #include <idlc/astbasetype.hxx>
35 #include <idlc/asttypedef.hxx>
36 #include <idlc/astexception.hxx>
37 #include <idlc/astmember.hxx>
38 #include <idlc/astenum.hxx>
39 #include <idlc/astsequence.hxx>
40 #include <idlc/astattribute.hxx>
41 #include <idlc/astoperation.hxx>
42 #include <idlc/astparameter.hxx>
43 #include <idlc/astinterfacemember.hxx>
44 #include <idlc/astservicemember.hxx>
45 #include <idlc/astobserves.hxx>
46 #include <idlc/astneeds.hxx>
47 #include <idlc/astunion.hxx>
49 #include "idlc/aststructinstance.hxx"
51 #include "attributeexceptions.hxx"
53 #include "rtl/strbuf.hxx"
55 #include <algorithm>
56 #include <vector>
59 #define YYDEBUG 1
60 #if !(defined MACOSX && defined PPC)
61 #define YYERROR_VERBOSE 1
62 #endif
64 using ::rtl::OUString;
65 using ::rtl::OString;
66 using ::rtl::OStringToOUString;
67 using ::rtl::OStringBuffer;
69 extern int yylex(void);
70 void yyerror(char const *);
72 void checkIdentifier(::rtl::OString* id)
74 static short check = 0;
75 if (check == 0) {
76 if (idlc()->getOptions()->isValid("-cid"))
77 check = 1;
78 else
79 check = 2;
82 if ( id->indexOf('_') >= 0 )
83 if ( (id->pData->buffer[0] >= 97 && id->pData->buffer[0] <= 122)
84 || id->pData->buffer[0] == '_') {
85 if (check == 1) {
86 ::rtl::OStringBuffer msg(25 + id->getLength());
87 msg.append("mismatched identifier '");
88 msg.append(*id);
89 msg.append("'");
90 idlc()->error()->syntaxError(idlc()->getParseState(),
91 idlc()->getLineNumber(),
92 msg.getStr());
94 else
95 idlc()->error()->warning0(WIDL_WRONG_NAMING_CONV, id->getStr());
99 void reportDoubleMemberDeclarations(
100 AstInterface::DoubleMemberDeclarations const & doubleMembers)
102 for (AstInterface::DoubleMemberDeclarations::const_iterator i(
103 doubleMembers.begin());
104 i != doubleMembers.end(); ++i)
106 idlc()->error()->error2(EIDL_DOUBLE_MEMBER, i->first, i->second);
110 void addInheritedInterface(
111 AstInterface * ifc, rtl::OString const & name, bool optional,
112 rtl::OUString const & documentation)
114 AstDeclaration * decl = ifc->lookupByName(name);
115 AstDeclaration const * resolved = resolveTypedefs(decl);
116 if (resolved != 0 && resolved->getNodeType() == NT_interface) {
117 if (idlc()->error()->checkPublished(decl)) {
118 if (!static_cast< AstInterface const * >(resolved)->isDefined()) {
119 idlc()->error()->inheritanceError(
120 NT_interface, &ifc->getScopedName(), decl);
121 } else {
122 AstInterface::DoubleDeclarations doubleDecls(
123 ifc->checkInheritedInterfaceClashes(
124 static_cast< AstInterface const * >(resolved),
125 optional));
126 if (doubleDecls.interfaces.empty()
127 && doubleDecls.members.empty())
129 ifc->addInheritedInterface(
130 static_cast< AstType * >(decl), optional,
131 documentation);
132 } else {
133 for (AstInterface::DoubleInterfaceDeclarations::iterator i(
134 doubleDecls.interfaces.begin());
135 i != doubleDecls.interfaces.end(); ++i)
137 idlc()->error()->error1(
138 EIDL_DOUBLE_INHERITANCE, *i);
140 reportDoubleMemberDeclarations(doubleDecls.members);
144 } else {
145 idlc()->error()->lookupError(
146 EIDL_INTERFACEMEMBER_LOOKUP, name, scopeAsDecl(ifc));
150 AstDeclaration const * createNamedType(
151 rtl::OString const * scopedName, DeclList const * typeArgs)
153 AstDeclaration * decl = idlc()->scopes()->topNonNull()->lookupByName(
154 *scopedName);
155 AstDeclaration const * resolved = resolveTypedefs(decl);
156 if (decl == 0) {
157 idlc()->error()->lookupError(*scopedName);
158 } else if (!idlc()->error()->checkPublished(decl)) {
159 decl = 0;
160 } else if (resolved->getNodeType() == NT_struct) {
161 if (static_cast< AstStruct const * >(resolved)->getTypeParameterCount()
162 != (typeArgs == 0 ? 0 : typeArgs->size()))
164 idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
165 decl = 0;
166 } else if (typeArgs != 0) {
167 AstScope * global = idlc()->scopes()->bottom();
168 AstDeclaration * inst = new AstStructInstance(
169 static_cast< AstType * >(decl), typeArgs, global);
170 decl = global->addDeclaration(inst);
171 if (decl != inst) {
172 delete inst;
175 } else if (decl->isType()) {
176 if (typeArgs != 0) {
177 idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
178 decl = 0;
180 } else {
181 idlc()->error()->noTypeError(decl);
182 decl = 0;
184 delete scopedName;
185 delete typeArgs;
186 return decl;
189 bool includes(AstDeclaration const * type1, AstDeclaration const * type2) {
190 OSL_ASSERT(type2 != 0);
191 if (type1 != 0) {
192 if (type1->getNodeType() == NT_instantiated_struct) {
193 AstStructInstance const * inst
194 = static_cast< AstStructInstance const * >(type1);
195 if (inst->getTypeTemplate() == type2) {
196 return true;
198 for (DeclList::const_iterator i(inst->getTypeArgumentsBegin());
199 i != inst->getTypeArgumentsEnd(); ++i)
201 if (includes(*i, type2)) {
202 return true;
205 } else if (type1 == type2) {
206 return true;
209 return false;
212 // Suppress any warnings from generated code:
213 #if defined __SUNPRO_CC
214 #pragma disable_warn
215 #elif defined _MSC_VER
216 #pragma warning(push, 1)
217 #pragma warning(disable: 4273 4701 4702)
218 #endif
221 * Declare the type of values in the grammar
223 %union {
224 ExprType etval; /* Expression type */
225 AstDeclaration* dclval; /* Declaration */
226 AstDeclaration const * cdclval;
227 DeclList * dclsval;
228 AstExpression* exval; /* expression value */
229 ExprList* exlval; /* expression list value */
230 FeDeclarator* fdval; /* declarator value */
231 FeDeclList* dlval; /* declarator list value */
232 FeInheritanceHeader* ihval; /* inheritance header value */
233 ::rtl::OString* sval; /* OString value */
234 std::vector< rtl::OString > * svals;
235 sal_Char* strval; /* sal_Char* value */
236 bool bval; /* sal_Boolean* value */
237 sal_Int64 ival; /* sal_Int64 value */
238 sal_uInt64 uval; /* sal_uInt64 value */
239 sal_uInt32 ulval; /* sal_uInt32 value */
240 double dval; /* double value */
241 float fval; /* float value */
242 StringList* slval; /* StringList value */
243 LabelList* llval; /* LabelList value */
244 AstUnionLabel* lbval; /* union label value */
245 AstMember* mval; /* member value */
246 AttributeExceptions::Part attexcpval;
247 AttributeExceptions attexcval;
251 * Token types: These are returned by the lexer
254 %token <sval> IDL_IDENTIFIER
255 %token IDL_ATTRIBUTE
256 %token IDL_BOUND
257 %token IDL_CASE
258 %token IDL_CONST
259 %token IDL_CONSTANTS
260 %token IDL_CONSTRAINED
261 %token IDL_DEFAULT
262 %token IDL_ENUM
263 %token IDL_EXCEPTION
264 %token IDL_INTERFACE
265 %token IDL_MAYBEAMBIGUOUS
266 %token IDL_MAYBEDEFAULT
267 %token IDL_MAYBEVOID
268 %token IDL_MODULE
269 %token IDL_NEEDS
270 %token IDL_OBSERVES
271 %token IDL_OPTIONAL
272 %token IDL_PROPERTY
273 %token IDL_RAISES
274 %token IDL_READONLY
275 %token IDL_REMOVABLE
276 %token IDL_SERVICE
277 %token IDL_SEQUENCE
278 %token IDL_SINGLETON
279 %token IDL_STRUCT
280 %token IDL_SWITCH
281 %token IDL_TYPEDEF
282 %token IDL_TRANSIENT
283 %token IDL_UNION
285 %token IDL_ANY
286 %token IDL_CHAR
287 %token IDL_BOOLEAN
288 %token IDL_BYTE
289 %token IDL_DOUBLE
290 %token IDL_FLOAT
291 %token IDL_HYPER
292 %token IDL_LONG
293 %token IDL_SHORT
294 %token IDL_VOID
295 %token IDL_STRING
296 %token IDL_TYPE
297 %token IDL_UNSIGNED
299 %token IDL_TRUE
300 %token IDL_FALSE
302 %token IDL_IN
303 %token IDL_OUT
304 %token IDL_INOUT
306 %token IDL_GET
307 %token IDL_SET
309 %token IDL_PUBLISHED
311 %token IDL_ELLIPSIS
313 %token <strval> IDL_LEFTSHIFT
314 %token <strval> IDL_RIGHTSHIFT
315 %token <strval> IDL_SCOPESEPARATOR
317 %token <ival> IDL_INTEGER_LITERAL
318 %token <uval> IDL_INTEGER_ULITERAL
319 %token <dval> IDL_FLOATING_PT_LITERAL
322 * These are production names:
324 %type <dclval> type_dcl
325 %type <dclval> array_declarator
326 %type <dclval> exception_name
327 %type <cdclval> array_type constructed_type_spec enum_type op_type_spec
328 %type <cdclval> sequence_type_spec simple_type_spec struct_type switch_type_spec
329 %type <cdclval> template_type_spec type_spec union_type
330 %type <cdclval> fundamental_type type_arg type_or_parameter
331 %type <dclsval> opt_raises raises exception_list
332 %type <attexcpval> opt_attribute_get_raises attribute_get_raises
333 %type <attexcpval> opt_attribute_set_raises attribute_set_raises
334 %type <dclsval> opt_type_args type_args
336 %type <sval> identifier
337 %type <sval> interface_decl
338 %type <sval> scoped_name inheritance_spec
339 %type <slval> scoped_names at_least_one_scoped_name
341 %type <etval> const_type integer_type char_type boolean_type
342 %type <etval> floating_pt_type any_type signed_int string_type
343 %type <etval> unsigned_int base_type_spec byte_type type_type
345 %type <exval> expression const_expr or_expr xor_expr and_expr
346 %type <exval> add_expr mult_expr unary_expr primary_expr shift_expr
347 %type <exval> literal positive_int_expr array_dim
349 %type <exlval> at_least_one_array_dim array_dims
351 %type <fdval> declarator simple_declarator complex_declarator
352 %type <dlval> declarators at_least_one_declarator
354 %type <ihval> exception_header structure_header interfaceheader
356 %type <ulval> flag_header opt_attrflags opt_attrflag
357 %type <ulval> direction service_interface_header service_service_header
359 %type <llval> case_labels at_least_one_case_label
360 %type <lbval> case_label
361 %type <mval> element_spec
363 %type <bval> optional_inherited_interface opt_rest opt_service_body
365 %type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises
367 %type <svals> opt_type_params type_params
371 * Grammar start here
373 start : definitions;
375 definitions :
376 definition definitions
377 | /* EMPTY */
380 definition :
381 opt_published publishable_definition
382 | module_dcl
384 idlc()->setParseState(PS_ModuleDeclSeen);
388 idlc()->setParseState(PS_NoState);
390 | error ';'
392 yyerror("definitions");
393 yyerrok;
397 opt_published:
398 IDL_PUBLISHED { idlc()->setPublished(true); }
399 | /* empty */ { idlc()->setPublished(false); }
402 publishable_definition:
403 type_dcl
405 idlc()->setParseState(PS_TypeDeclSeen);
409 idlc()->setParseState(PS_NoState);
411 | exception_dcl
413 idlc()->setParseState(PS_ExceptionDeclSeen);
417 idlc()->setParseState(PS_NoState);
419 | interface
421 idlc()->setParseState(PS_InterfaceDeclSeen);
425 idlc()->setParseState(PS_NoState);
427 | service_dcl
429 idlc()->setParseState(PS_ServiceDeclSeen);
433 idlc()->setParseState(PS_NoState);
435 | singleton_dcl
437 idlc()->setParseState(PS_SingletonDeclSeen);
441 idlc()->setParseState(PS_NoState);
443 | constants_dcl
445 idlc()->setParseState(PS_ConstantsDeclSeen);
449 idlc()->setParseState(PS_NoState);
453 module_dcl :
454 IDL_MODULE
456 idlc()->setParseState(PS_ModuleSeen);
457 idlc()->setPublished(false);
459 identifier
461 idlc()->setParseState(PS_ModuleIDSeen);
462 checkIdentifier($3);
464 AstScope* pScope = idlc()->scopes()->topNonNull();
465 AstModule* pModule = NULL;
466 AstDeclaration* pExists = NULL;
468 if ( pScope )
470 pModule = new AstModule(*$3, pScope);
471 if( (pExists = pScope->lookupForAdd(pModule)) )
473 pExists->setInMainfile(idlc()->isInMainFile());
474 pExists->setFileName(pModule->getFileName());
475 if (pExists->isPredefined())
477 pExists->setPredefined(false);
478 if (pExists->getDocumentation().getLength() == 0 &&
479 pModule->getDocumentation().getLength() > 0)
481 pExists->setDocumentation(pModule->getDocumentation());
484 delete(pModule);
485 pModule = (AstModule*)pExists;
486 } else
488 pScope->addDeclaration(pModule);
490 idlc()->scopes()->push(pModule);
492 delete $3;
496 idlc()->setParseState(PS_ModuleSqSeen);
498 definitions
500 idlc()->setParseState(PS_ModuleBodySeen);
504 idlc()->setParseState(PS_ModuleQsSeen);
506 * Finished with this module - pop it from the scope stack
508 idlc()->scopes()->pop();
512 interface :
513 interface_dcl
514 | forward_dcl
517 interface_decl :
518 IDL_INTERFACE
520 idlc()->setParseState(PS_InterfaceSeen);
522 identifier
524 idlc()->setParseState(PS_InterfaceIDSeen);
525 checkIdentifier($3);
526 $$ = $3;
530 forward_dcl :
531 interface_decl
533 idlc()->setParseState(PS_ForwardDeclSeen);
535 AstScope* pScope = idlc()->scopes()->topNonNull();
536 AstInterface* pForward = NULL;
537 AstDeclaration* pDecl = NULL;
540 * Make a new forward interface node and add it to its enclosing scope
542 if ( pScope && $1 )
544 pForward = new AstInterface(*$1, NULL, pScope);
546 pDecl = pScope->lookupByName(pForward->getScopedName());
547 if ( pDecl )
549 if ( (pDecl != pForward) &&
550 (pDecl->getNodeType() == NT_interface) )
552 delete pForward;
553 } else
555 idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(pScope), pDecl);
557 } else
560 * Add the interface to its definition scope
562 pScope->addDeclaration(pForward);
565 delete $1;
569 interface_dcl :
570 interfaceheader
572 idlc()->setParseState(PS_InterfaceHeadSeen);
574 AstScope* pScope = idlc()->scopes()->topNonNull();
575 AstInterface* pInterface = NULL;
576 AstInterface* pForward = NULL;
577 AstDeclaration* pDecl = NULL;
580 * Make a new interface node and add it to its enclosing scope
582 if ( pScope && $1 )
584 pInterface = new AstInterface(
585 *$1->getName(),
586 static_cast< AstInterface const * >(resolveTypedefs($1->getInherits())), pScope);
587 if ( pInterface &&
588 (pDecl = pScope->lookupByName(pInterface->getScopedName())) )
591 * See if we're defining a forward declared interface.
593 if (pDecl->getNodeType() == NT_interface)
595 pForward = (AstInterface*)pDecl;
596 if ( !pForward->isDefined() )
599 * Check if redefining in same scope
601 if ( pForward->getScope() != pScope )
603 if ( pForward->getScopedName() != pInterface->getScopedName() )
605 idlc()->error()->error3(EIDL_SCOPE_CONFLICT,
606 pInterface, pForward, scopeAsDecl(pScope));
609 else if ( !pInterface->isPublished()
610 && pForward->isPublished() )
612 idlc()->error()->error0(EIDL_PUBLISHED_FORWARD);
615 * All OK, set full definition
617 else
619 pForward->forwardDefined(*pInterface);
620 delete pInterface;
621 pInterface = pForward;
623 } else {
624 // special handling for XInterface because it is predefined
625 if ( pForward->isPredefined() &&
626 pForward->getScopedName() == "com::sun::star::uno::XInterface")
628 /* replace the predefined XInterface */
629 *pForward = *pInterface;
630 delete pInterface;
631 pInterface = pForward;
636 } else
639 * Add the interface to its definition scope
641 pScope->addDeclaration(pInterface);
645 * Push it on the scope stack
647 idlc()->scopes()->push(pInterface);
648 delete($1);
652 idlc()->setParseState(PS_InterfaceSqSeen);
654 exports
656 AstInterface * ifc = static_cast< AstInterface * >(
657 idlc()->scopes()->topNonNull());
658 if (!ifc->hasMandatoryInheritedInterfaces()
659 && ifc->getScopedName() != "com::sun::star::uno::XInterface")
661 addInheritedInterface(
662 ifc, rtl::OString("::com::sun::star::uno::XInterface"), false,
663 rtl::OUString());
665 ifc->setDefined();
666 idlc()->setParseState(PS_InterfaceBodySeen);
670 idlc()->setParseState(PS_InterfaceQsSeen);
672 * Done with this interface - pop it off the scopes stack
674 idlc()->scopes()->pop();
676 | error '}'
678 yyerror("interface definition");
679 yyerrok;
683 interfaceheader :
684 interface_decl inheritance_spec
686 idlc()->setParseState(PS_InheritSpecSeen);
688 $$ = new FeInheritanceHeader(NT_interface, $1, $2, 0);
689 delete $2;
693 inheritance_spec :
696 idlc()->setParseState(PS_InheritColonSeen);
698 scoped_name
700 $$ = $3;
702 | /* EMPTY */
704 $$ = NULL;
708 exports :
709 exports export
710 | /* EMPTY */
713 export :
714 attribute
716 idlc()->setParseState(PS_AttributeDeclSeen);
720 idlc()->setParseState(PS_NoState);
722 | operation
724 idlc()->setParseState(PS_OperationDeclSeen);
728 idlc()->setParseState(PS_NoState);
730 | interface_inheritance_decl
732 idlc()->setParseState(PS_InterfaceInheritanceDeclSeen);
736 idlc()->setParseState(PS_NoState);
740 attribute :
741 flag_header
742 simple_type_spec
744 idlc()->setParseState(PS_AttrTypeSeen);
746 simple_declarator
748 idlc()->setParseState(PS_AttrCompleted);
749 if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) {
750 idlc()->error()->flagError(EIDL_BAD_ATTRIBUTE_FLAGS, $1);
752 AstInterface * scope = static_cast< AstInterface * >(
753 idlc()->scopes()->top());
754 AstAttribute * attr = new AstAttribute(
755 $1, $4->compose($2), $4->getName(), scope);
756 delete $4;
757 AstInterface::DoubleMemberDeclarations doubleMembers(
758 scope->checkMemberClashes(attr));
759 if (doubleMembers.empty()) {
760 scope->addMember(attr);
761 } else {
762 reportDoubleMemberDeclarations(doubleMembers);
764 idlc()->scopes()->push(attr);
766 opt_attribute_block
768 static_cast< AstAttribute * >(idlc()->scopes()->top())->setExceptions(
769 $6.get.documentation, $6.get.exceptions, $6.set.documentation,
770 $6.set.exceptions);
771 delete $6.get.documentation;
772 delete $6.get.exceptions;
773 delete $6.set.documentation;
774 delete $6.set.exceptions;
775 idlc()->scopes()->pop();
779 flag_header :
780 '[' opt_attrflags ']'
782 idlc()->setParseState(PS_FlagHeaderSeen);
783 $$ = $2;
787 opt_attrflags :
788 opt_attrflags ',' opt_attrflag
790 if ( ($1 & $3) == $3 )
791 idlc()->error()->flagError(EIDL_DEFINED_ATTRIBUTEFLAG, $3);
793 $$ = $1 | $3;
795 | opt_attrflag
797 $$ = $1;
801 opt_attrflag :
802 IDL_ATTRIBUTE
804 idlc()->setParseState(PS_AttrSeen);
805 $$ = AF_ATTRIBUTE;
807 | IDL_PROPERTY
809 idlc()->setParseState(PS_PropertySeen);
810 $$ = AF_PROPERTY;
812 | IDL_READONLY
814 idlc()->setParseState(PS_ReadOnlySeen);
815 $$ = AF_READONLY;
817 | IDL_OPTIONAL
819 idlc()->setParseState(PS_OptionalSeen);
820 $$ = AF_OPTIONAL;
822 | IDL_MAYBEVOID
824 idlc()->setParseState(PS_MayBeVoidSeen);
825 $$ = AF_MAYBEVOID;
827 | IDL_BOUND
829 idlc()->setParseState(PS_BoundSeen);
830 $$ = AF_BOUND;
832 | IDL_CONSTRAINED
834 idlc()->setParseState(PS_ConstrainedSeen);
835 $$ = AF_CONSTRAINED;
837 | IDL_TRANSIENT
839 idlc()->setParseState(PS_TransientSeen);
840 $$ = AF_TRANSIENT;
842 | IDL_MAYBEAMBIGUOUS
844 idlc()->setParseState(PS_MayBeAmbigiousSeen);
845 $$ = AF_MAYBEAMBIGUOUS;
847 | IDL_MAYBEDEFAULT
849 idlc()->setParseState(PS_MayBeDefaultSeen);
850 $$ = AF_MAYBEDEFAULT;
852 | IDL_REMOVABLE
854 idlc()->setParseState(PS_RemoveableSeen);
855 $$ = AF_REMOVABLE;
857 | error ']'
859 yyerror("unknown property|attribute flag");
860 yyerrok;
864 opt_attribute_block:
865 '{' attribute_block_rest { $$ = $2; }
866 | /* empty */
868 $$.get.documentation = 0;
869 $$.get.exceptions = 0;
870 $$.set.documentation = 0;
871 $$.set.exceptions = 0;
875 attribute_block_rest:
876 opt_attribute_raises '}'
877 | error '}'
879 yyerror("bad attribute raises block");
880 yyerrok;
881 $$.get.documentation = 0;
882 $$.get.exceptions = 0;
883 $$.set.documentation = 0;
884 $$.set.exceptions = 0;
888 opt_attribute_raises:
889 attribute_get_raises
890 opt_attribute_set_raises
892 $$.get = $1;
893 $$.set = $2;
895 | attribute_set_raises
896 opt_attribute_get_raises
898 $$.get = $2;
899 $$.set = $1;
901 | /* empty */
903 $$.get.documentation = 0;
904 $$.get.exceptions = 0;
905 $$.set.documentation = 0;
906 $$.set.exceptions = 0;
910 opt_attribute_get_raises:
911 attribute_get_raises
912 | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
915 attribute_get_raises:
916 IDL_GET raises ';'
918 $$.documentation = new rtl::OUString(
919 rtl::OStringToOUString(
920 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
921 $$.exceptions = $2;
925 opt_attribute_set_raises:
926 attribute_set_raises
927 | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
930 attribute_set_raises:
931 IDL_SET
933 if (static_cast< AstAttribute * >(idlc()->scopes()->top())->
934 isReadonly())
936 idlc()->error()->error0(EIDL_READONLY_ATTRIBUTE_SET_EXCEPTIONS);
939 raises ';'
941 $$.documentation = new rtl::OUString(
942 rtl::OStringToOUString(
943 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
944 $$.exceptions = $3;
948 operation :
949 op_type_spec
951 idlc()->setParseState(PS_OpTypeSeen);
953 identifier
955 idlc()->setParseState(PS_OpIDSeen);
956 checkIdentifier($3);
958 AstInterface * pScope = static_cast< AstInterface * >(
959 idlc()->scopes()->top());
960 AstOperation* pOp = NULL;
963 * Create a node representing an operation on an interface
964 * and add it to its enclosing scope
966 if ( pScope && $1 )
968 AstType *pType = (AstType*)$1;
969 if ( !pType || (pType->getNodeType() == NT_exception) )
971 // type ERROR
972 } else
974 pOp = new AstOperation(pType, *$3, pScope);
976 AstInterface::DoubleMemberDeclarations doubleMembers(
977 pScope->checkMemberClashes(pOp));
978 if (doubleMembers.empty()) {
979 pScope->addMember(pOp);
980 } else {
981 reportDoubleMemberDeclarations(doubleMembers);
985 delete $3;
987 * Push the operation scope onto the scopes stack
989 idlc()->scopes()->push(pOp);
993 idlc()->setParseState(PS_OpSqSeen);
995 parameters
997 idlc()->setParseState(PS_OpParsCompleted);
1001 idlc()->setParseState(PS_OpQsSeen);
1003 opt_raises
1005 AstScope* pScope = idlc()->scopes()->topNonNull();
1006 AstOperation* pOp = NULL;
1008 * Add exceptions and context to the operation
1010 if ( pScope && pScope->getScopeNodeType() == NT_operation)
1012 pOp = (AstOperation*)pScope;
1014 if ( pOp )
1015 pOp->setExceptions($11);
1017 delete $11;
1019 * Done with this operation. Pop its scope from the scopes stack
1021 idlc()->scopes()->pop();
1025 op_type_spec :
1026 simple_type_spec
1027 | IDL_VOID
1029 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void);
1033 parameters :
1034 parameter
1035 | parameters
1038 idlc()->setParseState(PS_OpParCommaSeen);
1040 parameter
1041 | /* EMPTY */
1042 | error ','
1044 yyerror("parameter definition");
1045 yyerrok;
1049 parameter :
1051 direction
1054 idlc()->setParseState(PS_OpParDirSeen);
1056 simple_type_spec
1058 idlc()->setParseState(PS_OpParTypeSeen);
1060 opt_rest
1061 declarator
1063 idlc()->setParseState(PS_OpParDeclSeen);
1065 AstOperation * pScope = static_cast< AstOperation * >(
1066 idlc()->scopes()->top());
1067 AstParameter* pParam = NULL;
1070 * Create a node representing an argument to an operation
1071 * Add it to the enclosing scope (the operation scope)
1073 if ( pScope && $5 && $8 )
1075 AstType const * pType = $8->compose($5);
1076 if ( pType )
1078 if (pScope->isConstructor() && $2 != DIR_IN) {
1079 idlc()->error()->error0(EIDL_CONSTRUCTOR_PARAMETER_NOT_IN);
1081 if (pScope->isVariadic()) {
1082 idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_LAST);
1084 if ($7) {
1085 AstDeclaration const * type = resolveTypedefs(pType);
1086 if (type->getNodeType() != NT_predefined
1087 || (static_cast< AstBaseType const * >(type)->
1088 getExprType() != ET_any))
1090 idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_ANY);
1092 if (pScope->isConstructor()) {
1093 if (pScope->getIteratorBegin()
1094 != pScope->getIteratorEnd())
1096 idlc()->error()->error0(
1097 EIDL_CONSTRUCTOR_REST_PARAMETER_NOT_FIRST);
1099 } else {
1100 idlc()->error()->error0(EIDL_METHOD_HAS_REST_PARAMETER);
1104 pParam = new AstParameter(
1105 static_cast< Direction >($2), $7, pType, $8->getName(),
1106 pScope);
1108 if ( !$8->checkType($5) )
1110 // WARNING
1113 pScope->addDeclaration(pParam);
1117 | error
1118 simple_type_spec
1120 idlc()->setParseState(PS_NoState);
1121 yyerrok;
1125 direction :
1126 IDL_IN
1128 $$ = DIR_IN;
1130 | IDL_OUT
1132 $$ = DIR_OUT;
1134 | IDL_INOUT
1136 $$ = DIR_INOUT;
1140 opt_rest:
1141 IDL_ELLIPSIS
1143 $$ = true;
1145 | /* empty */
1147 $$ = false;
1151 opt_raises:
1152 raises
1153 | /* empty */
1155 $$ = 0;
1159 raises:
1160 IDL_RAISES
1162 idlc()->setParseState(PS_RaiseSeen);
1166 idlc()->setParseState(PS_RaiseSqSeen);
1168 exception_list
1171 idlc()->setParseState(PS_RaiseQsSeen);
1172 $$ = $5;
1176 exception_list:
1177 exception_name
1179 $$ = new DeclList;
1180 $$->push_back($1);
1182 | exception_list ',' exception_name
1184 $1->push_back($3);
1185 $$ = $1;
1189 exception_name:
1190 scoped_name
1192 // The topmost scope is either an AstOperation (for interface methods
1193 // and service constructors) or an AstAttribute (for interface
1194 // attributes), so look up exception names in the next-to-topmost scope:
1195 AstDeclaration * decl = idlc()->scopes()->nextToTop()->lookupByName(
1196 *$1);
1197 if (decl == 0) {
1198 idlc()->error()->lookupError(*$1);
1199 } else if (!idlc()->error()->checkPublished(decl)) {
1200 decl = 0;
1201 } else if (decl->getNodeType() != NT_exception) {
1202 idlc()->error()->error1(EIDL_ILLEGAL_RAISES, decl);
1203 decl = 0;
1205 delete $1;
1206 $$ = decl;
1210 interface_inheritance_decl:
1211 optional_inherited_interface
1212 IDL_INTERFACE
1214 idlc()->setParseState(PS_ServiceIFHeadSeen);
1216 scoped_name
1218 AstInterface * ifc = static_cast< AstInterface * >(
1219 idlc()->scopes()->top());
1220 if (ifc->usesSingleInheritance()) {
1221 idlc()->error()->error0(EIDL_MIXED_INHERITANCE);
1222 } else {
1223 addInheritedInterface(
1224 ifc, *$4, $1,
1225 rtl::OStringToOUString(
1226 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
1228 delete $4;
1232 optional_inherited_interface:
1233 '[' IDL_OPTIONAL ']' { $$ = true; }
1234 | /* EMPTY */ { $$ = false; }
1237 constants_exports :
1238 constants_export constants_exports
1239 | /* EMPTY */
1242 constants_export :
1243 IDL_CONST
1245 idlc()->setParseState(PS_ConstSeen);
1247 const_type
1249 idlc()->setParseState(PS_ConstTypeSeen);
1251 identifier
1253 idlc()->setParseState(PS_ConstIDSeen);
1254 checkIdentifier($5);
1258 idlc()->setParseState(PS_ConstAssignSeen);
1260 expression
1262 idlc()->setParseState(PS_ConstExprSeen);
1264 AstScope* pScope = idlc()->scopes()->topNonNull();
1265 AstConstant* pConstant = NULL;
1267 if ( $9 && pScope )
1269 if ( !$9->coerce($3) )
1271 idlc()->error()->coercionError($9, $3);
1272 } else
1274 pConstant = new AstConstant($3, $9, *$5, pScope);
1275 pScope->addDeclaration(pConstant);
1278 delete $5;
1280 idlc()->setParseState(PS_ConstantDeclSeen);
1282 ';' {};
1285 constants_dcl :
1286 IDL_CONSTANTS
1288 idlc()->setParseState(PS_ConstantsSeen);
1290 identifier
1292 idlc()->setParseState(PS_ConstantsIDSeen);
1293 checkIdentifier($3);
1297 idlc()->setParseState(PS_ConstantsSqSeen);
1299 AstScope* pScope = idlc()->scopes()->topNonNull();
1300 AstConstants* pConstants = NULL;
1301 AstDeclaration* pExists = NULL;
1303 if ( pScope )
1305 pConstants = new AstConstants(*$3, pScope);
1306 if( (pExists = pScope->lookupForAdd(pConstants)) )
1308 pExists->setInMainfile(idlc()->isInMainFile());
1309 delete(pConstants);
1310 pConstants = (AstConstants*)pExists;
1311 } else
1313 pScope->addDeclaration(pConstants);
1315 idlc()->scopes()->push(pConstants);
1317 delete $3;
1319 constants_exports
1321 idlc()->setParseState(PS_ConstantsBodySeen);
1325 idlc()->setParseState(PS_ConstantsQsSeen);
1327 * Finished with this constants - pop it from the scope stack
1329 idlc()->scopes()->pop();
1333 expression : const_expr ;
1335 const_expr : or_expr ;
1337 or_expr :
1338 xor_expr
1339 | or_expr '|' xor_expr
1341 $$ = new AstExpression(EC_or, $1, $3);
1345 xor_expr :
1346 and_expr
1347 | xor_expr '^' and_expr
1349 $$ = new AstExpression(EC_xor, $1, $3);
1353 and_expr :
1354 shift_expr
1355 | and_expr '&' shift_expr
1357 $$ = new AstExpression(EC_and, $1, $3);
1361 shift_expr :
1362 add_expr
1363 | shift_expr IDL_LEFTSHIFT add_expr
1365 $$ = new AstExpression(EC_left, $1, $3);
1367 | shift_expr IDL_RIGHTSHIFT add_expr
1369 $$ = new AstExpression(EC_right, $1, $3);
1373 add_expr :
1374 mult_expr
1375 | add_expr '+' mult_expr
1377 $$ = new AstExpression(EC_add, $1, $3);
1379 | add_expr '-' mult_expr
1381 $$ = new AstExpression(EC_minus, $1, $3);
1385 mult_expr :
1386 unary_expr
1387 | mult_expr '*' unary_expr
1389 $$ = new AstExpression(EC_mul, $1, $3);
1391 | mult_expr '/' unary_expr
1393 $$ = new AstExpression(EC_div, $1, $3);
1395 | mult_expr '%' unary_expr
1397 $$ = new AstExpression(EC_mod, $1, $3);
1401 unary_expr :
1402 primary_expr
1403 | '+' primary_expr
1405 $$ = new AstExpression(EC_u_plus, $2, NULL);
1407 | '-' primary_expr
1409 $$ = new AstExpression(EC_u_minus, $2, NULL);
1411 | '~' primary_expr
1416 primary_expr :
1417 scoped_name
1420 * An expression which is a scoped name is not resolved now,
1421 * but only when it is evaluated (such as when it is assigned
1422 * as a constant value)
1424 $$ = new AstExpression($1);
1426 | literal
1427 | '(' const_expr ')'
1429 $$ = $2;
1433 literal :
1434 IDL_INTEGER_LITERAL
1436 $$ = new AstExpression($1);
1438 | IDL_INTEGER_ULITERAL
1440 $$ = new AstExpression($1);
1442 | IDL_FLOATING_PT_LITERAL
1444 $$ = new AstExpression($1);
1446 | IDL_TRUE
1448 $$ = new AstExpression((sal_Int32)1, ET_boolean);
1450 | IDL_FALSE
1452 $$ = new AstExpression((sal_Int32)0, ET_boolean);
1456 positive_int_expr :
1457 const_expr
1459 $1->evaluate(EK_const);
1460 if ( !$1->coerce(ET_ulong) )
1462 idlc()->error()->coercionError($1, ET_ulong);
1463 delete $1;
1464 $$ = NULL;
1469 const_type :
1470 integer_type
1471 | byte_type
1472 | boolean_type
1473 | floating_pt_type
1474 | scoped_name
1476 AstScope* pScope = idlc()->scopes()->topNonNull();
1477 AstDeclaration const * type = 0;
1480 * If the constant's type is a scoped name, it must resolve
1481 * to a scalar constant type
1483 if ( pScope && (type = pScope->lookupByName(*$1)) ) {
1484 if (!idlc()->error()->checkPublished(type))
1486 type = 0;
1487 $$ = ET_none;
1489 else
1491 type = resolveTypedefs(type);
1492 if (type->getNodeType() == NT_predefined)
1494 $$ = static_cast< AstBaseType const * >(type)->
1495 getExprType();
1496 } else
1497 $$ = ET_any;
1499 } else
1500 $$ = ET_any;
1504 exception_header :
1505 IDL_EXCEPTION
1507 idlc()->setParseState(PS_ExceptSeen);
1509 identifier
1511 idlc()->setParseState(PS_ExceptIDSeen);
1512 checkIdentifier($3);
1514 inheritance_spec
1516 idlc()->setParseState(PS_InheritSpecSeen);
1518 $$ = new FeInheritanceHeader(NT_exception, $3, $5, 0);
1519 delete $5;
1523 exception_dcl :
1524 exception_header
1526 idlc()->setParseState(PS_ExceptHeaderSeen);
1528 AstScope* pScope = idlc()->scopes()->topNonNull();
1529 AstException* pExcept = NULL;
1531 if ( pScope )
1533 AstException* pBase = static_cast< AstException* >(
1534 $1->getInherits());
1535 pExcept = new AstException(*$1->getName(), pBase, pScope);
1536 pScope->addDeclaration(pExcept);
1539 * Push the scope of the exception on the scopes stack
1541 idlc()->scopes()->push(pExcept);
1542 delete $1;
1546 idlc()->setParseState(PS_ExceptSqSeen);
1548 members
1550 idlc()->setParseState(PS_ExceptBodySeen);
1554 idlc()->setParseState(PS_ExceptQsSeen);
1555 /* this exception is finished, pop its scope from the stack */
1556 idlc()->scopes()->pop();
1560 property :
1561 flag_header
1562 simple_type_spec
1564 idlc()->setParseState(PS_PropertyTypeSeen);
1566 at_least_one_declarator
1568 idlc()->setParseState(PS_PropertyCompleted);
1570 AstScope* pScope = idlc()->scopes()->topNonNull();
1571 AstAttribute* pAttr = NULL;
1572 FeDeclList* pList = $4;
1573 FeDeclarator* pDecl = NULL;
1574 AstType const * pType = NULL;
1576 if ( pScope->getScopeNodeType() == NT_singleton )
1578 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1579 } else
1581 if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
1582 idlc()->error()->flagError(EIDL_WRONGATTRIBUTEKEYWORD, AF_ATTRIBUTE);
1584 if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
1585 idlc()->error()->flagError(EIDL_MISSINGATTRIBUTEKEYWORD, AF_PROPERTY);
1588 * Create nodes representing attributes and add them to the
1589 * enclosing scope
1591 if ( pScope && $2 && pList )
1593 FeDeclList::iterator iter = pList->begin();
1594 FeDeclList::iterator end = pList->end();
1596 while (iter != end)
1598 pDecl = (*iter);
1599 if ( !pDecl )
1601 iter++;
1602 continue;
1605 pType = pDecl->compose($2);
1607 if ( !pType )
1609 iter++;
1610 continue;
1613 pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);
1615 pScope->addDeclaration(pAttr);
1616 iter++;
1617 delete pDecl;
1622 if ( pList )
1623 delete pList;
1625 | error ';'
1627 yyerror("property");
1628 yyerrok;
1632 service_exports :
1633 service_exports service_export
1634 | /* EMPTY */
1637 service_export :
1638 service_interface_header
1639 at_least_one_scoped_name
1642 idlc()->setParseState(PS_ServiceMemberSeen);
1644 AstScope* pScope = idlc()->scopes()->topNonNull();
1645 AstDeclaration* pDecl = NULL;
1646 AstInterfaceMember* pIMember = NULL;
1648 if ( pScope->getScopeNodeType() == NT_singleton )
1650 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1651 } else
1654 * Create a node representing a class member.
1655 * Store it in the enclosing scope
1657 if ( pScope && $2 )
1659 StringList::iterator iter = $2->begin();
1660 StringList::iterator end = $2->end();
1662 while ( iter != end )
1664 pDecl = pScope->lookupByName(*iter);
1665 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1667 /* we relax the strict published check and allow to add new
1668 * interfaces if they are optional
1670 bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
1671 if ( idlc()->error()->checkPublished(pDecl, bOptional) )
1673 pIMember = new AstInterfaceMember(
1674 $1, (AstInterface*)pDecl, *iter, pScope);
1675 pScope->addDeclaration(pIMember);
1677 } else
1679 idlc()->error()->
1680 lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1682 iter++;
1686 delete $2;
1688 | service_service_header
1689 at_least_one_scoped_name
1692 idlc()->setParseState(PS_ServiceMemberSeen);
1694 AstScope* pScope = idlc()->scopes()->topNonNull();
1695 AstDeclaration* pDecl = NULL;
1696 AstServiceMember* pSMember = NULL;
1699 * Create a node representing a class member.
1700 * Store it in the enclosing scope
1702 if ( pScope && $2 )
1704 StringList::iterator iter = $2->begin();
1705 StringList::iterator end = $2->end();
1707 while ( iter != end )
1709 pDecl = pScope->lookupByName(*iter);
1710 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1712 if ( static_cast< AstService * >(pDecl)->isSingleInterfaceBasedService() || (pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0) )
1713 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1714 else if ( idlc()->error()->checkPublished(pDecl) )
1716 pSMember = new AstServiceMember(
1717 $1, (AstService*)pDecl, *iter, pScope);
1718 pScope->addDeclaration(pSMember);
1720 } else
1722 idlc()->error()->
1723 lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1725 iter++;
1728 delete $2;
1730 | IDL_OBSERVES
1731 at_least_one_scoped_name
1734 idlc()->setParseState(PS_ServiceMemberSeen);
1736 AstScope* pScope = idlc()->scopes()->topNonNull();
1737 AstDeclaration* pDecl = NULL;
1738 AstObserves* pObserves = NULL;
1740 if ( pScope->getScopeNodeType() == NT_singleton )
1742 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1743 } else
1746 * Create a node representing a class member.
1747 * Store it in the enclosing scope
1749 if ( pScope && $2 )
1751 StringList::iterator iter = $2->begin();
1752 StringList::iterator end = $2->end();
1754 while ( iter != end )
1756 pDecl = pScope->lookupByName(*iter);
1757 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1759 pObserves = new AstObserves((AstInterface*)pDecl, *iter, pScope);
1760 pScope->addDeclaration(pObserves);
1761 } else
1763 idlc()->error()->
1764 lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1766 iter++;
1770 delete $2;
1772 | IDL_NEEDS
1773 at_least_one_scoped_name
1776 idlc()->setParseState(PS_ServiceMemberSeen);
1778 AstScope* pScope = idlc()->scopes()->topNonNull();
1779 AstDeclaration* pDecl = NULL;
1780 AstNeeds* pNeeds = NULL;
1782 if ( pScope->getScopeNodeType() == NT_singleton )
1784 idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1785 } else
1788 * Create a node representing a class member.
1789 * Store it in the enclosing scope
1791 if ( pScope && $2 )
1793 StringList::iterator iter = $2->begin();
1794 StringList::iterator end = $2->end();
1796 while ( iter != end )
1798 pDecl = pScope->lookupByName(*iter);
1799 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1801 pNeeds = new AstNeeds((AstService*)pDecl, *iter, pScope);
1802 pScope->addDeclaration(pNeeds);
1803 } else
1805 idlc()->error()->
1806 lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1808 iter++;
1812 delete $2;
1814 | property
1817 idlc()->setParseState(PS_PropertyDeclSeen);
1821 service_interface_header :
1822 IDL_INTERFACE
1824 idlc()->setParseState(PS_ServiceIFHeadSeen);
1825 $$ = AF_INVALID;
1827 | flag_header
1828 IDL_INTERFACE
1830 idlc()->setParseState(PS_ServiceIFHeadSeen);
1831 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1832 idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1833 $$ = $1;
1837 service_service_header :
1838 IDL_SERVICE
1840 idlc()->setParseState(PS_ServiceSHeadSeen);
1841 $$ = AF_INVALID;
1843 | flag_header
1844 IDL_SERVICE
1846 idlc()->setParseState(PS_ServiceSHeadSeen);
1847 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1848 idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1849 $$ = $1;
1853 service_dcl :
1854 IDL_SERVICE
1856 idlc()->setParseState(PS_ServiceSeen);
1858 identifier
1860 idlc()->setParseState(PS_ServiceIDSeen);
1861 checkIdentifier($3);
1863 AstScope* pScope = idlc()->scopes()->topNonNull();
1864 AstService* pService = NULL;
1867 * Make a new service and add it to the enclosing scope
1869 if (pScope != NULL)
1871 pService = new AstService(*$3, pScope);
1872 pScope->addDeclaration(pService);
1874 delete $3;
1876 * Push it on the stack
1878 idlc()->scopes()->push(pService);
1880 service_dfn
1882 /* this service is finished, pop its scope from the stack */
1883 idlc()->scopes()->pop();
1887 service_dfn:
1888 service_interface_dfn
1889 | service_obsolete_dfn
1892 service_interface_dfn:
1893 ':' scoped_name
1895 AstScope * scope = idlc()->scopes()->nextToTop();
1896 // skip the scope pushed by service_dcl
1897 AstDeclaration * decl = scope->lookupByName(*$2);
1898 if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
1899 if (idlc()->error()->checkPublished(decl)) {
1900 idlc()->scopes()->top()->addDeclaration(decl);
1902 } else {
1903 idlc()->error()->lookupError(
1904 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
1906 delete $2;
1908 opt_service_body
1910 AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
1911 if (s != 0) {
1912 s->setSingleInterfaceBasedService();
1913 s->setDefaultConstructor(!$4);
1918 opt_service_body:
1919 service_body { $$ = true; }
1920 | /* empty */ { $$ = false; }
1923 service_body:
1925 constructors
1929 constructors:
1930 constructors constructor
1931 | /* empty */
1934 constructor:
1935 identifier
1937 checkIdentifier($1);
1938 AstScope * scope = idlc()->scopes()->top();
1939 AstOperation * ctor = new AstOperation(0, *$1, scope);
1940 delete $1;
1941 scope->addDeclaration(ctor);
1942 idlc()->scopes()->push(ctor);
1945 parameters
1947 opt_raises
1949 static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions(
1950 $6);
1951 delete $6;
1952 idlc()->scopes()->pop();
1953 if (static_cast< AstService * >(idlc()->scopes()->top())->
1954 checkLastConstructor())
1956 idlc()->error()->error0(EIDL_SIMILAR_CONSTRUCTORS);
1962 singleton_dcl :
1963 IDL_SINGLETON
1965 idlc()->setParseState(PS_SingletonSeen);
1967 identifier
1969 idlc()->setParseState(PS_SingletonIDSeen);
1970 checkIdentifier($3);
1972 AstScope* pScope = idlc()->scopes()->topNonNull();
1973 AstService* pService = NULL;
1976 * Make a new service and add it to the enclosing scope
1978 if (pScope != NULL)
1980 pService = new AstService(NT_singleton, *$3, pScope);
1981 pScope->addDeclaration(pService);
1983 delete $3;
1985 * Push it on the stack
1987 idlc()->scopes()->push(pService);
1989 singleton_dfn
1991 /* this singelton is finished, pop its scope from the stack */
1992 idlc()->scopes()->pop();
1996 singleton_dfn:
1997 singleton_interface_dfn
1998 | service_obsolete_dfn
2001 singleton_interface_dfn:
2002 ':' scoped_name
2004 AstScope * scope = idlc()->scopes()->nextToTop();
2005 // skip the scope (needlessly) pushed by singleton_dcl
2006 AstDeclaration * decl = scope->lookupByName(*$2);
2007 if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
2008 if (idlc()->error()->checkPublished(decl)) {
2009 idlc()->scopes()->top()->addDeclaration(decl);
2011 } else {
2012 idlc()->error()->lookupError(
2013 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
2015 delete $2;
2019 service_obsolete_dfn:
2022 idlc()->setParseState(
2023 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2024 ? PS_ServiceSqSeen : PS_SingletonSqSeen);
2026 service_exports
2028 idlc()->setParseState(
2029 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2030 ? PS_ServiceBodySeen : PS_SingletonBodySeen);
2034 idlc()->setParseState(
2035 idlc()->scopes()->top()->getScopeNodeType() == NT_service
2036 ? PS_ServiceQsSeen : PS_SingletonQsSeen);
2040 type_dcl :
2041 IDL_TYPEDEF
2043 idlc()->setParseState(PS_TypedefSeen);
2045 type_declarator {}
2046 | struct_type {}
2047 | union_type {}
2048 | enum_type {}
2051 type_declarator :
2052 type_spec
2054 idlc()->setParseState(PS_TypeSpecSeen);
2055 if ($1 != 0 && $1->getNodeType() == NT_instantiated_struct) {
2056 idlc()->error()->error0(EIDL_INSTANTIATED_STRUCT_TYPE_TYPEDEF);
2059 at_least_one_declarator
2061 idlc()->setParseState(PS_DeclaratorsSeen);
2063 AstScope* pScope = idlc()->scopes()->topNonNull();
2064 AstTypeDef* pTypeDef = NULL;
2065 FeDeclList* pList = $3;
2066 FeDeclarator* pDecl = NULL;
2067 AstType const * pType = NULL;
2070 * Create nodes representing typedefs and add them to the
2071 * enclosing scope
2073 if ( pScope && $1 && pList )
2075 FeDeclList::iterator iter = pList->begin();
2076 FeDeclList::iterator end = pList->end();
2078 while (iter != end)
2080 pDecl = (*iter);
2081 if ( !pDecl )
2083 iter++;
2084 continue;
2087 pType = pDecl->compose($1);
2089 if ( !pType )
2091 iter++;
2092 continue;
2095 pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);
2097 pScope->addDeclaration(pTypeDef);
2098 iter++;
2099 delete pDecl;
2101 delete pList;
2106 at_least_one_declarator :
2107 declarator declarators
2109 if ( $2 )
2111 $2->push_back($1);
2112 $$ = $2;
2113 } else
2115 FeDeclList* pList = new FeDeclList();
2116 pList->push_back($1);
2117 $$ = pList;
2122 declarators :
2123 declarators
2126 idlc()->setParseState(PS_DeclsCommaSeen);
2128 declarator
2130 idlc()->setParseState(PS_DeclsDeclSeen);
2131 if ( $1 )
2133 $1->push_back($4);
2134 $$ = $1;
2135 } else
2137 FeDeclList* pList = new FeDeclList();
2138 pList->push_back($4);
2139 $$ = pList;
2142 | /* EMPTY */
2144 $$ = NULL;
2148 declarator :
2149 simple_declarator
2150 | complex_declarator
2153 simple_declarator :
2154 identifier
2156 // For historic reasons, the struct com.sun.star.uno.Uik contains
2157 // members with illegal names (of the form "m_DataN"); avoid useless
2158 // warnings about them:
2159 AstScope * scope = idlc()->scopes()->top();
2160 if (scope == 0 || scope->getScopeNodeType() != NT_struct
2161 || (scopeAsDecl(scope)->getScopedName()
2162 != "com::sun::star::uno::Uik"))
2164 checkIdentifier($1);
2167 $$ = new FeDeclarator(*$1, FeDeclarator::FD_simple, NULL);
2168 delete $1;
2172 complex_declarator :
2173 array_declarator
2175 $$ = new FeDeclarator($1->getLocalName(), FeDeclarator::FD_complex, $1);
2179 array_declarator :
2180 identifier
2182 idlc()->setParseState(PS_ArrayIDSeen);
2183 checkIdentifier($1);
2185 at_least_one_array_dim
2187 idlc()->setParseState(PS_ArrayCompleted);
2188 $$ = new AstArray(*$1, NULL, *$3, idlc()->scopes()->bottom());
2189 delete $1;
2193 at_least_one_array_dim :
2194 array_dim array_dims
2196 if( $2 )
2198 $2->push_front($1);
2199 $$ = $2;
2200 } else
2202 ExprList* pList = new ExprList();
2203 pList->push_back($1);
2204 $$ = pList;
2209 array_dims :
2210 array_dims array_dim
2212 if( $1 )
2214 $1->push_back($2);
2215 $$ = $1;
2216 } else
2218 ExprList* pList = new ExprList();
2219 pList->push_back($2);
2220 $$ = pList;
2223 | /* EMPTY */
2225 $$ = NULL;
2229 array_dim :
2232 idlc()->setParseState(PS_DimSqSeen);
2234 positive_int_expr
2236 idlc()->setParseState(PS_DimExprSeen);
2240 idlc()->setParseState(PS_DimQsSeen);
2242 * Array dimensions are expressions which must be coerced to
2243 * positive integers
2245 if ( !$3 || !$3->coerce(ET_uhyper) )
2247 idlc()->error()->coercionError($3, ET_uhyper);
2248 $$ = NULL;
2249 } else
2250 $$ = $3;
2254 at_least_one_scoped_name :
2255 scoped_name scoped_names
2257 if ($2)
2259 $2->push_front(*$1);
2260 $$ = $2;
2261 } else
2263 StringList* pNames = new StringList();
2264 pNames->push_back(*$1);
2265 $$ = pNames;
2267 delete($1);
2271 scoped_names :
2272 scoped_names
2275 idlc()->setParseState(PS_SNListCommaSeen);
2277 scoped_name
2279 idlc()->setParseState(PS_ScopedNameSeen);
2280 if ($1)
2282 $1->push_back(*$4);
2283 $$ = $1;
2284 } else
2286 StringList* pNames = new StringList();
2287 pNames->push_back(*$4);
2288 $$ = pNames;
2290 delete($4);
2292 | /* EMPTY */
2294 $$ = NULL;
2298 scoped_name :
2299 identifier
2301 idlc()->setParseState(PS_SN_IDSeen);
2302 checkIdentifier($1);
2303 $$ = $1;
2305 | IDL_SCOPESEPARATOR
2307 idlc()->setParseState(PS_ScopeDelimSeen);
2309 identifier
2311 checkIdentifier($3);
2312 OString* pName = new OString("::");
2313 *pName += *$3;
2314 delete $3;
2315 $$ = pName;
2317 | scoped_name
2318 IDL_SCOPESEPARATOR
2321 identifier
2323 checkIdentifier($4);
2324 *$1 += ::rtl::OString("::");
2325 *$1 += *$4;
2326 delete $4;
2327 $$ = $1;
2331 type_spec :
2332 simple_type_spec
2333 | constructed_type_spec
2336 simple_type_spec :
2337 fundamental_type
2338 | scoped_name opt_type_args
2340 $$ = createNamedType($1, $2);
2344 fundamental_type:
2345 base_type_spec
2347 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2349 | template_type_spec
2352 opt_type_args:
2353 '<' type_args '>' { $$ = $2; }
2354 | /* empty */ { $$ = 0; }
2357 type_args:
2358 type_arg
2360 $$ = new DeclList;
2361 $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
2363 | type_args ',' type_arg
2365 $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
2366 $$ = $1;
2370 type_arg:
2371 simple_type_spec
2373 if ($1 != 0 && static_cast< AstType const * >($1)->isUnsigned()) {
2374 idlc()->error()->error0(EIDL_UNSIGNED_TYPE_ARGUMENT);
2376 $$ = $1;
2380 base_type_spec :
2381 integer_type
2382 | floating_pt_type
2383 | char_type
2384 | boolean_type
2385 | byte_type
2386 | any_type
2387 | type_type
2388 | string_type
2391 integer_type :
2392 signed_int
2393 | unsigned_int
2396 signed_int :
2397 IDL_LONG
2399 $$ = ET_long;
2401 | IDL_HYPER
2403 $$ = ET_hyper;
2405 | IDL_SHORT
2407 $$ = ET_short;
2411 unsigned_int :
2412 IDL_UNSIGNED IDL_LONG
2414 $$ = ET_ulong;
2416 | IDL_UNSIGNED IDL_HYPER
2418 $$ = ET_uhyper;
2420 | IDL_UNSIGNED IDL_SHORT
2422 $$ = ET_ushort;
2426 floating_pt_type :
2427 IDL_DOUBLE
2429 $$ = ET_double;
2431 | IDL_FLOAT
2433 $$ = ET_float;
2437 char_type :
2438 IDL_CHAR
2440 $$ = ET_char;
2444 byte_type :
2445 IDL_BYTE
2447 $$ = ET_byte;
2451 boolean_type :
2452 IDL_BOOLEAN
2454 $$ = ET_boolean;
2458 any_type :
2459 IDL_ANY
2461 $$ = ET_any;
2465 type_type :
2466 IDL_TYPE
2468 $$ = ET_type;
2472 string_type :
2473 IDL_STRING
2475 $$ = ET_string;
2479 template_type_spec :
2480 sequence_type_spec
2481 | array_type
2484 constructed_type_spec :
2485 struct_type
2486 | union_type
2487 | enum_type
2490 array_type :
2491 simple_type_spec
2493 idlc()->setParseState(PS_ArrayTypeSeen);
2495 at_least_one_array_dim
2497 idlc()->setParseState(PS_ArrayCompleted);
2499 AstScope* pScope = idlc()->scopes()->bottom();
2500 AstDeclaration* pDecl = NULL;
2501 AstDeclaration* pArray = NULL;
2503 if ( $1 )
2505 pArray = new AstArray((AstType*)$1, *$3, idlc()->scopes()->bottom());
2506 if ( pScope )
2508 pDecl = pScope->addDeclaration(pArray);
2509 if ( pArray != pDecl )
2511 // if array type already defined then use it
2512 delete pArray;
2513 pArray = pDecl;
2517 $$ = pArray;
2521 sequence_type_spec :
2522 IDL_SEQUENCE
2524 idlc()->setParseState(PS_SequenceSeen);
2526 * Push a sequence marker on scopes stack
2528 idlc()->scopes()->push(NULL);
2532 idlc()->setParseState(PS_SequenceSqSeen);
2534 simple_type_spec
2536 idlc()->setParseState(PS_SequenceTypeSeen);
2540 idlc()->setParseState(PS_SequenceQsSeen);
2542 * Remove sequence marker from scopes stack
2544 if (idlc()->scopes()->top() == NULL)
2545 idlc()->scopes()->pop();
2547 * Create a node representing a sequence
2549 AstScope* pScope = idlc()->scopes()->bottom();
2550 AstDeclaration* pDecl = NULL;
2551 AstDeclaration* pSeq = NULL;
2553 if ( $5 )
2555 AstType *pType = (AstType*)$5;
2556 if ( pType )
2558 pSeq = new AstSequence(pType, pScope);
2560 * Add this AstSequence to the types defined in the global scope
2562 pDecl = pScope->addDeclaration(pSeq);
2563 if ( pSeq != pDecl )
2565 // if sequence type already defined then use it
2566 delete pSeq;
2567 pSeq = pDecl;
2571 $$ = pSeq;
2573 | error '>'
2575 yyerror("sequence declaration");
2576 yyerrok;
2577 $$ = 0;
2581 struct_type :
2582 structure_header
2584 idlc()->setParseState(PS_StructHeaderSeen);
2586 AstScope* pScope = idlc()->scopes()->topNonNull();
2587 AstStruct* pStruct = NULL;
2589 if ( pScope )
2591 AstStruct const* pBase= static_cast< AstStruct const* >(resolveTypedefs($1->getInherits()));
2592 pStruct = new AstStruct(
2593 *$1->getName(), $1->getTypeParameters(), pBase, pScope);
2594 pScope->addDeclaration(pStruct);
2597 * Push the scope of the struct on the scopes stack
2599 idlc()->scopes()->push(pStruct);
2600 delete $1;
2604 idlc()->setParseState(PS_StructSqSeen);
2606 at_least_one_member
2608 idlc()->setParseState(PS_StructBodySeen);
2612 idlc()->setParseState(PS_StructQsSeen);
2613 /* this exception is finished, pop its scope from the stack */
2614 idlc()->scopes()->pop();
2618 structure_header :
2619 IDL_STRUCT
2621 idlc()->setParseState(PS_StructSeen);
2623 identifier
2625 idlc()->setParseState(PS_StructIDSeen);
2626 checkIdentifier($3);
2628 opt_type_params
2629 inheritance_spec
2631 idlc()->setParseState(PS_InheritSpecSeen);
2633 // Polymorphic struct type templates with base types would cause various
2634 // problems in language bindings, so forbid them here. For example,
2635 // GCC prior to version 3.4 fails with code like
2637 // struct Base { ... };
2638 // template< typename typeparam_T > struct Derived: public Base {
2639 // int member1 CPPU_GCC3_ALIGN(Base);
2640 // ... };
2642 // (Note that plain struct types with instantiated polymorphic struct
2643 // type bases, which might also cause problems in language bindings, are
2644 // already rejected on a syntactic level.)
2645 if ($5 != 0 && $6 != 0) {
2646 idlc()->error()->error0(EIDL_STRUCT_TYPE_TEMPLATE_WITH_BASE);
2649 $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
2650 delete $5;
2651 delete $6;
2655 opt_type_params:
2656 '<' type_params '>' { $$ = $2; }
2657 | /* empty */ { $$ = 0; }
2660 type_params:
2661 identifier
2663 $$ = new std::vector< rtl::OString >;
2664 $$->push_back(*$1);
2665 delete $1;
2667 | type_params ',' identifier
2669 if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
2670 idlc()->error()->error0(EIDL_IDENTICAL_TYPE_PARAMETERS);
2672 $1->push_back(*$3);
2673 delete $3;
2674 $$ = $1;
2678 at_least_one_member : member members ;
2680 members :
2681 members member
2682 | /* EMPTY */
2685 member :
2686 type_or_parameter
2688 idlc()->setParseState(PS_MemberTypeSeen);
2690 at_least_one_declarator
2692 idlc()->setParseState(PS_MemberDeclsSeen);
2696 idlc()->setParseState(PS_MemberDeclsCompleted);
2698 AstScope* pScope = idlc()->scopes()->topNonNull();
2699 AstMember* pMember = NULL;
2700 FeDeclList* pList = $3;
2701 FeDeclarator* pDecl = NULL;
2702 AstType const * pType = NULL;
2704 // !!! check recursive type
2706 if ( pScope && pList && $1 )
2708 FeDeclList::iterator iter = pList->begin();
2709 FeDeclList::iterator end = pList->end();
2710 while (iter != end)
2712 pDecl = (*iter);
2713 if ( !pDecl )
2715 iter++;
2716 continue;
2719 pType = pDecl->compose($1);
2721 if ( !pType )
2723 iter++;
2724 continue;
2727 pMember = new AstMember(pType, pDecl->getName(), pScope);
2729 if ( !pDecl->checkType($1) )
2731 // WARNING
2734 pScope->addDeclaration(pMember);
2735 iter++;
2736 delete pDecl;
2738 delete pList;
2741 | error ';'
2743 yyerror("member definition");
2744 yyerrok;
2748 type_or_parameter:
2749 fundamental_type
2750 | scoped_name opt_type_args
2752 AstDeclaration const * decl = 0;
2753 AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top());
2754 if (scope != 0 && $2 == 0) {
2755 decl = scope->findTypeParameter(*$1);
2757 if (decl != 0) {
2758 delete $1;
2759 delete $2;
2760 } else {
2761 decl = createNamedType($1, $2);
2762 if (scope != 0 && includes(decl, scopeAsDecl(scope))) {
2763 idlc()->error()->error1(
2764 EIDL_RECURSIVE_TYPE, scopeAsDecl(scope));
2765 decl = 0;
2768 $$ = decl;
2772 enum_type :
2773 IDL_ENUM
2775 idlc()->setParseState(PS_EnumSeen);
2777 identifier
2779 idlc()->setParseState(PS_EnumIDSeen);
2780 checkIdentifier($3);
2782 AstScope* pScope = idlc()->scopes()->topNonNull();
2783 AstEnum* pEnum = NULL;
2786 * Create a node representing an enum and add it to its
2787 * enclosing scope
2789 if (pScope != NULL)
2791 pEnum = new AstEnum(*$3, pScope);
2793 * Add it to its defining scope
2795 pScope->addDeclaration(pEnum);
2797 delete $3;
2799 * Push the enum scope on the scopes stack
2801 idlc()->scopes()->push(pEnum);
2806 idlc()->setParseState(PS_EnumSqSeen);
2808 at_least_one_enumerator
2810 idlc()->setParseState(PS_EnumBodySeen);
2814 idlc()->setParseState(PS_EnumQsSeen);
2816 * Done with this enum. Pop its scope from the scopes stack
2818 if (idlc()->scopes()->top() == NULL)
2819 $$ = NULL;
2820 else
2822 $$ = (AstEnum*)idlc()->scopes()->topNonNull();
2823 idlc()->scopes()->pop();
2828 at_least_one_enumerator : enumerator enumerators ;
2830 enumerators :
2831 enumerators
2834 idlc()->setParseState(PS_EnumCommaSeen);
2836 enumerator
2837 | /* EMPTY */
2838 | error ','
2840 yyerror("enumerator definition");
2841 yyerrok;
2845 enumerator :
2846 identifier
2848 checkIdentifier($1);
2850 AstScope* pScope = idlc()->scopes()->topNonNull();
2851 AstEnum* pEnum = NULL;
2852 AstConstant* pEnumVal = NULL;
2854 if ( pScope && pScope->getScopeNodeType() == NT_enum)
2856 pEnum = (AstEnum*)pScope;
2857 if (pEnum && $1)
2859 AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
2860 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2861 pExpr, *$1, pScope);
2863 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2864 idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2866 pScope->addDeclaration(pEnumVal);
2868 delete $1;
2870 | identifier
2872 const_expr
2874 checkIdentifier($1);
2876 AstScope* pScope = idlc()->scopes()->topNonNull();
2877 AstEnum* pEnum = NULL;
2878 AstConstant* pEnumVal = NULL;
2880 if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
2882 $3->evaluate(EK_const);
2883 if ( $3->coerce(ET_long) )
2885 pEnum = (AstEnum*)pScope;
2886 if (pEnum)
2888 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2889 $3, *$1, pScope);
2891 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2892 idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2894 pScope->addDeclaration(pEnumVal);
2895 } else
2897 idlc()->error()->coercionError($3, ET_long);
2898 delete $3;
2901 delete $1;
2905 union_type :
2906 IDL_UNION
2908 idlc()->setParseState(PS_UnionSeen);
2910 identifier
2912 idlc()->setParseState(PS_UnionIDSeen);
2913 checkIdentifier($3);
2915 IDL_SWITCH
2917 idlc()->setParseState(PS_SwitchSeen);
2921 idlc()->setParseState(PS_SwitchOpenParSeen);
2923 switch_type_spec
2925 idlc()->setParseState(PS_SwitchTypeSeen);
2929 idlc()->setParseState(PS_SwitchCloseParSeen);
2931 AstScope* pScope = idlc()->scopes()->topNonNull();
2932 AstUnion* pUnion = NULL;
2935 * Create a node representing a union. Add it to its enclosing
2936 * scope
2938 if ( $9 && pScope )
2940 AstType* pType = (AstType*)$9;
2941 if ( !pType)
2943 idlc()->error()->noTypeError($9);
2944 } else
2946 pUnion = new AstUnion(*$3, pType, pScope);
2947 pScope->addDeclaration(pUnion);
2950 delete $3;
2952 * Push the scope of the union on the scopes stack
2954 idlc()->scopes()->push(pUnion);
2958 idlc()->setParseState(PS_UnionSqSeen);
2960 at_least_one_case_branch
2962 idlc()->setParseState(PS_UnionBodySeen);
2966 idlc()->setParseState(PS_UnionQsSeen);
2967 /* this union is finished, pop its scope from the stack */
2968 idlc()->scopes()->pop();
2972 switch_type_spec :
2973 integer_type
2975 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2977 | char_type
2979 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2981 | boolean_type
2983 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2985 | enum_type
2986 | scoped_name
2988 AstScope* pScope = idlc()->scopes()->topNonNull();
2989 AstBaseType* pBaseType = NULL;
2990 AstDeclaration const * pDecl = NULL;
2991 AstTypeDef* pTypeDef = NULL;
2992 sal_Bool bFound = sal_False;
2994 * If the constant's type is a scoped name, it must resolve
2995 * to a scalar constant type
2997 if ( pScope && (pDecl = pScope->lookupByName(*$1)) )
3000 * Look through typedefs
3002 while ( !bFound )
3004 switch (pDecl->getNodeType())
3006 case NT_enum:
3007 $$ = pDecl;
3008 bFound = sal_True;
3009 break;
3010 case NT_predefined:
3011 pBaseType = (AstBaseType*)pDecl;
3012 if ( pBaseType )
3014 switch (pBaseType->getExprType())
3016 case ET_short:
3017 case ET_ushort:
3018 case ET_long:
3019 case ET_ulong:
3020 case ET_hyper:
3021 case ET_uhyper:
3022 case ET_char:
3023 case ET_byte:
3024 case ET_boolean:
3025 $$ = pBaseType;
3026 bFound = sal_True;
3027 break;
3028 default:
3029 $$ = NULL;
3030 bFound = sal_True;
3031 break;
3034 break;
3035 case NT_typedef:
3036 pTypeDef = (AstTypeDef*)pDecl;
3037 if ( pTypeDef )
3038 pDecl = pTypeDef->getBaseType();
3039 break;
3040 default:
3041 $$ = NULL;
3042 bFound = sal_True;
3043 break;
3046 } else
3047 $$ = NULL;
3049 if ($$ == NULL)
3050 idlc()->error()->lookupError(*$1);
3054 at_least_one_case_branch : case_branch case_branches ;
3056 case_branches :
3057 case_branches case_branch
3058 | /* EMPTY */
3061 case_branch :
3062 at_least_one_case_label
3064 idlc()->setParseState(PS_UnionLabelSeen);
3066 element_spec
3068 idlc()->setParseState(PS_UnionElemSeen);
3070 AstScope* pScope = idlc()->scopes()->topNonNull();
3071 AstUnionLabel* pLabel = NULL;
3072 AstUnionBranch* pBranch = NULL;
3073 AstMember* pMember = $3;
3076 * Create several nodes representing branches of a union.
3077 * Add them to the enclosing scope (the union scope)
3079 if ( pScope && $1 && $3 )
3081 LabelList::iterator iter = $1->begin();
3082 LabelList::iterator end = $1->end();
3083 for (;iter != end; iter++)
3085 pLabel = *iter;
3086 if ( !pLabel )
3088 iter++;
3089 continue;
3091 pBranch = new AstUnionBranch(pLabel, pMember->getType(),
3092 pMember->getLocalName(), pScope);
3093 pScope->addDeclaration(pBranch);
3096 if ( $1 ) delete($1);
3100 at_least_one_case_label :
3101 case_label case_labels
3103 if ( $2 )
3105 $2->push_front($1);
3106 $$ = $2;
3107 } else
3109 LabelList* pLabels = new LabelList();
3110 pLabels->push_back($1);
3111 $$ = pLabels;
3116 case_labels :
3117 case_labels case_label
3119 if ( $1 )
3121 $1->push_back($2);
3122 $$ = $1;
3123 } else
3125 LabelList* pLabels = new LabelList();
3126 pLabels->push_back($2);
3127 $$ = pLabels;
3130 | /* EMPTY */
3132 $$ = NULL;
3136 case_label :
3137 IDL_DEFAULT
3139 idlc()->setParseState(PS_DefaultSeen);
3143 idlc()->setParseState(PS_LabelColonSeen);
3144 $$ = new AstUnionLabel(UL_default, NULL);
3146 | IDL_CASE
3148 idlc()->setParseState(PS_CaseSeen);
3150 const_expr
3152 idlc()->setParseState(PS_LabelExprSeen);
3156 idlc()->setParseState(PS_LabelColonSeen);
3157 $$ = new AstUnionLabel(UL_label, $3);
3161 element_spec :
3162 type_spec
3164 idlc()->setParseState(PS_UnionElemTypeSeen);
3166 declarator
3168 idlc()->setParseState(PS_UnionElemDeclSeen);
3172 idlc()->setParseState(PS_UnionElemCompleted);
3174 AstScope* pScope = idlc()->scopes()->topNonNull();
3176 * Check for illegal recursive use of type
3178 // if ( $1 && AST_illegal_recursive_type($1))
3179 // idlc()->error()->error1(EIDL_RECURSIVE_TYPE, $1);
3181 * Create a field in a union branch
3183 if ( $1 && $3 )
3185 AstType const * pType = $3->compose($1);
3186 if ( !pType )
3187 $$ = NULL;
3188 else
3189 $$ = new AstMember(pType, $3->getName(), pScope);
3190 } else
3191 $$ = NULL;
3193 if ( $3 ) delete $3;
3195 | error
3198 $$ = NULL;
3202 identifier:
3203 IDL_IDENTIFIER
3204 | IDL_GET { $$ = new OString("get"); }
3205 | IDL_SET { $$ = new OString("set"); }
3206 | IDL_PUBLISHED { $$ = new OString("published"); }
3212 * Report an error situation discovered in a production
3214 void yyerror(char const *errmsg)
3216 idlc()->error()->syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
3217 idlc()->setParseState(PS_NoState);
3220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */