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