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