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