lokdialog: convert the show sheet dialog to async exec
[LibreOffice.git] / idlc / source / parser.y
blob0fe8eb8049c1828b2df204b2bf2f985ced404544
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 * parser.yy - BISON grammar for IDLC 1.0
25 #include <string.h>
27 #include <idlc.hxx>
28 #include <errorhandler.hxx>
29 #include <fehelper.hxx>
30 #include <astexpression.hxx>
31 #include <astconstants.hxx>
32 #include <astconstant.hxx>
33 #include <astbasetype.hxx>
34 #include <asttypedef.hxx>
35 #include <astexception.hxx>
36 #include <astmember.hxx>
37 #include <astenum.hxx>
38 #include <astsequence.hxx>
39 #include <astattribute.hxx>
40 #include <astoperation.hxx>
41 #include <astparameter.hxx>
42 #include <astinterfacemember.hxx>
43 #include <astservicemember.hxx>
44 #include <astobserves.hxx>
45 #include <astneeds.hxx>
47 #include <aststructinstance.hxx>
49 #include "attributeexceptions.hxx"
51 #include <rtl/strbuf.hxx>
52 #include <osl/diagnose.h>
54 #include <algorithm>
55 #include <vector>
58 #define YYDEBUG 1
59 #define YYERROR_VERBOSE 1
61 using ::rtl::OUString;
62 using ::rtl::OString;
63 using ::rtl::OStringToOUString;
64 using ::rtl::OStringBuffer;
66 extern int yylex(void);
67 void yyerror(char const *);
69 void checkIdentifier(::rtl::OString const * id)
71 static short check = 0;
72 if (check == 0) {
73 if (idlc()->getOptions()->isValid("-cid"))
74 check = 1;
75 else
76 check = 2;
79 if ( id->indexOf('_') >= 0 )
80 if ( (id->pData->buffer[0] >= 97 && id->pData->buffer[0] <= 122)
81 || id->pData->buffer[0] == '_') {
82 if (check == 1) {
83 ::rtl::OStringBuffer msg(25 + id->getLength());
84 msg.append("mismatched identifier '");
85 msg.append(*id);
86 msg.append("'");
87 ErrorHandler::syntaxError(idlc()->getParseState(),
88 idlc()->getLineNumber(),
89 msg.getStr());
91 else
92 ErrorHandler::warning0(WarningCode::WrongNamingConvention, id->getStr());
96 void reportDoubleMemberDeclarations(
97 AstInterface::DoubleMemberDeclarations const & doubleMembers)
99 for (AstInterface::DoubleMemberDeclarations::const_iterator i(
100 doubleMembers.begin());
101 i != doubleMembers.end(); ++i)
103 ErrorHandler::error2(ErrorCode::DoubleMember, i->first, i->second);
107 void addInheritedInterface(
108 AstInterface * ifc, rtl::OString const & name, bool optional,
109 rtl::OUString const & documentation)
111 AstDeclaration * decl = ifc->lookupByName(name);
112 AstDeclaration const * resolved = resolveTypedefs(decl);
113 if (resolved != nullptr && resolved->getNodeType() == NT_interface) {
114 if (ErrorHandler::checkPublished(decl)) {
115 if (!static_cast< AstInterface const * >(resolved)->isDefined()) {
116 ErrorHandler::inheritanceError(
117 NT_interface, &ifc->getScopedName(), decl);
118 } else {
119 AstInterface::DoubleDeclarations doubleDecls(
120 ifc->checkInheritedInterfaceClashes(
121 static_cast< AstInterface const * >(resolved),
122 optional));
123 if (doubleDecls.interfaces.empty()
124 && doubleDecls.members.empty())
126 ifc->addInheritedInterface(
127 static_cast< AstType * >(decl), optional,
128 documentation);
129 } else {
130 for (AstInterface::DoubleInterfaceDeclarations::iterator i(
131 doubleDecls.interfaces.begin());
132 i != doubleDecls.interfaces.end(); ++i)
134 ErrorHandler::error1(
135 ErrorCode::DoubleInheritance, *i);
137 reportDoubleMemberDeclarations(doubleDecls.members);
141 } else {
142 ErrorHandler::lookupError(
143 ErrorCode::InterfaceMemberLookup, name, scopeAsDecl(ifc));
147 AstDeclaration const * createNamedType(
148 rtl::OString const * scopedName, DeclList const * typeArgs)
150 AstDeclaration * decl = idlc()->scopes()->topNonNull()->lookupByName(
151 *scopedName);
152 AstDeclaration const * resolved = resolveTypedefs(decl);
153 if (decl == nullptr) {
154 ErrorHandler::lookupError(*scopedName);
155 } else if (!ErrorHandler::checkPublished(decl)) {
156 decl = nullptr;
157 } else if (resolved->getNodeType() == NT_struct) {
158 if (static_cast< AstStruct const * >(resolved)->getTypeParameterCount()
159 != (typeArgs == nullptr ? 0 : typeArgs->size()))
161 ErrorHandler::error0(ErrorCode::WrongNumberOfTypeArguments);
162 decl = nullptr;
163 } else if (typeArgs != nullptr) {
164 AstScope * global = idlc()->scopes()->bottom();
165 AstDeclaration * inst = new AstStructInstance(
166 static_cast< AstType * >(decl), typeArgs, global);
167 decl = global->addDeclaration(inst);
168 if (decl != inst) {
169 delete inst;
172 } else if (decl->isType()) {
173 if (typeArgs != nullptr) {
174 ErrorHandler::error0(ErrorCode::WrongNumberOfTypeArguments);
175 decl = nullptr;
177 } else {
178 ErrorHandler::noTypeError(decl);
179 decl = nullptr;
181 delete scopedName;
182 delete typeArgs;
183 return decl;
186 bool includes(AstDeclaration const * type1, AstDeclaration const * type2) {
187 OSL_ASSERT(type2 != nullptr);
188 if (type1 != nullptr) {
189 if (type1->getNodeType() == NT_instantiated_struct) {
190 AstStructInstance const * inst
191 = static_cast< AstStructInstance const * >(type1);
192 if (inst->getTypeTemplate() == type2) {
193 return true;
195 for (DeclList::const_iterator i(inst->getTypeArgumentsBegin());
196 i != inst->getTypeArgumentsEnd(); ++i)
198 if (includes(*i, type2)) {
199 return true;
202 } else if (type1 == type2) {
203 return true;
206 return false;
209 // Suppress any warnings from generated code:
210 #if defined _MSC_VER
211 #pragma warning(disable: 4702) // unreachable code
212 #endif
215 * Declare the type of values in the grammar
217 %union {
218 ExprType etval; /* Expression type */
219 AstDeclaration* dclval; /* Declaration */
220 AstDeclaration const * cdclval;
221 DeclList * dclsval;
222 AstExpression* exval; /* expression value */
223 FeDeclarator* fdval; /* declarator value */
224 FeDeclList* dlval; /* declarator list value */
225 FeInheritanceHeader* ihval; /* inheritance header value */
226 ::rtl::OString* sval; /* OString value */
227 std::vector< rtl::OString > * svals;
228 sal_Char* strval; /* sal_Char* value */
229 bool bval; /* sal_Boolean* value */
230 sal_Int64 ival; /* sal_Int64 value */
231 sal_uInt64 uval; /* sal_uInt64 value */
232 sal_uInt32 ulval; /* sal_uInt32 value */
233 double dval; /* double value */
234 float fval; /* float value */
235 std::list< OString >* slval; /* StringList value */
236 AttributeExceptions::Part attexcpval;
237 AttributeExceptions attexcval;
241 * Token types: These are returned by the lexer
244 %token <sval> IDL_IDENTIFIER
245 %token IDL_ATTRIBUTE
246 %token IDL_BOUND
247 %token IDL_CONST
248 %token IDL_CONSTANTS
249 %token IDL_CONSTRAINED
250 %token IDL_ENUM
251 %token IDL_EXCEPTION
252 %token IDL_INTERFACE
253 %token IDL_MAYBEAMBIGUOUS
254 %token IDL_MAYBEDEFAULT
255 %token IDL_MAYBEVOID
256 %token IDL_MODULE
257 %token IDL_NEEDS
258 %token IDL_OBSERVES
259 %token IDL_OPTIONAL
260 %token IDL_PROPERTY
261 %token IDL_RAISES
262 %token IDL_READONLY
263 %token IDL_REMOVABLE
264 %token IDL_SERVICE
265 %token IDL_SEQUENCE
266 %token IDL_SINGLETON
267 %token IDL_STRUCT
268 %token IDL_TYPEDEF
269 %token IDL_TRANSIENT
271 %token IDL_ANY
272 %token IDL_CHAR
273 %token IDL_BOOLEAN
274 %token IDL_BYTE
275 %token IDL_DOUBLE
276 %token IDL_FLOAT
277 %token IDL_HYPER
278 %token IDL_LONG
279 %token IDL_SHORT
280 %token IDL_VOID
281 %token IDL_STRING
282 %token IDL_TYPE
283 %token IDL_UNSIGNED
285 %token IDL_TRUE
286 %token IDL_FALSE
288 %token IDL_IN
289 %token IDL_OUT
290 %token IDL_INOUT
292 %token IDL_GET
293 %token IDL_SET
295 %token IDL_PUBLISHED
297 %token IDL_ELLIPSIS
299 %token <strval> IDL_LEFTSHIFT
300 %token <strval> IDL_RIGHTSHIFT
301 %token <strval> IDL_SCOPESEPARATOR
303 %token <ival> IDL_INTEGER_LITERAL
304 %token <uval> IDL_INTEGER_ULITERAL
305 %token <dval> IDL_FLOATING_PT_LITERAL
308 * These are production names:
310 %type <dclval> type_dcl
311 %type <dclval> exception_name
312 %type <cdclval> constructed_type_spec enum_type op_type_spec
313 %type <cdclval> sequence_type_spec simple_type_spec struct_type
314 %type <cdclval> type_spec
315 %type <cdclval> fundamental_type type_arg type_or_parameter
316 %type <dclsval> opt_raises raises exception_list
317 %type <attexcpval> opt_attribute_get_raises attribute_get_raises
318 %type <attexcpval> opt_attribute_set_raises attribute_set_raises
319 %type <dclsval> opt_type_args type_args
321 %type <sval> identifier
322 %type <sval> interface_decl
323 %type <sval> scoped_name inheritance_spec
324 %type <slval> scoped_names at_least_one_scoped_name
326 %type <etval> const_type integer_type char_type boolean_type
327 %type <etval> floating_pt_type any_type signed_int string_type
328 %type <etval> unsigned_int base_type_spec byte_type type_type
330 %type <exval> expression const_expr or_expr xor_expr and_expr
331 %type <exval> add_expr mult_expr unary_expr primary_expr shift_expr
332 %type <exval> literal
334 %type <fdval> declarator
335 %type <dlval> declarators at_least_one_declarator
337 %type <ihval> exception_header structure_header interfaceheader
339 %type <ulval> flag_header opt_attrflags opt_attrflag
340 %type <ulval> direction service_interface_header service_service_header
342 %type <bval> optional_inherited_interface opt_rest opt_service_body
344 %type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises
346 %type <svals> opt_type_params type_params
350 * Grammar start here
352 start : definitions;
354 definitions :
355 definition definitions
356 | /* EMPTY */
359 definition :
360 opt_published publishable_definition
361 | module_dcl
363 idlc()->setParseState(PS_ModuleDeclSeen);
367 idlc()->setParseState(PS_NoState);
369 | error ';'
371 yyerror("definitions");
372 yyerrok;
376 opt_published:
377 IDL_PUBLISHED { idlc()->setPublished(true); }
378 | /* empty */ { idlc()->setPublished(false); }
381 publishable_definition:
382 type_dcl
384 idlc()->setParseState(PS_TypeDeclSeen);
388 idlc()->setParseState(PS_NoState);
390 | exception_dcl
392 idlc()->setParseState(PS_ExceptionDeclSeen);
396 idlc()->setParseState(PS_NoState);
398 | interface
400 idlc()->setParseState(PS_InterfaceDeclSeen);
404 idlc()->setParseState(PS_NoState);
406 | service_dcl
408 idlc()->setParseState(PS_ServiceDeclSeen);
412 idlc()->setParseState(PS_NoState);
414 | singleton_dcl
416 idlc()->setParseState(PS_SingletonDeclSeen);
420 idlc()->setParseState(PS_NoState);
422 | constants_dcl
424 idlc()->setParseState(PS_ConstantsDeclSeen);
428 idlc()->setParseState(PS_NoState);
432 module_dcl :
433 IDL_MODULE
435 idlc()->setParseState(PS_ModuleSeen);
436 idlc()->setPublished(false);
438 identifier
440 idlc()->setParseState(PS_ModuleIDSeen);
441 checkIdentifier($3);
443 AstScope* pScope = idlc()->scopes()->topNonNull();
444 AstModule* pModule = nullptr;
446 if ( pScope )
448 pModule = new AstModule(*$3, pScope);
449 if( AstDeclaration* pExists = pScope->lookupForAdd(pModule) )
451 pExists->setInMainfile(idlc()->isInMainFile());
452 pExists->setFileName(pModule->getFileName());
453 if (pExists->isPredefined())
455 pExists->setPredefined(false);
456 if (pExists->getDocumentation().getLength() == 0 &&
457 pModule->getDocumentation().getLength() > 0)
459 pExists->setDocumentation(pModule->getDocumentation());
462 delete(pModule);
463 pModule = static_cast<AstModule*>(pExists);
464 } else
466 pScope->addDeclaration(pModule);
468 idlc()->scopes()->push(pModule);
470 delete $3;
474 idlc()->setParseState(PS_ModuleSqSeen);
476 definitions
478 idlc()->setParseState(PS_ModuleBodySeen);
482 idlc()->setParseState(PS_ModuleQsSeen);
484 * Finished with this module - pop it from the scope stack
486 idlc()->scopes()->pop();
490 interface :
491 interface_dcl
492 | forward_dcl
495 interface_decl :
496 IDL_INTERFACE
498 idlc()->setParseState(PS_InterfaceSeen);
500 identifier
502 idlc()->setParseState(PS_InterfaceIDSeen);
503 checkIdentifier($3);
504 $$ = $3;
508 forward_dcl :
509 interface_decl
511 idlc()->setParseState(PS_ForwardDeclSeen);
513 AstScope* pScope = idlc()->scopes()->topNonNull();
514 AstInterface* pForward = nullptr;
515 AstDeclaration* pDecl = nullptr;
518 * Make a new forward interface node and add it to its enclosing scope
520 if ( pScope && $1 )
522 pForward = new AstInterface(*$1, nullptr, pScope);
524 pDecl = pScope->lookupByName(pForward->getScopedName());
525 if ( pDecl )
527 if ( (pDecl != pForward) &&
528 (pDecl->getNodeType() == NT_interface) )
530 delete pForward;
531 } else
533 ErrorHandler::error2(ErrorCode::RedefScope, scopeAsDecl(pScope), pDecl);
535 } else
538 * Add the interface to its definition scope
540 pScope->addDeclaration(pForward);
543 delete $1;
547 interface_dcl :
548 interfaceheader
550 idlc()->setParseState(PS_InterfaceHeadSeen);
552 AstScope* pScope = idlc()->scopes()->topNonNull();
553 AstInterface* pInterface = nullptr;
554 AstInterface* pForward = nullptr;
557 * Make a new interface node and add it to its enclosing scope
559 if ( pScope && $1 )
561 pInterface = new AstInterface(
562 *$1->getName(),
563 static_cast< AstInterface const * >(resolveTypedefs($1->getInherits())), pScope);
564 if ( AstDeclaration* pDecl = pScope->lookupByName(pInterface->getScopedName()) )
567 * See if we're defining a forward declared interface.
569 if (pDecl->getNodeType() == NT_interface)
571 pForward = static_cast<AstInterface*>(pDecl);
572 if ( !pForward->isDefined() )
575 * Check if redefining in same scope
577 if ( pForward->getScope() != pScope )
579 if ( pForward->getScopedName() != pInterface->getScopedName() )
581 ErrorHandler::error3(ErrorCode::ScopeConflict,
582 pInterface, pForward, scopeAsDecl(pScope));
585 else if ( !pInterface->isPublished()
586 && pForward->isPublished() )
588 ErrorHandler::error0(ErrorCode::PublishedForward);
591 * All OK, set full definition
593 else
595 pForward->forwardDefined(*pInterface);
596 delete pInterface;
597 pInterface = pForward;
599 } else {
600 // special handling for XInterface because it is predefined
601 if ( pForward->isPredefined() &&
602 pForward->getScopedName() == "com::sun::star::uno::XInterface")
604 /* replace the predefined XInterface */
605 *pForward = *pInterface;
606 delete pInterface;
607 pInterface = pForward;
612 } else
615 * Add the interface to its definition scope
617 pScope->addDeclaration(pInterface);
621 * Push it on the scope stack
623 idlc()->scopes()->push(pInterface);
624 delete $1;
628 idlc()->setParseState(PS_InterfaceSqSeen);
630 exports
632 AstInterface * ifc = static_cast< AstInterface * >(
633 idlc()->scopes()->topNonNull());
634 if (!ifc->hasMandatoryInheritedInterfaces()
635 && ifc->getScopedName() != "com::sun::star::uno::XInterface")
637 addInheritedInterface(
638 ifc, rtl::OString("::com::sun::star::uno::XInterface"), false,
639 rtl::OUString());
641 ifc->setDefined();
642 idlc()->setParseState(PS_InterfaceBodySeen);
646 idlc()->setParseState(PS_InterfaceQsSeen);
648 * Done with this interface - pop it off the scopes stack
650 idlc()->scopes()->pop();
652 | error '}'
654 yyerror("interface definition");
655 yyerrok;
659 interfaceheader :
660 interface_decl inheritance_spec
662 idlc()->setParseState(PS_InheritSpecSeen);
664 $$ = new FeInheritanceHeader(NT_interface, $1, $2, nullptr);
665 delete $2;
669 inheritance_spec :
672 idlc()->setParseState(PS_InheritColonSeen);
674 scoped_name
676 $$ = $3;
678 | /* EMPTY */
680 $$ = nullptr;
684 exports :
685 exports export
686 | /* EMPTY */
689 export :
690 attribute
692 idlc()->setParseState(PS_AttributeDeclSeen);
696 idlc()->setParseState(PS_NoState);
698 | operation
700 idlc()->setParseState(PS_OperationDeclSeen);
704 idlc()->setParseState(PS_NoState);
706 | interface_inheritance_decl
708 idlc()->setParseState(PS_InterfaceInheritanceDeclSeen);
712 idlc()->setParseState(PS_NoState);
716 attribute :
717 flag_header
718 simple_type_spec
720 idlc()->setParseState(PS_AttrTypeSeen);
722 declarator
724 idlc()->setParseState(PS_AttrCompleted);
725 if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) {
726 ErrorHandler::flagError(ErrorCode::BadAttributeFlags, $1);
728 AstInterface * scope = static_cast< AstInterface * >(
729 idlc()->scopes()->top());
730 AstAttribute * attr = new AstAttribute(
731 $1, FeDeclarator::compose($2), $4->getName(), scope);
732 delete $4;
733 AstInterface::DoubleMemberDeclarations doubleMembers(
734 scope->checkMemberClashes(attr));
735 if (doubleMembers.empty()) {
736 scope->addMember(attr);
737 } else {
738 reportDoubleMemberDeclarations(doubleMembers);
740 idlc()->scopes()->push(attr);
742 opt_attribute_block
744 static_cast< AstAttribute * >(idlc()->scopes()->top())->setExceptions(
745 $6.get.documentation, $6.get.exceptions, $6.set.documentation,
746 $6.set.exceptions);
747 delete $6.get.documentation;
748 delete $6.get.exceptions;
749 delete $6.set.documentation;
750 delete $6.set.exceptions;
751 idlc()->scopes()->pop();
755 flag_header :
756 '[' opt_attrflags ']'
758 idlc()->setParseState(PS_FlagHeaderSeen);
759 $$ = $2;
763 opt_attrflags :
764 opt_attrflags ',' opt_attrflag
766 if ( ($1 & $3) == $3 )
767 ErrorHandler::flagError(ErrorCode::DefinedAttributeFlag, $3);
769 $$ = $1 | $3;
771 | opt_attrflag
773 $$ = $1;
777 opt_attrflag :
778 IDL_ATTRIBUTE
780 idlc()->setParseState(PS_AttrSeen);
781 $$ = AF_ATTRIBUTE;
783 | IDL_PROPERTY
785 idlc()->setParseState(PS_PropertySeen);
786 $$ = AF_PROPERTY;
788 | IDL_READONLY
790 idlc()->setParseState(PS_ReadOnlySeen);
791 $$ = AF_READONLY;
793 | IDL_OPTIONAL
795 idlc()->setParseState(PS_OptionalSeen);
796 $$ = AF_OPTIONAL;
798 | IDL_MAYBEVOID
800 idlc()->setParseState(PS_MayBeVoidSeen);
801 $$ = AF_MAYBEVOID;
803 | IDL_BOUND
805 idlc()->setParseState(PS_BoundSeen);
806 $$ = AF_BOUND;
808 | IDL_CONSTRAINED
810 idlc()->setParseState(PS_ConstrainedSeen);
811 $$ = AF_CONSTRAINED;
813 | IDL_TRANSIENT
815 idlc()->setParseState(PS_TransientSeen);
816 $$ = AF_TRANSIENT;
818 | IDL_MAYBEAMBIGUOUS
820 idlc()->setParseState(PS_MayBeAmbigiousSeen);
821 $$ = AF_MAYBEAMBIGUOUS;
823 | IDL_MAYBEDEFAULT
825 idlc()->setParseState(PS_MayBeDefaultSeen);
826 $$ = AF_MAYBEDEFAULT;
828 | IDL_REMOVABLE
830 idlc()->setParseState(PS_RemoveableSeen);
831 $$ = AF_REMOVABLE;
833 | error ']'
835 yyerror("unknown property|attribute flag");
836 yyerrok;
840 opt_attribute_block:
841 '{' attribute_block_rest { $$ = $2; }
842 | /* empty */
844 $$.get.documentation = nullptr;
845 $$.get.exceptions = nullptr;
846 $$.set.documentation = nullptr;
847 $$.set.exceptions = nullptr;
851 attribute_block_rest:
852 opt_attribute_raises '}'
853 | error '}'
855 yyerror("bad attribute raises block");
856 yyerrok;
857 $$.get.documentation = nullptr;
858 $$.get.exceptions = nullptr;
859 $$.set.documentation = nullptr;
860 $$.set.exceptions = nullptr;
864 opt_attribute_raises:
865 attribute_get_raises
866 opt_attribute_set_raises
868 $$.get = $1;
869 $$.set = $2;
871 | attribute_set_raises
872 opt_attribute_get_raises
874 $$.get = $2;
875 $$.set = $1;
877 | /* empty */
879 $$.get.documentation = nullptr;
880 $$.get.exceptions = nullptr;
881 $$.set.documentation = nullptr;
882 $$.set.exceptions = nullptr;
886 opt_attribute_get_raises:
887 attribute_get_raises
888 | /* empty */ { $$.documentation = nullptr; $$.exceptions = nullptr; }
891 attribute_get_raises:
892 IDL_GET raises ';'
894 $$.documentation = new rtl::OUString(
895 rtl::OStringToOUString(
896 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
897 $$.exceptions = $2;
901 opt_attribute_set_raises:
902 attribute_set_raises
903 | /* empty */ { $$.documentation = nullptr; $$.exceptions = nullptr; }
906 attribute_set_raises:
907 IDL_SET
909 if (static_cast< AstAttribute * >(idlc()->scopes()->top())->
910 isReadonly())
912 ErrorHandler::error0(ErrorCode::ReadOnlyAttributeSetExceptions);
915 raises ';'
917 $$.documentation = new rtl::OUString(
918 rtl::OStringToOUString(
919 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
920 $$.exceptions = $3;
924 operation :
925 op_type_spec
927 idlc()->setParseState(PS_OpTypeSeen);
929 identifier
931 idlc()->setParseState(PS_OpIDSeen);
932 checkIdentifier($3);
934 AstInterface * pScope = static_cast< AstInterface * >(
935 idlc()->scopes()->top());
936 AstOperation* pOp = nullptr;
939 * Create a node representing an operation on an interface
940 * and add it to its enclosing scope
942 if ( pScope && $1 )
944 AstType const *pType = static_cast<AstType const *>($1);
945 if ( !pType || (pType->getNodeType() == NT_exception) )
947 // type ERROR
948 } else
950 pOp = new AstOperation(pType, *$3, pScope);
952 AstInterface::DoubleMemberDeclarations doubleMembers(
953 pScope->checkMemberClashes(pOp));
954 if (doubleMembers.empty()) {
955 pScope->addMember(pOp);
956 } else {
957 reportDoubleMemberDeclarations(doubleMembers);
961 delete $3;
963 * Push the operation scope onto the scopes stack
965 idlc()->scopes()->push(pOp);
969 idlc()->setParseState(PS_OpSqSeen);
971 parameters
973 idlc()->setParseState(PS_OpParsCompleted);
977 idlc()->setParseState(PS_OpQsSeen);
979 opt_raises
981 AstScope* pScope = idlc()->scopes()->topNonNull();
982 AstOperation* pOp = nullptr;
984 * Add exceptions and context to the operation
986 if ( pScope && pScope->getScopeNodeType() == NT_operation)
988 pOp = static_cast<AstOperation*>(pScope);
990 if ( pOp )
991 pOp->setExceptions($11);
993 delete $11;
995 * Done with this operation. Pop its scope from the scopes stack
997 idlc()->scopes()->pop();
1001 op_type_spec :
1002 simple_type_spec
1003 | IDL_VOID
1005 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void);
1009 parameters :
1010 parameter
1011 | parameters
1014 idlc()->setParseState(PS_OpParCommaSeen);
1016 parameter
1017 | /* EMPTY */
1018 | error ','
1020 yyerror("parameter definition");
1021 yyerrok;
1025 parameter :
1027 direction
1030 idlc()->setParseState(PS_OpParDirSeen);
1032 simple_type_spec
1034 idlc()->setParseState(PS_OpParTypeSeen);
1036 opt_rest
1037 declarator
1039 idlc()->setParseState(PS_OpParDeclSeen);
1041 AstOperation * pScope = static_cast< AstOperation * >(
1042 idlc()->scopes()->top());
1043 AstParameter* pParam = nullptr;
1046 * Create a node representing an argument to an operation
1047 * Add it to the enclosing scope (the operation scope)
1049 if ( pScope && $5 && $8 )
1051 AstType const * pType = FeDeclarator::compose($5);
1052 if ( pType )
1054 if (pScope->isConstructor() && $2 != DIR_IN) {
1055 ErrorHandler::error0(ErrorCode::ConstructorParameterNotIn);
1057 if (pScope->isVariadic()) {
1058 ErrorHandler::error0(ErrorCode::RestParameterNotLast);
1060 if ($7) {
1061 AstDeclaration const * type = resolveTypedefs(pType);
1062 if (type->getNodeType() != NT_predefined
1063 || (static_cast< AstBaseType const * >(type)->
1064 getExprType() != ET_any))
1066 ErrorHandler::error0(ErrorCode::RestParameterNotAny);
1068 if (pScope->isConstructor()) {
1069 if (pScope->getIteratorBegin()
1070 != pScope->getIteratorEnd())
1072 ErrorHandler::error0(
1073 ErrorCode::ConstructorRestParameterNotFirst);
1075 } else {
1076 ErrorHandler::error0(ErrorCode::MethodHasRestParameter);
1080 pParam = new AstParameter(
1081 static_cast< Direction >($2), $7, pType, $8->getName(),
1082 pScope);
1084 if ( !$8->checkType($5) )
1086 // WARNING
1089 pScope->addDeclaration(pParam);
1093 | error
1094 simple_type_spec
1096 idlc()->setParseState(PS_NoState);
1097 yyerrok;
1101 direction :
1102 IDL_IN
1104 $$ = DIR_IN;
1106 | IDL_OUT
1108 $$ = DIR_OUT;
1110 | IDL_INOUT
1112 $$ = DIR_INOUT;
1116 opt_rest:
1117 IDL_ELLIPSIS
1119 $$ = true;
1121 | /* empty */
1123 $$ = false;
1127 opt_raises:
1128 raises
1129 | /* empty */
1131 $$ = nullptr;
1135 raises:
1136 IDL_RAISES
1138 idlc()->setParseState(PS_RaiseSeen);
1142 idlc()->setParseState(PS_RaiseSqSeen);
1144 exception_list
1147 idlc()->setParseState(PS_RaiseQsSeen);
1148 $$ = $5;
1152 exception_list:
1153 exception_name
1155 $$ = new DeclList;
1156 $$->push_back($1);
1158 | exception_list ',' exception_name
1160 $1->push_back($3);
1161 $$ = $1;
1165 exception_name:
1166 scoped_name
1168 // The topmost scope is either an AstOperation (for interface methods
1169 // and service constructors) or an AstAttribute (for interface
1170 // attributes), so look up exception names in the next-to-topmost scope:
1171 AstDeclaration * decl = idlc()->scopes()->nextToTop()->lookupByName(
1172 *$1);
1173 if (decl == nullptr) {
1174 ErrorHandler::lookupError(*$1);
1175 } else if (!ErrorHandler::checkPublished(decl)) {
1176 decl = nullptr;
1177 } else if (decl->getNodeType() != NT_exception) {
1178 ErrorHandler::error1(ErrorCode::IllegalRaises, decl);
1179 decl = nullptr;
1181 delete $1;
1182 $$ = decl;
1186 interface_inheritance_decl:
1187 optional_inherited_interface
1188 IDL_INTERFACE
1190 idlc()->setParseState(PS_ServiceIFHeadSeen);
1192 scoped_name
1194 AstInterface * ifc = static_cast< AstInterface * >(
1195 idlc()->scopes()->top());
1196 if (ifc->usesSingleInheritance()) {
1197 ErrorHandler::error0(ErrorCode::MixedInheritance);
1198 } else {
1199 addInheritedInterface(
1200 ifc, *$4, $1,
1201 rtl::OStringToOUString(
1202 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
1204 delete $4;
1208 optional_inherited_interface:
1209 '[' IDL_OPTIONAL ']' { $$ = true; }
1210 | /* EMPTY */ { $$ = false; }
1213 constants_exports :
1214 constants_export constants_exports
1215 | /* EMPTY */
1218 constants_export :
1219 IDL_CONST
1221 idlc()->setParseState(PS_ConstSeen);
1223 const_type
1225 idlc()->setParseState(PS_ConstTypeSeen);
1227 identifier
1229 idlc()->setParseState(PS_ConstIDSeen);
1230 checkIdentifier($5);
1234 idlc()->setParseState(PS_ConstAssignSeen);
1236 expression
1238 idlc()->setParseState(PS_ConstExprSeen);
1240 AstScope* pScope = idlc()->scopes()->topNonNull();
1241 AstConstant* pConstant = nullptr;
1243 if ( $9 && pScope )
1245 if ( !$9->coerce($3) )
1247 ErrorHandler::coercionError($9, $3);
1248 } else
1250 pConstant = new AstConstant($3, $9, *$5, pScope);
1251 pScope->addDeclaration(pConstant);
1254 delete $5;
1256 idlc()->setParseState(PS_ConstantDeclSeen);
1258 ';' {};
1261 constants_dcl :
1262 IDL_CONSTANTS
1264 idlc()->setParseState(PS_ConstantsSeen);
1266 identifier
1268 idlc()->setParseState(PS_ConstantsIDSeen);
1269 checkIdentifier($3);
1273 idlc()->setParseState(PS_ConstantsSqSeen);
1275 AstScope* pScope = idlc()->scopes()->topNonNull();
1276 AstConstants* pConstants = nullptr;
1278 if ( pScope )
1280 pConstants = new AstConstants(*$3, pScope);
1281 if( AstDeclaration* pExists = pScope->lookupForAdd(pConstants) )
1283 pExists->setInMainfile(idlc()->isInMainFile());
1284 delete(pConstants);
1285 pConstants = static_cast<AstConstants*>(pExists);
1286 } else
1288 pScope->addDeclaration(pConstants);
1290 idlc()->scopes()->push(pConstants);
1292 delete $3;
1294 constants_exports
1296 idlc()->setParseState(PS_ConstantsBodySeen);
1300 idlc()->setParseState(PS_ConstantsQsSeen);
1302 * Finished with this constants - pop it from the scope stack
1304 idlc()->scopes()->pop();
1308 expression : const_expr ;
1310 const_expr : or_expr ;
1312 or_expr :
1313 xor_expr
1314 | or_expr '|' xor_expr
1316 $$ = new AstExpression(ExprComb::Or, $1, $3);
1320 xor_expr :
1321 and_expr
1322 | xor_expr '^' and_expr
1324 $$ = new AstExpression(ExprComb::Xor, $1, $3);
1328 and_expr :
1329 shift_expr
1330 | and_expr '&' shift_expr
1332 $$ = new AstExpression(ExprComb::And, $1, $3);
1336 shift_expr :
1337 add_expr
1338 | shift_expr IDL_LEFTSHIFT add_expr
1340 $$ = new AstExpression(ExprComb::Left, $1, $3);
1342 | shift_expr IDL_RIGHTSHIFT add_expr
1344 $$ = new AstExpression(ExprComb::Right, $1, $3);
1348 add_expr :
1349 mult_expr
1350 | add_expr '+' mult_expr
1352 $$ = new AstExpression(ExprComb::Add, $1, $3);
1354 | add_expr '-' mult_expr
1356 $$ = new AstExpression(ExprComb::Minus, $1, $3);
1360 mult_expr :
1361 unary_expr
1362 | mult_expr '*' unary_expr
1364 $$ = new AstExpression(ExprComb::Mul, $1, $3);
1366 | mult_expr '/' unary_expr
1368 $$ = new AstExpression(ExprComb::Div, $1, $3);
1370 | mult_expr '%' unary_expr
1372 $$ = new AstExpression(ExprComb::Mod, $1, $3);
1376 unary_expr :
1377 primary_expr
1378 | '+' primary_expr
1380 $$ = new AstExpression(ExprComb::UPlus, $2, nullptr);
1382 | '-' primary_expr
1384 $$ = new AstExpression(ExprComb::UMinus, $2, nullptr);
1386 | '~' primary_expr
1391 primary_expr :
1392 scoped_name
1395 * An expression which is a scoped name is not resolved now,
1396 * but only when it is evaluated (such as when it is assigned
1397 * as a constant value)
1399 $$ = new AstExpression($1);
1401 | literal
1402 | '(' const_expr ')'
1404 $$ = $2;
1408 literal :
1409 IDL_INTEGER_LITERAL
1411 $$ = new AstExpression($1);
1413 | IDL_INTEGER_ULITERAL
1415 $$ = new AstExpression($1);
1417 | IDL_FLOATING_PT_LITERAL
1419 $$ = new AstExpression($1);
1421 | IDL_TRUE
1423 $$ = new AstExpression(sal_Int32(1), ET_boolean);
1425 | IDL_FALSE
1427 $$ = new AstExpression(sal_Int32(0), ET_boolean);
1431 const_type :
1432 integer_type
1433 | byte_type
1434 | boolean_type
1435 | floating_pt_type
1436 | scoped_name
1438 AstScope* pScope = idlc()->scopes()->topNonNull();
1439 AstDeclaration const * type = nullptr;
1442 * If the constant's type is a scoped name, it must resolve
1443 * to a scalar constant type
1445 if ( pScope && (type = pScope->lookupByName(*$1)) ) {
1446 if (!ErrorHandler::checkPublished(type))
1448 type = nullptr;
1449 $$ = ET_none;
1451 else
1453 type = resolveTypedefs(type);
1454 if (type->getNodeType() == NT_predefined)
1456 $$ = static_cast< AstBaseType const * >(type)->
1457 getExprType();
1458 } else
1459 $$ = ET_any;
1461 } else
1462 $$ = ET_any;
1466 exception_header :
1467 IDL_EXCEPTION
1469 idlc()->setParseState(PS_ExceptSeen);
1471 identifier
1473 idlc()->setParseState(PS_ExceptIDSeen);
1474 checkIdentifier($3);
1476 inheritance_spec
1478 idlc()->setParseState(PS_InheritSpecSeen);
1480 $$ = new FeInheritanceHeader(NT_exception, $3, $5, nullptr);
1481 delete $5;
1485 exception_dcl :
1486 exception_header
1488 idlc()->setParseState(PS_ExceptHeaderSeen);
1490 AstScope* pScope = idlc()->scopes()->topNonNull();
1491 AstException* pExcept = nullptr;
1493 if ( pScope )
1495 AstException* pBase = static_cast< AstException* >(
1496 $1->getInherits());
1497 pExcept = new AstException(*$1->getName(), pBase, pScope);
1498 pScope->addDeclaration(pExcept);
1501 * Push the scope of the exception on the scopes stack
1503 idlc()->scopes()->push(pExcept);
1504 delete $1;
1508 idlc()->setParseState(PS_ExceptSqSeen);
1510 members
1512 idlc()->setParseState(PS_ExceptBodySeen);
1516 idlc()->setParseState(PS_ExceptQsSeen);
1517 /* this exception is finished, pop its scope from the stack */
1518 idlc()->scopes()->pop();
1522 property :
1523 flag_header
1524 simple_type_spec
1526 idlc()->setParseState(PS_PropertyTypeSeen);
1528 at_least_one_declarator
1530 idlc()->setParseState(PS_PropertyCompleted);
1532 AstScope* pScope = idlc()->scopes()->topNonNull();
1533 AstAttribute* pAttr = nullptr;
1534 FeDeclList* pList = $4;
1535 FeDeclarator* pDecl = nullptr;
1536 AstType const * pType = nullptr;
1538 if ( pScope->getScopeNodeType() == NT_singleton )
1540 ErrorHandler::error0(ErrorCode::IllegalAdd);
1541 } else
1543 if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
1544 ErrorHandler::flagError(ErrorCode::WrongAttributeKeyword, AF_ATTRIBUTE);
1546 if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
1547 ErrorHandler::flagError(ErrorCode::MissingAttributeKeyword, AF_PROPERTY);
1550 * Create nodes representing attributes and add them to the
1551 * enclosing scope
1553 if ( pScope && $2 && pList )
1555 FeDeclList::iterator iter = pList->begin();
1556 FeDeclList::iterator end = pList->end();
1558 while (iter != end)
1560 pDecl = (*iter);
1561 if ( !pDecl )
1563 ++iter;
1564 continue;
1567 pType = FeDeclarator::compose($2);
1569 if ( !pType )
1571 ++iter;
1572 continue;
1575 pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);
1577 pScope->addDeclaration(pAttr);
1578 ++iter;
1579 delete pDecl;
1584 if ( pList )
1585 delete pList;
1587 | error ';'
1589 yyerror("property");
1590 yyerrok;
1594 service_exports :
1595 service_exports service_export
1596 | /* EMPTY */
1599 service_export :
1600 service_interface_header
1601 at_least_one_scoped_name
1604 idlc()->setParseState(PS_ServiceMemberSeen);
1606 AstScope* pScope = idlc()->scopes()->topNonNull();
1607 AstDeclaration* pDecl = nullptr;
1608 AstInterfaceMember* pIMember = nullptr;
1610 if ( pScope->getScopeNodeType() == NT_singleton )
1612 ErrorHandler::error0(ErrorCode::IllegalAdd);
1613 } else
1616 * Create a node representing a class member.
1617 * Store it in the enclosing scope
1619 if ( pScope && $2 )
1621 std::list< OString >::iterator iter = $2->begin();
1622 std::list< OString >::iterator end = $2->end();
1624 while ( iter != end )
1626 pDecl = pScope->lookupByName(*iter);
1627 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1629 /* we relax the strict published check and allow to add new
1630 * interfaces if they are optional
1632 bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
1633 if ( ErrorHandler::checkPublished(pDecl, bOptional) )
1635 pIMember = new AstInterfaceMember(
1636 $1, static_cast<AstInterface*>(pDecl), *iter, pScope);
1637 pScope->addDeclaration(pIMember);
1639 } else
1641 ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, *iter, scopeAsDecl(pScope));
1643 ++iter;
1647 delete $2;
1649 | service_service_header
1650 at_least_one_scoped_name
1653 idlc()->setParseState(PS_ServiceMemberSeen);
1655 AstScope* pScope = idlc()->scopes()->topNonNull();
1656 AstDeclaration* pDecl = nullptr;
1657 AstServiceMember* pSMember = nullptr;
1660 * Create a node representing a class member.
1661 * Store it in the enclosing scope
1663 if ( pScope && $2 )
1665 std::list< OString >::iterator iter = $2->begin();
1666 std::list< OString >::iterator end = $2->end();
1668 while ( iter != end )
1670 pDecl = pScope->lookupByName(*iter);
1671 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1673 if ( static_cast< AstService * >(pDecl)->isSingleInterfaceBasedService() || (pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0) )
1674 ErrorHandler::error0(ErrorCode::IllegalAdd);
1675 else if ( ErrorHandler::checkPublished(pDecl) )
1677 pSMember = new AstServiceMember(
1678 $1, static_cast<AstService*>(pDecl), *iter, pScope);
1679 pScope->addDeclaration(pSMember);
1681 } else
1683 ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, *iter, scopeAsDecl(pScope));
1685 ++iter;
1688 delete $2;
1690 | IDL_OBSERVES
1691 at_least_one_scoped_name
1694 idlc()->setParseState(PS_ServiceMemberSeen);
1696 AstScope* pScope = idlc()->scopes()->topNonNull();
1697 AstDeclaration* pDecl = nullptr;
1698 AstObserves* pObserves = nullptr;
1700 if ( pScope->getScopeNodeType() == NT_singleton )
1702 ErrorHandler::error0(ErrorCode::IllegalAdd);
1703 } else
1706 * Create a node representing a class member.
1707 * Store it in the enclosing scope
1709 if ( pScope && $2 )
1711 std::list< OString >::iterator iter = $2->begin();
1712 std::list< OString >::iterator end = $2->end();
1714 while ( iter != end )
1716 pDecl = pScope->lookupByName(*iter);
1717 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1719 pObserves = new AstObserves(static_cast<AstInterface*>(pDecl), *iter, pScope);
1720 pScope->addDeclaration(pObserves);
1721 } else
1723 ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, *iter, scopeAsDecl(pScope));
1725 ++iter;
1729 delete $2;
1731 | IDL_NEEDS
1732 at_least_one_scoped_name
1735 idlc()->setParseState(PS_ServiceMemberSeen);
1737 AstScope* pScope = idlc()->scopes()->topNonNull();
1738 AstDeclaration* pDecl = nullptr;
1739 AstNeeds* pNeeds = nullptr;
1741 if ( pScope->getScopeNodeType() == NT_singleton )
1743 ErrorHandler::error0(ErrorCode::IllegalAdd);
1744 } else
1747 * Create a node representing a class member.
1748 * Store it in the enclosing scope
1750 if ( pScope && $2 )
1752 std::list< OString >::iterator iter = $2->begin();
1753 std::list< OString >::iterator end = $2->end();
1755 while ( iter != end )
1757 pDecl = pScope->lookupByName(*iter);
1758 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1760 pNeeds = new AstNeeds(static_cast<AstService*>(pDecl), *iter, pScope);
1761 pScope->addDeclaration(pNeeds);
1762 } else
1764 ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, *iter, scopeAsDecl(pScope));
1766 ++iter;
1770 delete $2;
1772 | property
1775 idlc()->setParseState(PS_PropertyDeclSeen);
1779 service_interface_header :
1780 IDL_INTERFACE
1782 idlc()->setParseState(PS_ServiceIFHeadSeen);
1783 $$ = AF_INVALID;
1785 | flag_header
1786 IDL_INTERFACE
1788 idlc()->setParseState(PS_ServiceIFHeadSeen);
1789 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1790 ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
1791 $$ = $1;
1795 service_service_header :
1796 IDL_SERVICE
1798 idlc()->setParseState(PS_ServiceSHeadSeen);
1799 $$ = AF_INVALID;
1801 | flag_header
1802 IDL_SERVICE
1804 idlc()->setParseState(PS_ServiceSHeadSeen);
1805 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1806 ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
1807 $$ = $1;
1811 service_dcl :
1812 IDL_SERVICE
1814 idlc()->setParseState(PS_ServiceSeen);
1816 identifier
1818 idlc()->setParseState(PS_ServiceIDSeen);
1819 checkIdentifier($3);
1821 AstScope* pScope = idlc()->scopes()->topNonNull();
1822 AstService* pService = nullptr;
1825 * Make a new service and add it to the enclosing scope
1827 if (pScope != nullptr)
1829 pService = new AstService(*$3, pScope);
1830 pScope->addDeclaration(pService);
1832 delete $3;
1834 * Push it on the stack
1836 idlc()->scopes()->push(pService);
1838 service_dfn
1840 /* this service is finished, pop its scope from the stack */
1841 idlc()->scopes()->pop();
1845 service_dfn:
1846 service_interface_dfn
1847 | service_obsolete_dfn
1850 service_interface_dfn:
1851 ':' scoped_name
1853 AstScope * scope = idlc()->scopes()->nextToTop();
1854 // skip the scope pushed by service_dcl
1855 AstDeclaration * decl = scope->lookupByName(*$2);
1856 if (decl != nullptr
1857 && resolveTypedefs(decl)->getNodeType() == NT_interface)
1859 if (ErrorHandler::checkPublished(decl)) {
1860 idlc()->scopes()->top()->addDeclaration(decl);
1862 } else {
1863 ErrorHandler::lookupError(
1864 ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
1866 delete $2;
1868 opt_service_body
1870 AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
1871 if (s != nullptr) {
1872 s->setSingleInterfaceBasedService();
1873 s->setDefaultConstructor(!$4);
1878 opt_service_body:
1879 service_body { $$ = true; }
1880 | /* empty */ { $$ = false; }
1883 service_body:
1885 constructors
1889 constructors:
1890 constructors constructor
1891 | /* empty */
1894 constructor:
1895 identifier
1897 checkIdentifier($1);
1898 AstScope * scope = idlc()->scopes()->top();
1899 AstOperation * ctor = new AstOperation(nullptr, *$1, scope);
1900 delete $1;
1901 scope->addDeclaration(ctor);
1902 idlc()->scopes()->push(ctor);
1905 parameters
1907 opt_raises
1909 static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions(
1910 $6);
1911 delete $6;
1912 idlc()->scopes()->pop();
1913 if (static_cast< AstService * >(idlc()->scopes()->top())->
1914 checkLastConstructor())
1916 ErrorHandler::error0(ErrorCode::SimilarConstructors);
1922 singleton_dcl :
1923 IDL_SINGLETON
1925 idlc()->setParseState(PS_SingletonSeen);
1927 identifier
1929 idlc()->setParseState(PS_SingletonIDSeen);
1930 checkIdentifier($3);
1932 AstScope* pScope = idlc()->scopes()->topNonNull();
1933 AstService* pService = nullptr;
1936 * Make a new service and add it to the enclosing scope
1938 if (pScope != nullptr)
1940 pService = new AstService(NT_singleton, *$3, pScope);
1941 pScope->addDeclaration(pService);
1943 delete $3;
1945 * Push it on the stack
1947 idlc()->scopes()->push(pService);
1949 singleton_dfn
1951 /* this singelton is finished, pop its scope from the stack */
1952 idlc()->scopes()->pop();
1956 singleton_dfn:
1957 singleton_interface_dfn
1958 | service_obsolete_dfn
1961 singleton_interface_dfn:
1962 ':' scoped_name
1964 AstScope * scope = idlc()->scopes()->nextToTop();
1965 // skip the scope (needlessly) pushed by singleton_dcl
1966 AstDeclaration * decl = scope->lookupByName(*$2);
1967 if (decl != nullptr
1968 && resolveTypedefs(decl)->getNodeType() == NT_interface)
1970 if (ErrorHandler::checkPublished(decl)) {
1971 idlc()->scopes()->top()->addDeclaration(decl);
1973 } else {
1974 ErrorHandler::lookupError(
1975 ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
1977 delete $2;
1981 service_obsolete_dfn:
1984 idlc()->setParseState(
1985 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1986 ? PS_ServiceSqSeen : PS_SingletonSqSeen);
1988 service_exports
1990 idlc()->setParseState(
1991 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1992 ? PS_ServiceBodySeen : PS_SingletonBodySeen);
1996 idlc()->setParseState(
1997 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1998 ? PS_ServiceQsSeen : PS_SingletonQsSeen);
2002 type_dcl :
2003 IDL_TYPEDEF
2005 idlc()->setParseState(PS_TypedefSeen);
2007 type_declarator {}
2008 | struct_type {}
2009 | enum_type {}
2012 type_declarator :
2013 type_spec
2015 idlc()->setParseState(PS_TypeSpecSeen);
2016 if ($1 != nullptr && $1->getNodeType() == NT_instantiated_struct) {
2017 ErrorHandler::error0(ErrorCode::InstantiatedStructTypeTypedef);
2020 at_least_one_declarator
2022 idlc()->setParseState(PS_DeclaratorsSeen);
2024 AstScope* pScope = idlc()->scopes()->topNonNull();
2025 AstTypeDef* pTypeDef = nullptr;
2026 FeDeclList* pList = $3;
2027 FeDeclarator* pDecl = nullptr;
2028 AstType const * pType = nullptr;
2031 * Create nodes representing typedefs and add them to the
2032 * enclosing scope
2034 if ( pScope && $1 && pList )
2036 FeDeclList::iterator iter = pList->begin();
2037 FeDeclList::iterator end = pList->end();
2039 while (iter != end)
2041 pDecl = (*iter);
2042 if ( !pDecl )
2044 ++iter;
2045 continue;
2048 pType = FeDeclarator::compose($1);
2050 if ( !pType )
2052 ++iter;
2053 continue;
2056 pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);
2058 pScope->addDeclaration(pTypeDef);
2059 ++iter;
2060 delete pDecl;
2062 delete pList;
2067 at_least_one_declarator :
2068 declarator declarators
2070 if ( $2 )
2072 $2->push_back($1);
2073 $$ = $2;
2074 } else
2076 FeDeclList* pList = new FeDeclList;
2077 pList->push_back($1);
2078 $$ = pList;
2083 declarators :
2084 declarators
2087 idlc()->setParseState(PS_DeclsCommaSeen);
2089 declarator
2091 idlc()->setParseState(PS_DeclsDeclSeen);
2092 if ( $1 )
2094 $1->push_back($4);
2095 $$ = $1;
2096 } else
2098 FeDeclList* pList = new FeDeclList;
2099 pList->push_back($4);
2100 $$ = pList;
2103 | /* EMPTY */
2105 $$ = nullptr;
2109 declarator :
2110 identifier
2112 // For historic reasons, the struct com.sun.star.uno.Uik contains
2113 // members with illegal names (of the form "m_DataN"); avoid useless
2114 // warnings about them:
2115 AstScope * scope = idlc()->scopes()->top();
2116 if (scope == nullptr || scope->getScopeNodeType() != NT_struct
2117 || (scopeAsDecl(scope)->getScopedName()
2118 != "com::sun::star::uno::Uik"))
2120 checkIdentifier($1);
2123 $$ = new FeDeclarator(*$1);
2124 delete $1;
2128 at_least_one_scoped_name :
2129 scoped_name scoped_names
2131 if ($2)
2133 $2->push_front(*$1);
2134 $$ = $2;
2135 } else
2137 std::list< OString >* pScopedNames = new std::list< OString >;
2138 // coverity [copy_paste_error]
2139 pScopedNames->push_back(*$1);
2140 $$ = pScopedNames;
2142 delete $1;
2146 scoped_names :
2147 scoped_names
2150 idlc()->setParseState(PS_SNListCommaSeen);
2152 scoped_name
2154 idlc()->setParseState(PS_ScopedNameSeen);
2155 if ($1)
2157 $1->push_back(*$4);
2158 $$ = $1;
2159 } else
2161 std::list< OString >* pNames = new std::list< OString >;
2162 pNames->push_back(*$4);
2163 $$ = pNames;
2165 delete $4;
2167 | /* EMPTY */
2169 $$ = nullptr;
2173 scoped_name :
2174 identifier
2176 idlc()->setParseState(PS_SN_IDSeen);
2177 checkIdentifier($1);
2178 $$ = $1;
2180 | IDL_SCOPESEPARATOR
2182 idlc()->setParseState(PS_ScopeDelimSeen);
2184 identifier
2186 checkIdentifier($3);
2187 OString* pName = new OString("::");
2188 *pName += *$3;
2189 delete $3;
2190 $$ = pName;
2192 | scoped_name
2193 IDL_SCOPESEPARATOR
2196 identifier
2198 checkIdentifier($4);
2199 *$1 += ::rtl::OString("::");
2200 *$1 += *$4;
2201 delete $4;
2202 $$ = $1;
2206 type_spec :
2207 simple_type_spec
2208 | constructed_type_spec
2211 simple_type_spec :
2212 fundamental_type
2213 | scoped_name opt_type_args
2215 $$ = createNamedType($1, $2);
2219 fundamental_type:
2220 base_type_spec
2222 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2224 | sequence_type_spec
2227 opt_type_args:
2228 '<' type_args '>' { $$ = $2; }
2229 | /* empty */ { $$ = nullptr; }
2232 type_args:
2233 type_arg
2235 $$ = new DeclList;
2236 $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
2238 | type_args ',' type_arg
2240 $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
2241 $$ = $1;
2245 type_arg:
2246 simple_type_spec
2248 if ($1 != nullptr && static_cast< AstType const * >($1)->isUnsigned()) {
2249 ErrorHandler::error0(ErrorCode::UnsignedTypeArgument);
2251 $$ = $1;
2255 base_type_spec :
2256 integer_type
2257 | floating_pt_type
2258 | char_type
2259 | boolean_type
2260 | byte_type
2261 | any_type
2262 | type_type
2263 | string_type
2266 integer_type :
2267 signed_int
2268 | unsigned_int
2271 signed_int :
2272 IDL_LONG
2274 $$ = ET_long;
2276 | IDL_HYPER
2278 $$ = ET_hyper;
2280 | IDL_SHORT
2282 $$ = ET_short;
2286 unsigned_int :
2287 IDL_UNSIGNED IDL_LONG
2289 $$ = ET_ulong;
2291 | IDL_UNSIGNED IDL_HYPER
2293 $$ = ET_uhyper;
2295 | IDL_UNSIGNED IDL_SHORT
2297 $$ = ET_ushort;
2301 floating_pt_type :
2302 IDL_DOUBLE
2304 $$ = ET_double;
2306 | IDL_FLOAT
2308 $$ = ET_float;
2312 char_type :
2313 IDL_CHAR
2315 $$ = ET_char;
2319 byte_type :
2320 IDL_BYTE
2322 $$ = ET_byte;
2326 boolean_type :
2327 IDL_BOOLEAN
2329 $$ = ET_boolean;
2333 any_type :
2334 IDL_ANY
2336 $$ = ET_any;
2340 type_type :
2341 IDL_TYPE
2343 $$ = ET_type;
2347 string_type :
2348 IDL_STRING
2350 $$ = ET_string;
2354 constructed_type_spec :
2355 struct_type
2356 | enum_type
2359 sequence_type_spec :
2360 IDL_SEQUENCE
2362 idlc()->setParseState(PS_SequenceSeen);
2364 * Push a sequence marker on scopes stack
2366 idlc()->scopes()->push(nullptr);
2370 idlc()->setParseState(PS_SequenceSqSeen);
2372 simple_type_spec
2374 idlc()->setParseState(PS_SequenceTypeSeen);
2378 idlc()->setParseState(PS_SequenceQsSeen);
2380 * Remove sequence marker from scopes stack
2382 if (idlc()->scopes()->top() == nullptr)
2383 idlc()->scopes()->pop();
2385 * Create a node representing a sequence
2387 AstScope* pScope = idlc()->scopes()->bottom();
2388 AstDeclaration* pDecl = nullptr;
2389 AstDeclaration* pSeq = nullptr;
2391 if ( $5 )
2393 AstType const *pType = static_cast<AstType const *>($5);
2394 if ( pType )
2396 pSeq = new AstSequence(pType, pScope);
2398 * Add this AstSequence to the types defined in the global scope
2400 pDecl = pScope->addDeclaration(pSeq);
2401 if ( pSeq != pDecl )
2403 // if sequence type already defined then use it
2404 delete pSeq;
2405 pSeq = pDecl;
2409 $$ = pSeq;
2411 | error '>'
2413 yyerror("sequence declaration");
2414 yyerrok;
2415 $$ = nullptr;
2419 struct_type :
2420 structure_header
2422 idlc()->setParseState(PS_StructHeaderSeen);
2424 AstScope* pScope = idlc()->scopes()->topNonNull();
2425 AstStruct* pStruct = nullptr;
2427 if ( pScope )
2429 AstStruct const* pBase= static_cast< AstStruct const* >(resolveTypedefs($1->getInherits()));
2430 pStruct = new AstStruct(
2431 *$1->getName(), $1->getTypeParameters(), pBase, pScope);
2432 pScope->addDeclaration(pStruct);
2435 * Push the scope of the struct on the scopes stack
2437 idlc()->scopes()->push(pStruct);
2438 delete $1;
2442 idlc()->setParseState(PS_StructSqSeen);
2444 at_least_one_member
2446 idlc()->setParseState(PS_StructBodySeen);
2450 idlc()->setParseState(PS_StructQsSeen);
2451 /* this exception is finished, pop its scope from the stack */
2452 idlc()->scopes()->pop();
2456 structure_header :
2457 IDL_STRUCT
2459 idlc()->setParseState(PS_StructSeen);
2461 identifier
2463 idlc()->setParseState(PS_StructIDSeen);
2464 checkIdentifier($3);
2466 opt_type_params
2467 inheritance_spec
2469 idlc()->setParseState(PS_InheritSpecSeen);
2471 // Polymorphic struct type templates with base types would cause various
2472 // problems in language bindings, so forbid them here. For example,
2473 // GCC prior to version 3.4 fails with code like
2475 // struct Base { ... };
2476 // template< typename typeparam_T > struct Derived: public Base {
2477 // int member1 CPPU_GCC3_ALIGN(Base);
2478 // ... };
2480 // (Note that plain struct types with instantiated polymorphic struct
2481 // type bases, which might also cause problems in language bindings, are
2482 // already rejected on a syntactic level.)
2483 if ($5 != nullptr && $6 != nullptr) {
2484 ErrorHandler::error0(ErrorCode::StructTypeTemplateWithBase);
2487 $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
2488 delete $5;
2489 delete $6;
2493 opt_type_params:
2494 '<' type_params '>' { $$ = $2; }
2495 | /* empty */ { $$ = nullptr; }
2498 type_params:
2499 identifier
2501 $$ = new std::vector< rtl::OString >;
2502 $$->push_back(*$1);
2503 delete $1;
2505 | type_params ',' identifier
2507 if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
2508 ErrorHandler::error0(ErrorCode::IdenticalTypeParameters);
2510 $1->push_back(*$3);
2511 delete $3;
2512 $$ = $1;
2516 at_least_one_member : member members ;
2518 members :
2519 members member
2520 | /* EMPTY */
2523 member :
2524 type_or_parameter
2526 idlc()->setParseState(PS_MemberTypeSeen);
2528 at_least_one_declarator
2530 idlc()->setParseState(PS_MemberDeclsSeen);
2534 idlc()->setParseState(PS_MemberDeclsCompleted);
2536 AstScope* pScope = idlc()->scopes()->topNonNull();
2537 AstMember* pMember = nullptr;
2538 FeDeclList* pList = $3;
2539 FeDeclarator* pDecl = nullptr;
2540 AstType const * pType = nullptr;
2542 // !!! check recursive type
2544 if ( pScope && pList && $1 )
2546 FeDeclList::iterator iter = pList->begin();
2547 FeDeclList::iterator end = pList->end();
2548 while (iter != end)
2550 pDecl = (*iter);
2551 if ( !pDecl )
2553 ++iter;
2554 continue;
2557 pType = FeDeclarator::compose($1);
2559 if ( !pType )
2561 ++iter;
2562 continue;
2565 pMember = new AstMember(pType, pDecl->getName(), pScope);
2567 if ( !pDecl->checkType($1) )
2569 // WARNING
2572 pScope->addDeclaration(pMember);
2573 ++iter;
2574 delete pDecl;
2576 delete pList;
2579 | error ';'
2581 yyerror("member definition");
2582 yyerrok;
2586 type_or_parameter:
2587 fundamental_type
2588 | scoped_name opt_type_args
2590 AstDeclaration const * decl = nullptr;
2591 AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top());
2592 if (scope != nullptr && $2 == nullptr) {
2593 decl = scope->findTypeParameter(*$1);
2595 if (decl != nullptr) {
2596 delete $1;
2597 delete $2;
2598 } else {
2599 decl = createNamedType($1, $2);
2600 if (scope != nullptr && includes(decl, scopeAsDecl(scope))) {
2601 ErrorHandler::error1(
2602 ErrorCode::RecursiveType, scopeAsDecl(scope));
2603 decl = nullptr;
2606 $$ = decl;
2610 enum_type :
2611 IDL_ENUM
2613 idlc()->setParseState(PS_EnumSeen);
2615 identifier
2617 idlc()->setParseState(PS_EnumIDSeen);
2618 checkIdentifier($3);
2620 AstScope* pScope = idlc()->scopes()->topNonNull();
2621 AstEnum* pEnum = nullptr;
2624 * Create a node representing an enum and add it to its
2625 * enclosing scope
2627 if (pScope != nullptr)
2629 pEnum = new AstEnum(*$3, pScope);
2631 * Add it to its defining scope
2633 pScope->addDeclaration(pEnum);
2635 delete $3;
2637 * Push the enum scope on the scopes stack
2639 idlc()->scopes()->push(pEnum);
2644 idlc()->setParseState(PS_EnumSqSeen);
2646 at_least_one_enumerator
2648 idlc()->setParseState(PS_EnumBodySeen);
2652 idlc()->setParseState(PS_EnumQsSeen);
2654 * Done with this enum. Pop its scope from the scopes stack
2656 if (idlc()->scopes()->top() == nullptr)
2657 $$ = nullptr;
2658 else
2660 $$ = static_cast<AstEnum*>(idlc()->scopes()->topNonNull());
2661 idlc()->scopes()->pop();
2666 at_least_one_enumerator : enumerator enumerators ;
2668 enumerators :
2669 enumerators
2672 idlc()->setParseState(PS_EnumCommaSeen);
2674 enumerator
2675 | /* EMPTY */
2676 | error ','
2678 yyerror("enumerator definition");
2679 yyerrok;
2683 enumerator :
2684 identifier
2686 checkIdentifier($1);
2688 AstScope* pScope = idlc()->scopes()->topNonNull();
2689 AstEnum* pEnum = nullptr;
2690 AstConstant* pEnumVal = nullptr;
2692 if ( pScope && pScope->getScopeNodeType() == NT_enum)
2694 pEnum = static_cast<AstEnum*>(pScope);
2695 if (pEnum && $1)
2697 AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
2698 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2699 pExpr, *$1, pScope);
2701 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2702 ErrorHandler::error1(ErrorCode::Eval, pEnum);
2704 pScope->addDeclaration(pEnumVal);
2706 delete $1;
2708 | identifier
2710 const_expr
2712 checkIdentifier($1);
2714 AstScope* pScope = idlc()->scopes()->topNonNull();
2715 AstEnum* pEnum = nullptr;
2716 AstConstant* pEnumVal = nullptr;
2718 if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
2720 $3->evaluate();
2721 if ( $3->coerce(ET_long) )
2723 pEnum = static_cast<AstEnum*>(pScope);
2724 if (pEnum)
2726 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2727 $3, *$1, pScope);
2729 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2730 ErrorHandler::error1(ErrorCode::Eval, pEnum);
2732 pScope->addDeclaration(pEnumVal);
2733 } else
2735 ErrorHandler::coercionError($3, ET_long);
2736 delete $3;
2739 delete $1;
2743 identifier:
2744 IDL_IDENTIFIER
2745 | IDL_GET { $$ = new OString("get"); }
2746 | IDL_SET { $$ = new OString("set"); }
2747 | IDL_PUBLISHED { $$ = new OString("published"); }
2753 * Report an error situation discovered in a production
2755 void yyerror(char const *errmsg)
2757 ErrorHandler::syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
2758 idlc()->setParseState(PS_NoState);
2761 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */