1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: No names yet. 3 // Purpose: To provide a simple _framework_ 4 // for series of source code parsers with 5 // compatible interfaces 6 // Author: Aleksandras Gluchovas 7 // Modified by: AG on 28/12/98 8 // Created: 22/09/98 9 // RCS-ID: $Id: srcparser.h 41718 2006-10-08 14:34:37Z VZ $ 10 // Copyright: (c) Aleskandars Gluchovas 11 // Licence: wxWindows licence 12 ///////////////////////////////////////////////////////////////////////////// 13 14 #ifndef __SRCPARSER_G__ 15 #define __SRCPARSER_G__ 16 17 #if defined( wxUSE_TEMPLATE_STL ) 18 #include <vector> 19 20 #ifdef WIN32 21 #include <bstring.h> 22 #else 23 24 #include <strclass.h> 25 #include <string.h> 26 27 #endif 28 29 #else 30 #include "wx/string.h" 31 #include "wxstlvec.h" 32 33 #endif 34 35 #include "markup.h" // markup tags used in spOperator::GetFullName() 36 37 // these methods are used for debugging only and disappear in the release build 38 #ifdef __WXDEBUG__ 39 #define DECLARE_DUMP virtual void DumpThis(const wxString& indent) const; 40 #else 41 #define DECLARE_DUMP 42 #endif 43 44 // context class list in "inside-out" order : 45 46 class spContext; 47 48 class spParameter; 49 class spAttribute; 50 class spOperation; 51 class spEnumeration; 52 class spTypeDef; 53 class spPreprocessorLine; 54 class spClass; 55 class spNameSpace; 56 class spFile; 57 58 // source context visibilities 59 enum SRC_VISIBLITY_TYPES 60 { 61 SP_VIS_PUBLIC, 62 SP_VIS_PROTECTED, 63 SP_VIS_PRIVATE 64 }; 65 66 // class types 67 enum SP_CLASS_TYPES 68 { 69 SP_CLTYPE_INVALID, 70 SP_CLTYPE_CLASS, 71 SP_CLTYPE_TEMPLATE_CLASS, 72 SP_CLTYPE_STRUCTURE, 73 SP_CLTYPE_UNION, 74 SP_CLTYPE_INTERFACE 75 }; 76 77 // inheritance types 78 enum SP_INHERITANCE_TYPES 79 { 80 SP_INHERIT_VIRTUAL, 81 SP_INHERIT_PUBLIC, 82 SP_INHERIT_PRIVATE 83 }; 84 85 // proprocessor definitions types (specific to C++ code) 86 87 enum SP_PREP_DEFINITION_TYPES 88 { 89 SP_PREP_DEF_DEFINE_SYMBOL, 90 SP_PREP_DEF_REDEFINE_SYMBOL, 91 SP_PREP_DEF_INCLUDE_FILE, 92 SP_PREP_DEF_OTHER 93 }; 94 95 // common context types 96 97 #define SP_CTX_UNKNOWN 0x000 98 #define SP_CTX_FILE 0x001 99 #define SP_CTX_NAMESPACE 0x002 100 #define SP_CTX_CLASS 0x004 101 #define SP_CTX_TYPEDEF 0x008 102 #define SP_CTX_PREPROCESSOR 0x010 103 #define SP_CTX_ENUMERATION 0x020 104 #define SP_CTX_ATTRIBUTE 0x040 105 #define SP_CTX_OPERATION 0x080 106 #define SP_CTX_PARAMETER 0x100 107 108 // other (custom) context codes may be defined elsewere, however they should 109 // not clash with above codes for common type and also should not 110 // exceed 16-bits of in value 111 112 // masks all context types (up to 16 custom context can be defined) 113 114 #define SP_CTX_ANY 0xFFFF 115 116 class spComment; 117 118 119 120 #if defined( wxUSE_TEMPLATE_STL ) 121 122 // context members 123 typedef vector<spContext*> MMemberListT; 124 // comments list 125 typedef vector<spComment*> MCommentListT; 126 // list of parameters 127 typedef vector<spParameter*> MParamListT; 128 // wxString list 129 typedef vector<wxString> StrListT; 130 131 #else 132 133 typedef spContext* spContextPtrT; 134 typedef spComment* spCommentPtrT; 135 typedef spParameter* spParameterPtrT; 136 typedef WXSTL_VECTOR_SHALLOW_COPY(spContextPtrT) MMemberListT; 137 typedef WXSTL_VECTOR_SHALLOW_COPY(spCommentPtrT) MCommentListT; 138 typedef WXSTL_VECTOR_SHALLOW_COPY(spParameterPtrT) MParamListT; 139 typedef WXSTL_VECTOR_SHALLOW_COPY(wxString) StrListT; 140 141 #endif 142 // base class for all visitors of source code contents 143 144 class spVisitor 145 { 146 protected: 147 bool mSiblingSkipped; 148 bool mChildSkipped; 149 int mContextMask; 150 151 spContext* mpCurCxt; 152 153 public: 154 // methods invoked by context 155 156 // method invoked from user's controling code 157 // to visit all nodes staring at the given context. 158 // Content is sorted if requrired, see comments 159 // spClass on sorting the class members 160 161 void VisitAll( spContext& atContext, 162 bool sortContent = true 163 ); 164 165 // methods invoked by visitor 166 167 // goes to the next context in the outter scope 168 // NOTE:: should not be invoked more than once while 169 // visiting certain context 170 171 void SkipSiblings(); 172 173 // prevents going down into the contexts contained by 174 // the current context 175 // NOTE:: the same as above 176 177 void SkipChildren(); 178 179 // can be called only in from visiting procedure 180 void RemoveCurrentContext(); 181 182 // method enables fast filtered traversal 183 // of source content, e.g. collecting only classes, 184 // or only global functions 185 186 // arg. context - can contain combination of contexts concatinated 187 // with bitwise OR, e.g. SP_CTX_CLASS | SP_CTX_NAMESPACE 188 // 189 // method can be invoked from the user's controling as well as 190 // from within the visting procedure 191 192 void SetFilter( int contextMask ); 193 194 // methods should be implemneted by specific visitor: 195 196 // NOTE:: Do not confuse visiting with parsing, first 197 // the source is parsed, and than can be visited 198 // multiple times by variouse visitors (there can 199 // be more the one visitor visiting content at a time) 200 VisitFile(spFile & WXUNUSED (fl))201 virtual void VisitFile( spFile& WXUNUSED(fl) ) {} 202 VisitNameSpace(spNameSpace & WXUNUSED (ns))203 virtual void VisitNameSpace( spNameSpace& WXUNUSED(ns) ) {} 204 VisitClass(spClass & WXUNUSED (cl))205 virtual void VisitClass( spClass& WXUNUSED(cl) ) {} 206 VisitEnumeration(spEnumeration & WXUNUSED (en))207 virtual void VisitEnumeration( spEnumeration& WXUNUSED(en) ) {} 208 VisitTypeDef(spTypeDef & WXUNUSED (td))209 virtual void VisitTypeDef( spTypeDef& WXUNUSED(td) ) {} 210 VisitPreprocessorLine(spPreprocessorLine & WXUNUSED (pd))211 virtual void VisitPreprocessorLine( spPreprocessorLine& WXUNUSED(pd) ) {} 212 VisitAttribute(spAttribute & WXUNUSED (attr))213 virtual void VisitAttribute( spAttribute& WXUNUSED(attr) ) {} 214 VisitOperation(spOperation & WXUNUSED (op))215 virtual void VisitOperation( spOperation& WXUNUSED(op) ) {} 216 VisitParameter(spParameter & WXUNUSED (param))217 virtual void VisitParameter( spParameter& WXUNUSED(param) ) {} 218 VisitCustomContext(spContext & WXUNUSED (ctx))219 virtual void VisitCustomContext( spContext& WXUNUSED(ctx) ) {} 220 ~spVisitor()221 virtual ~spVisitor() { } 222 }; 223 224 // stores one section of comments, 225 // multiple sections can be put to geather 226 // and attached to some context 227 228 class spComment 229 { 230 public: 231 wxString m_Text; 232 bool mIsMultiline; // multiline comments ar those with /**/'s 233 234 // true, if these was an empty empty 235 // line above single line comment 236 237 bool mStartsPar; 238 239 public: 240 241 bool IsMultiline() const; 242 bool StartsParagraph() const; 243 244 wxString& GetText(); 245 246 // contstant version of GetText() 247 wxString GetText() const; 248 }; 249 250 // abstract base class for common (to most languages) code 251 // contexts (constructs), e.g file, namespace, class, operation, 252 // etc 253 254 class spContext 255 { 256 protected: 257 // "linked" list of comments belonging to this context 258 MCommentListT mComments; 259 260 // NULL, if this is file context 261 MMemberListT mMembers; 262 263 // NULL, if this is top-most context 264 spContext* m_pParent; 265 266 // points to context object, where the this context 267 // was originally declared, meaning that this object 268 // is redeclaration (or if in the case of operation 269 // this context object most probably referres to the 270 // implemnetation in .cpp file for example) 271 272 // is NULL, if this object referres to the first occurence 273 // of the context 274 275 spContext* mpFirstOccurence; 276 277 // used, to avoid excessive sorting of context's agreggates 278 bool mAlreadySorted; 279 280 public: 281 282 // source line number, (-1) if unknown 283 int mSrcLineNo; 284 285 // offset of context in the source file, (-1) if unknown 286 int mSrcOffset; 287 288 // lentgh of the context in characters, (-1) if unknown 289 int mContextLength; 290 291 // source line number, in which this cotext ends, (-1) if unknown 292 int mLastScrLineNo; 293 294 // fields are valid, if the may contain other contexts nested inside 295 int mHeaderLength; 296 int mFooterLength; 297 298 // zero-based index of the first character of 299 // this context in the source line, (-1) if unknown 300 int mFirstCharPos; 301 302 // zero-based index of the first character of 303 // this context in the last source line of this context, (-1) if unknown 304 int mLastCharPos; 305 306 // see SRC_VISIBLITY_TYPES enumeration 307 int mVisibility; 308 309 // true, if context does not really exist in the source 310 // but was created by external tools (e.g. forward engineering) 311 312 bool mIsVirtualContext; 313 bool mVirtualContextHasChildren; 314 315 // body of the context in case (mIsVirtual == true) 316 wxString mVirtualContextBody; 317 wxString mVittualContextFooter; 318 319 // e.g. can be used by documentation generator to store 320 // reference to section object 321 void* mpUserData; 322 323 public: 324 // universal identifier of the context (e.g. class name) 325 wxString m_Name; 326 327 public: 328 // default constructor 329 spContext(); 330 331 // automatically destorys all aggregated contexts 332 // (thus, it's enought to call destructor of root-context) 333 virtual ~spContext(); 334 335 // see mUererData member; GetUserData()336 void* GetUserData() { return mpUserData; } 337 338 // sets untyped pointer to user data SetUserData(void * pUserData)339 void SetUserData( void* pUserData ) 340 { mpUserData = pUserData; } 341 342 // searches the whole context tree for the cotnexts 343 // which match given masks, pust results into lst array 344 void GetContextList( MMemberListT& lst, int contextMask ); 345 346 // used by default visitor's implementation 347 bool IsSorted(); 348 349 /*** forward/reverse ingineering fecilities ***/ 350 351 bool PositionIsKnown(); 352 353 bool IsVirtualContext(); 354 355 bool VitualContextHasChildren(); 356 357 void SetVirtualContextBody( const wxString& body, 358 bool hasChildren = false, 359 const wxString& footer = wxEmptyString ); 360 361 wxString GetVirtualContextBody(); 362 wxString GetFooterOfVirtualContextBody(); 363 364 // can be overriden by top-level context classes 365 // to find-out ot the source-fragment of this 366 // context using it's position information 367 virtual wxString GetBody( spContext* pCtx = NULL ); 368 369 virtual wxString GetHeader( spContext* pCtx = NULL ); 370 371 // true, if there is at least one entry 372 // in the comment list of this context 373 bool HasComments(); GetCommentList()374 MCommentListT& GetCommentList() { return mComments; } GetCommentList()375 const MCommentListT& GetCommentList() const { return mComments; } 376 377 // should be overriden, if the context supports sorting 378 // of it's members SortMembers()379 virtual void SortMembers() {} 380 381 // returns identifier of this context GetName()382 inline wxString& GetName() { return m_Name; } 383 384 // returns -1, if souce line # is unknow GetSourceLineNo()385 inline int GetSourceLineNo() { return mSrcLineNo; } 386 387 // see comments on mpFirstOccurence member variable 388 bool IsFirstOccurence(); 389 spContext* GetFirstOccurence(); 390 391 // returns not-NULL value if this context 392 // is aggregated by another cotnext 393 spContext* GetOutterContext(); 394 395 // perhaps more intuitive alias for `GetOutterContext()' GetParent()396 inline spContext* GetParent() { return m_pParent; } 397 398 bool HasOutterContext(); 399 400 // add one aggregate (or child) into this context 401 void AddMember ( spContext* pMember ); 402 MMemberListT& GetMembers(); 403 404 // append comment to the comment list decribing 405 // this context 406 void AddComment( spComment* pComment ); 407 408 // returns NULL, if the context with the given 409 // name and type is not contained by this context 410 // and it's children. Children's children are not 411 // searched recursivelly if searchSubMembers is false 412 413 spContext* FindContext( const wxString& identifier, 414 int contextType = SP_CTX_ANY, 415 bool searchSubMembers = true 416 ); 417 418 // removes this context from it's parent 419 // (NOTE:: context should have an outter cotnext 420 // to when this method is called, otherwise removal 421 // will result assertion failure) 422 void RemoveThisContext(); 423 424 // returns true, if this object is aggregated in the file 425 bool IsInFile(); 426 427 // true, if outter context is a namespace 428 bool IsInNameSpace(); 429 430 // true, if outter context is a class 431 bool IsInClass(); 432 433 // true, if outter cotext is an operation (true for "spParameter"s) 434 bool IsInOperation(); 435 436 // true if the context is public IsPublic()437 bool IsPublic() const { return mVisibility == SP_VIS_PUBLIC; } 438 439 // NOTE:: method returns not the type of this object 440 // but the file/namespace/class/operation or file in which this 441 // attribute is contained. First, check for the type of 442 // context using the above method. 443 444 // Requiering container which does not exist, will result 445 // in assertion failure 446 447 spClass& GetClass(); 448 spFile& GetFile(); 449 spNameSpace& GetNameSpace(); 450 spOperation& GetOperation(); 451 452 // each new context should override this method 453 // to return it's specific type GetContextType()454 virtual int GetContextType() const { return SP_CTX_UNKNOWN; } 455 456 // perhaps more intuitive short-cut GetType()457 inline int GetType() { return GetContextType(); } 458 459 // cast this context to the desired type - returns NULL if type is wrong CastToAttribute()460 spAttribute *CastToAttribute() 461 { 462 return GetContextType() == SP_CTX_ATTRIBUTE ? (spAttribute *)this 463 : NULL; 464 } 465 466 // derived classes override this to invoke VisitXXX method 467 // which corresponds to the class of specific context, 468 // - this is what the "Visitor" pattern told us ^) 469 470 // if method is not overriden, then it's probably user-defined 471 // custom context 472 AcceptVisitor(spVisitor & visitor)473 virtual void AcceptVisitor( spVisitor& visitor ) 474 475 { visitor.VisitCustomContext( *this ); }; 476 477 // called by visitors, to remove given subcontext 478 // of this context object 479 void RemoveChild( spContext* pChild ); 480 481 void RemoveChildren(); 482 483 spContext* GetEnclosingContext( int mask = SP_CTX_ANY ); 484 485 #ifdef __WXDEBUG__ 486 virtual void Dump(const wxString& indent) const; 487 #endif // __WXDEBUG__ 488 489 DECLARE_DUMP 490 }; 491 492 // stores information about single argument of operation 493 494 class spParameter : public spContext 495 { 496 public: 497 // type of argument (parameter) 498 wxString m_Type; 499 500 // "stringified" initial value 501 wxString m_InitVal; 502 503 public: GetContextType()504 virtual int GetContextType() const { return SP_CTX_PARAMETER; } 505 AcceptVisitor(spVisitor & visitor)506 virtual void AcceptVisitor( spVisitor& visitor ) 507 { visitor.VisitParameter( *this ); } 508 509 DECLARE_DUMP 510 }; 511 512 513 // stores information about member(or global) variable 514 515 class spAttribute : public spContext 516 { 517 public: 518 // type of the attribute 519 wxString m_Type; 520 521 // it's initial value 522 wxString m_InitVal; 523 524 // constantness 525 bool mIsConstant; 526 public: 527 GetContextType()528 virtual int GetContextType() const { return SP_CTX_ATTRIBUTE; } 529 AcceptVisitor(spVisitor & visitor)530 virtual void AcceptVisitor( spVisitor& visitor ) 531 { visitor.VisitAttribute( *this ); } 532 533 DECLARE_DUMP 534 }; 535 536 class spOperation : public spContext 537 { 538 public: 539 // type of return value 540 wxString m_RetType; 541 542 // argument list 543 //MParamListT mParams; 544 545 // true, if operation does not modify 546 // the content of the object 547 bool mIsConstant; 548 549 // flag, specific to C++ 550 bool mIsVirtual; 551 552 // true, if definition follows the declaration immediatelly 553 bool mHasDefinition; 554 555 // scope if any (e.g. MyClass::MyFunction(), scope stirng is "MyClass" ) 556 // usually found along with implementation of the method, which is now skipped 557 558 wxString mScope; 559 560 public: 561 spOperation(); 562 563 // returns full declaration of the operations 564 // (ret val., identifier, arg. list), 565 566 // arguments are marked up with italic, 567 // default values marked up with bold-italic, 568 // all the rest is marked as bold 569 570 // NOTE:: this method may be overriden by class 571 // specific to concrete parser, to provide 572 // language-dependent reperesnetation of 573 // operation and it's argumetn list 574 // 575 // the default implementation outputs name in 576 // C++/Java syntax 577 578 virtual wxString GetFullName(MarkupTagsT tags); 579 GetContextType()580 virtual int GetContextType() const { return SP_CTX_OPERATION; } 581 AcceptVisitor(spVisitor & visitor)582 virtual void AcceptVisitor( spVisitor& visitor ) 583 { visitor.VisitOperation( *this ); } 584 585 DECLARE_DUMP 586 }; 587 588 // stores infromation about preprocessor directive 589 590 class spPreprocessorLine : public spContext 591 { 592 593 public: 594 595 // prepocessor statement including '#' and 596 // attached multiple lines with '\' character 597 wxString m_Line; 598 599 int mDefType; // see SP_PREP_DEFINITION_TYPES enumeration 600 601 public: 602 GetContextType()603 virtual int GetContextType() const { return SP_CTX_PREPROCESSOR; } 604 GetStatementType()605 virtual int GetStatementType() const { return mDefType; } 606 607 wxString CPP_GetIncludedFileNeme() const; 608 AcceptVisitor(spVisitor & visitor)609 virtual void AcceptVisitor( spVisitor& visitor ) 610 { visitor.VisitPreprocessorLine( *this ); } 611 612 DECLARE_DUMP 613 }; 614 615 // stores information about the class 616 617 class spClass : public spContext 618 { 619 public: 620 // list of superclasses/interfaces 621 StrListT m_SuperClassNames; 622 623 // see SP_CLASS_TYPES enumeration 624 int mClassSubType; 625 626 // see SP_INHERITANCE_TYPES enumeration 627 int mInheritanceType; 628 629 // valid if mClassSubType is SP_CLTYPE_TEMPLATE_CLASS 630 wxString mTemplateTypes; 631 632 // true, if it's and interface of abstract base class 633 bool mIsAbstract; 634 635 public: 636 // sorts class members in the following order: 637 // 638 // (by "privacy level" - first private, than protected, public) 639 // 640 // within above set 641 // 642 // (by member type - attributes first, than methods, nested classes) 643 // 644 // within above set 645 // 646 // (by identifier of the member) 647 648 virtual void SortMembers(); 649 GetContextType()650 virtual int GetContextType() const { return SP_CTX_CLASS; } 651 AcceptVisitor(spVisitor & visitor)652 virtual void AcceptVisitor( spVisitor& visitor ) 653 { visitor.VisitClass( *this ); } 654 655 DECLARE_DUMP 656 }; 657 658 // stores information about enum statement 659 660 class spEnumeration : public spContext 661 { 662 public: 663 wxString m_EnumContent; // full-text content of enumeration 664 665 public: GetContextType()666 virtual int GetContextType() const { return SP_CTX_ENUMERATION; } 667 AcceptVisitor(spVisitor & visitor)668 virtual void AcceptVisitor( spVisitor& visitor ) 669 { visitor.VisitEnumeration( *this ); } 670 671 DECLARE_DUMP 672 }; 673 674 class spTypeDef : public spContext 675 { 676 public: 677 // the original type which is redefined 678 // by this type definition 679 wxString m_OriginalType; 680 681 public: GetContextType()682 virtual int GetContextType() const { return SP_CTX_TYPEDEF; } 683 AcceptVisitor(spVisitor & visitor)684 virtual void AcceptVisitor( spVisitor& visitor ) 685 { visitor.VisitTypeDef( *this ); } 686 687 DECLARE_DUMP 688 }; 689 690 // NOTE:: files context may be put to other 691 // file context, resulting in a collection 692 // of parsed file contexts, with a virtual "superfile" 693 694 class spFile : public spContext 695 { 696 public: 697 // since file name cannot be determined from 698 // source code, filling in this field is optional 699 wxString m_FileName; 700 701 public: GetContextType()702 virtual int GetContextType() const { return SP_CTX_FILE; } 703 AcceptVisitor(spVisitor & visitor)704 virtual void AcceptVisitor( spVisitor& visitor ) 705 { visitor.VisitFile( *this ); } 706 707 DECLARE_DUMP 708 }; 709 710 //TODO:: comments. 711 712 class SourceParserPlugin 713 { 714 public: 715 virtual bool CanUnderstandContext( char* cur, char* end, spContext* pOuttterCtx ) = 0; 716 virtual void ParseContext( char* start, char*& cur, char* end, spContext* pOuttterCtx ) = 0; 717 ~SourceParserPlugin()718 virtual ~SourceParserPlugin() { } 719 }; 720 721 // abstract interface for source parsers 722 // which can output parsing results in the 723 // form of context-tree, where each node 724 // should be derivative of spContext, (see 725 // above classes) 726 727 class SourceParserBase 728 { 729 private: 730 // auto-resizing file buffer, created in ParseFile() 731 // to reuse large heap block for multiple parsings 732 733 char* mpFileBuf; 734 int mFileBufSz; 735 736 protected: 737 SourceParserPlugin* mpPlugin; 738 739 protected: 740 // value is set in the derived parser classes 741 int mParserStatus; 742 743 public: 744 SourceParserBase(); 745 virtual ~SourceParserBase(); 746 747 // loads entier source file(as text) into memory, 748 // and passes it's contents to ParseAll() method, 749 // memory occupied by source text is released after 750 // parsing is done 751 // 752 // (NOTE:: this is the default implementation), 753 754 virtual spFile* ParseFile( const char* fname ); 755 756 // should returns the root-node of the created context tree 757 // (user is responsible for releasing it from the heep) 758 // "end" should point to the (last character + 1) of the 759 // source text area 760 761 virtual spFile* Parse( char* start, char* end ) = 0; 762 763 // returns parser "status word" (specific to concrete parser) GetParserStatus()764 int GetParserStatus() { return mParserStatus; } 765 766 void SetPlugin( SourceParserPlugin* pPlugin ); 767 }; 768 769 #endif 770