1 #ifndef COMPLEXSUP_H 2 #define COMPLEXSUP_H 3 4 #include <iostream> 5 #include <fstream> 6 using namespace std; 7 8 extern "C" 9 { 10 #include <string.h> 11 #include "classes.h" 12 #include "../express/express.h" 13 #include "../exppp/exppp.h" 14 #include "../express/dict.h" 15 } 16 17 #define FALSE 0 18 #define TRUE 1 19 #define DONT_KNOW -1 20 #define LISTEND 999 21 // LISTEND signifies that an OrList has gone beyond its last viable choice 22 // among its children. 23 24 enum MarkType { 25 NOMARK, ORMARK, MARK 26 }; 27 // MARK is the usual value we'd mark with. If we mark with ORMARK, it means 28 // an OrList marked this node, so we'll know it may become unmarked later if 29 // we try another choice. 30 31 enum MatchType { 32 UNKNOWN, UNSATISFIED, SATISFIED, MATCHSOME, MATCHALL, NEWCHOICE, NOMORE 33 }; 34 // These are the conditions the EntList::match() functions may return. They 35 // are also the assigned values to EntList::viable. 36 // 37 // UNKNOWN - The default EntList::viable value - before any matching 38 // has been attempted. 39 // UNSATISFIED - EntList had conditions that EntNode did not satisfy (e.g., 40 // EntList specified A AND B while EntNode only contained an 41 // A). 42 // SATISFIED - EntList had no conditions EntNode did not meet. But, 43 // EntList did not match (mark) any nodes of EntNode which 44 // were not already matched. 45 // MATCHSOME - EntList matched some of the nodes in EntNode. 46 // MATCHALL - EntList matched all the nodes in EntNode (complex entity 47 // can be instantiated). 48 // MORECHOICES - Special case - when trying alternate OR paths, this return 49 // value signifies that we have found another choice. 50 // NOMORE - Special case - when trying alternate OR paths, this return 51 // value signifies that no more alternates within this path. 52 53 enum JoinType { 54 SIMPLE, AND, OR, ANDOR 55 }; 56 57 class SimpleList; 58 class MultList; 59 class JoinList; 60 class AndOrList; 61 class AndList; 62 class OrList; 63 class ComplexList; 64 class ComplexCollect; 65 66 class EntNode { 67 friend class SimpleList; 68 friend class AndOrList; 69 friend class AndList; 70 friend class OrList; 71 friend class ComplexList; 72 73 public: 74 EntNode( const char * nm = "" ) : next( 0 ), mark( NOMARK ), 75 multSupers( 0 ) { 76 strcpy( name, nm ); 77 } 78 EntNode( char *[] ); // given a list, create a linked list of EntNodes ~EntNode()79 ~EntNode() { 80 if( next ) { 81 delete next; 82 } 83 } 84 operator const char * () { 85 return name; 86 } 87 int operator== ( EntNode & ent ) { 88 return ( strcmp( name, ent.name ) == 0 ); 89 } 90 int operator< ( EntNode & ent ) { 91 return ( strcmp( name, ent.name ) < 0 ); 92 } 93 int operator> ( EntNode & ent ) { 94 return ( strcmp( name, ent.name ) > 0 ); 95 } 96 void setmark( MarkType stamp = MARK ) { 97 mark = stamp; 98 } 99 void markAll( MarkType = MARK ); unmarkAll()100 void unmarkAll() { 101 markAll( NOMARK ); 102 } 103 int marked( MarkType base = ORMARK ) { 104 return ( mark >= base ); 105 } 106 int allMarked(); // returns TRUE if all nodes in list are marked 107 int unmarkedCount(); multSuprs()108 int multSuprs() { 109 return multSupers; 110 } multSuprs(int j)111 void multSuprs( int j ) { 112 multSupers = j; 113 } 114 115 EntNode * next; 116 117 private: 118 MarkType mark; 119 char name[BUFSIZ]; 120 int multSupers; // do I correspond to an entity with >1 supertype? 121 }; 122 123 class EntList { 124 friend class MultList; 125 friend class JoinList; 126 friend class OrList; 127 friend class ComplexList; 128 friend class ComplexCollect; 129 friend ostream & operator<< ( ostream &, EntList & ); 130 friend ostream & operator<< ( ostream &, MultList & ); 131 132 public: EntList(JoinType j)133 EntList( JoinType j ) : join( j ), prev( 0 ), next( 0 ), viable( UNKNOWN ), 134 level( 0 ) {} ~EntList()135 virtual ~EntList() {} viableVal()136 MatchType viableVal() { 137 return viable; 138 } setLevel(int l)139 virtual void setLevel( int l ) { 140 level = l; 141 } getMaxLevel()142 virtual int getMaxLevel() { 143 return level; 144 } 145 virtual int contains( const char * ) = 0; 146 virtual int hit( const char * ) = 0; 147 virtual int isDependent( const char * ) = 0; matchNonORs(EntNode *)148 virtual MatchType matchNonORs( EntNode * ) { 149 return UNKNOWN; 150 } 151 virtual int acceptChoice( EntNode * ) = 0; 152 virtual void unmarkAll( EntNode * ) = 0; reset()153 virtual void reset() { 154 viable = UNKNOWN; 155 } 156 int siblings(); 157 virtual void write( ostream & ) = 0; 158 // write out my contents to stream 159 160 // List access functions. They access desired children based on their 161 // join or viable values. Below is an incomplete list of possible fns, 162 // but all we need. 163 EntList * firstNot( JoinType ); nextNot(JoinType j)164 EntList * nextNot( JoinType j ) { 165 return next->firstNot( j ); 166 } 167 EntList * firstWanted( MatchType ); nextWanted(MatchType mat)168 EntList * nextWanted( MatchType mat ) { 169 return next->firstWanted( mat ); 170 } 171 EntList * lastNot( JoinType ); prevNot(JoinType j)172 EntList * prevNot( JoinType j ) { 173 return prev->lastNot( j ); 174 } 175 EntList * lastWanted( MatchType ); prevWanted(MatchType mat)176 EntList * prevWanted( MatchType mat ) { 177 return prev->lastWanted( mat ); 178 } 179 180 JoinType join; multiple()181 int multiple() { 182 return ( join != SIMPLE ); 183 } 184 EntList * prev, * next; 185 186 protected: 187 MatchType viable; 188 // How does this EntList match the complex type. Used especially if Ent- 189 // List's parent is an OrList or AndOrList to record if this child is an 190 // acceptable choice or not. For an AndOr, viable children are accepted 191 // right away. For Or, only one is accepted, but we keep track of the 192 // other possible solutions in case we'll want to try them. 193 int level; // How many levels deep are we (main use for printing). 194 }; 195 196 class SimpleList : public EntList { 197 friend class ComplexList; 198 friend ostream & operator<< ( ostream &, SimpleList & ); 199 200 public: SimpleList(const char * n)201 SimpleList( const char * n ) : EntList( SIMPLE ), I_marked( NOMARK ) { 202 strcpy( name, n ); 203 } ~SimpleList()204 ~SimpleList() {} 205 int operator== ( const char * nm ) { 206 return ( strcmp( name, nm ) == 0 ); 207 } Name()208 const char * Name() { 209 return name; 210 } contains(const char * nm)211 int contains( const char * nm ) { 212 return *this == nm; 213 } hit(const char * nm)214 int hit( const char * nm ) { 215 return *this == nm; 216 } 217 int isDependent( const char * ); 218 MatchType matchNonORs( EntNode * ); 219 int acceptChoice( EntNode * ); 220 void unmarkAll( EntNode * ); reset()221 void reset() { 222 viable = UNKNOWN; 223 I_marked = NOMARK; 224 } 225 void write( ostream & ); 226 227 private: 228 char name[BUFSIZ]; // Name of entity we correspond to. 229 MarkType I_marked; // Did I mark, and with what type of mark. 230 }; 231 232 class MultList : public EntList { 233 // Supports concepts and functionality common to all the compound list 234 // types, especially AND and ANDOR. 235 236 friend class ComplexList; 237 friend class ComplexCollect; 238 friend ostream & operator<< ( ostream &, MultList & ); 239 240 public: MultList(JoinType j)241 MultList( JoinType j ) : EntList( j ), numchildren( 0 ), childList( 0 ) {} 242 ~MultList(); 243 void setLevel( int ); 244 int getMaxLevel(); 245 int contains( const char * ); 246 int hit( const char * ); 247 int isDependent( const char * ); 248 void appendList( EntList * ); 249 EntList * copyList( EntList * ); 250 void processSubExp( Expression, Entity, ComplexCollect * ); 251 void addSimpleAndSubs( Entity, ComplexCollect * ); 252 virtual MatchType matchORs( EntNode * ) = 0; 253 virtual MatchType tryNext( EntNode * ); 254 childCount()255 int childCount() { 256 return numchildren; 257 } 258 // EntList *operator[]( int ); 259 EntList * getChild( int ); getLast()260 EntList * getLast() { 261 return ( getChild( numchildren - 1 ) ); 262 } 263 void unmarkAll( EntNode * ); 264 int prevKnown( EntList * ); 265 void reset(); 266 void write( ostream & ); 267 268 protected: 269 int numchildren; 270 EntList * childList; 271 // Points to a list of "children" of this EntList. E.g., if join = 272 // AND, it would point to a list of the entity types we are AND'ing. 273 // The children may be SIMPLE EntLists (contain entity names) or may 274 // themselves be And-, Or-, or AndOrLists. 275 }; 276 277 class JoinList : public MultList { 278 // A specialized MultList, super for subtypes AndOrList and AndList, or 279 // ones which join their multiple children. 280 public: JoinList(JoinType j)281 JoinList( JoinType j ) : MultList( j ) {} ~JoinList()282 ~JoinList() {} 283 void setViableVal( EntNode * ); 284 int acceptChoice( EntNode * ); 285 }; 286 287 class AndOrList : public JoinList { 288 friend class ComplexList; 289 290 public: AndOrList()291 AndOrList() : JoinList( ANDOR ) {} ~AndOrList()292 ~AndOrList() {} 293 MatchType matchNonORs( EntNode * ); 294 MatchType matchORs( EntNode * ); 295 }; 296 297 class AndList : public JoinList { 298 friend class MultList; 299 friend class ComplexList; 300 friend ostream & operator<< ( ostream &, ComplexList & ); 301 302 public: AndList()303 AndList() : JoinList( AND ), supertype( 0 ) {} ~AndList()304 ~AndList() {} 305 int isDependent( const char * ); 306 MatchType matchNonORs( EntNode * ); 307 MatchType matchORs( EntNode * ); 308 309 private: 310 int supertype; // do I represent a supertype? 311 }; 312 313 class OrList : public MultList { 314 public: OrList()315 OrList() : MultList( OR ), choice( -1 ), choice1( -2 ), choiceCount( 0 ) {} ~OrList()316 ~OrList() {} 317 int hit( const char * ); 318 MatchType matchORs( EntNode * ); 319 MatchType tryNext( EntNode * ); 320 void unmarkAll( EntNode * ); 321 int acceptChoice( EntNode * ); acceptNextChoice(EntNode * ents)322 int acceptNextChoice( EntNode * ents ) { 323 choice++; 324 return ( acceptChoice( ents ) ); 325 } reset()326 void reset() { 327 choice = -1; 328 choice1 = -2; 329 choiceCount = 0; 330 MultList::reset(); 331 } 332 333 private: 334 int choice, choice1, choiceCount; 335 // Which choice of our childList did we select from this OrList; what's 336 // the first viable choice; and how many choices are there entirely. 337 }; 338 339 class ComplexList { 340 // Contains the entire list of EntLists which describe the set of 341 // instantiable complex entities defined by an EXPRESS expression. 342 343 friend class MultList; 344 friend class ComplexCollect; 345 friend ostream & operator<< ( ostream &, ComplexList & ); 346 347 public: 348 ComplexList( AndList * alist = NULL ) : list( 0 ), head( alist ), next( 0 ), 349 abstract( 0 ), dependent( 0 ), 350 multSupers( 0 ) {} 351 ComplexList( Entity, ComplexCollect * ); 352 ~ComplexList(); 353 void buildList(); 354 void remove(); 355 int operator< ( ComplexList & c ) { 356 return ( strcmp( supertype(), c.supertype() ) < 0 ); 357 } 358 int operator< ( char * name ) { 359 return ( strcmp( supertype(), name ) < 0 ); 360 } 361 int operator== ( char * name ) { 362 return ( strcmp( supertype(), name ) == 0 ); 363 } supertype()364 const char * supertype() { 365 return ( ( SimpleList * )head->childList )->name; 366 } 367 // Based on knowledge that ComplexList always created by ANDing supertype 368 // with subtypes. 369 int toplevel( const char * ); 370 int contains( EntNode * ); 371 int matches( EntNode * ); 372 int isDependent( const char * ); 373 374 EntNode * list; // List of all entities contained in this complex type, 375 // regardless of how. (Used as a quick way of determining 376 // if this List *may* contain a certain complex type.) 377 AndList * head; 378 ComplexList * next; Dependent()379 int Dependent() { 380 return dependent; 381 } 382 void write( ostream & ); getEntListMaxLevel()383 int getEntListMaxLevel() { 384 return head->getMaxLevel(); 385 } 386 387 private: 388 void addSuper( Entity ); 389 void addSubExp( Expression ); 390 void addImplicitSubs( Linked_List, ComplexCollect * ); 391 void addChildren( EntList * ); 392 int hitMultNodes( EntNode * ); 393 int abstract; // is our supertype abstract? 394 int dependent; // is our supertype also a subtype of other supertype(s)? 395 int multSupers; // am I a combo-CList created to test a subtype which has 396 int maxlevel; 397 }; // >1 supertypes? 398 399 class ComplexCollect { 400 // The collection of all the ComplexLists defined by the current schema. 401 public: clists(c)402 ComplexCollect( ComplexList * c = NULL ) : clists( c ) { 403 count = ( c ? 1 : 0 ); 404 } 405 ComplexCollect( Express ); ~ComplexCollect()406 ~ComplexCollect() { 407 delete clists; 408 } 409 void insert( ComplexList * ); 410 void remove( ComplexList * ); 411 // Remove this list but don't delete its hierarchy structure, because 412 // it's used elsewhere. 413 ComplexList * find( char * ); 414 int supports( EntNode * ); externMapping(const char * ent)415 bool externMapping( const char * ent ) { 416 return ( clists ? clists->isDependent( ent ) : 0 ); 417 } 418 // One of our clists shows that ent will have to be instantiated 419 // using external mapping (see Part 21, sect 11.2.5.1). 420 void write( const char * ); 421 422 ComplexList * clists; 423 424 private: 425 int count; // # of clist children 426 }; 427 428 // Standalone function which can be used to print out the complex info in an 429 // express file (prints out CCollect, CList & EntList instant. statements): 430 void print_complex( ComplexCollect &, const char * ); 431 432 #endif 433