xref: /aoo4110/main/idlc/source/parser.y (revision b1cdbd2c)
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