xref: /trunk/main/idlc/source/parser.y (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb) !
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