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