1 /*************************************************************************** 2 knoten.h - description 3 ------------------- 4 begin : Sun Jul 1 2001 5 copyright : (C) 2001 by Immi 6 email : cuyo@karimmi.de 7 8 Modified 2002,2005,2006,2008,2009,2011 by the cuyo developers 9 Maintenance modifications 2012 by Bernhard R. Link 10 Maintenance modifications 2012 by the cuyo developers 11 12 ***************************************************************************/ 13 14 /*************************************************************************** 15 * * 16 * This program is free software; you can redistribute it and/or modify * 17 * it under the terms of the GNU General Public License as published by * 18 * the Free Software Foundation; either version 2 of the License, or * 19 * (at your option) any later version. * 20 * * 21 ***************************************************************************/ 22 23 #ifndef KNOTEN_H 24 #define KNOTEN_H 25 26 #include <vector> 27 #include <map> 28 29 #include "version.h" 30 31 #include "fehler.h" 32 33 34 #define type_egal 0 // wird von DatenDatei::getEintragKnoten() benutzt 35 #define type_DefKnoten 1 36 #define type_ListenKnoten 2 37 #define type_DatenKnoten 3 38 39 #define type_EgalDatum 0 // wirft keinen Fehler beim Typecheck 40 #define type_WortDatum 1 41 #define type_ZahlDatum 2 42 #define type_VielfachheitDatum 3 43 44 #define namespace_prozedur 0 45 #define namespace_variable 1 46 47 48 /* Die Tiefen der DefKnoten. */ 49 #define tiefe_global 0 50 #define tiefe_level 1 51 #define tiefe_sorte 2 52 53 54 /* Die Rollen von Argumenten */ 55 #define zahlrolle_einzige 0 56 #define wortrolle_einziges 0 57 58 59 class Code; 60 class DatenKnoten; 61 class Definition; 62 63 64 65 66 /***********************************************************************/ 67 /* Knoten */ 68 69 70 /** Wenn die Level.descr geparst wird, wird das Ergebnis als ein 71 Baum von Knoten gespeichert. F�r den Baum gilt (im Moment) folgendes: 72 - Die Wurzel ist ein DefKnoten. 73 - Kinder von DefKnoten sind DefKnoten oder ListenKnoten. 74 - Kinder von ListenKnoten sind DatenKnoten. 75 */ 76 class Knoten { 77 78 79 /** Datei, in der dieser Knoten definiert wurde (f�r Fehlermeldungen) */ 80 Str mDateiName; 81 /** Zeilen-Nr, in der dieser Knoten definiert wurde (f�r Fehlermeldungen) */ 82 int mZeilenNr; 83 84 public: Knoten(Str datna,int znr)85 Knoten(Str datna, int znr): mDateiName(datna), mZeilenNr(znr) {} 86 ~Knoten()87 virtual ~Knoten() {} 88 89 virtual int type() const = 0; 90 91 virtual Str toString() const = 0; 92 93 /** Liefert einen String zur�ck, der angibt, wo dieser Code 94 definiert wurde (f�r Fehlermeldungen) */ 95 Str getDefString() const; 96 }; 97 98 99 100 101 102 103 /***********************************************************************/ 104 /* DefKnoten */ 105 106 107 108 //typedef std::map<Str, Knoten *> tKnotenMap; 109 110 typedef VersionMap<Knoten> tKnotenMap; 111 typedef VersionMap<Definition> tCodeSpeicher; 112 113 114 115 /** Knoten der Form 116 bla=... 117 blub=... 118 << 119 bild=... 120 gras=... 121 >> 122 Das was rechts von bla und blub steht, sind Kinder: 123 Entweder DefKnoten oder ListenKnoten. 124 Das, was in <<...>> steht, ist Code. (Neu: Code ist auch Knoten.) 125 */ 126 class DefKnoten: public Knoten { 127 128 /** Die Knoten-Kinder dieses Knotens */ 129 tKnotenMap mKinder; 130 131 /** Die Code-"Kinder" dieses Knotens */ 132 tCodeSpeicher mCodeSpeicher[2]; 133 134 /** Wenn man von hier aus im Baum nach oben l�uft der n�chste 135 DefKnoten, den man trifft. (Wird ben�tigt, um auf den 136 CodeSpeicher vom Vater zuzufreifen.) */ 137 DefKnoten * mVater; 138 139 /** 0 bei der Wurzel, 1 bei Kindern der Wurzel (Level-DefKnoten), etc. */ 140 int mTiefe; 141 142 /** Nur f�r den Top-Knoten: 1, wenn schon eine Level-Defintion 143 gespeichert ist. Wenn danach noch Cual-Code kommt, wird eine Warnung 144 ausgeben. 145 3, wenn die Warnung schon ausgegeben wurde. */ 146 int mErstLevelDannCual; 147 148 149 /** Variablen werden intern durchnummeriert. Hier steht die 150 n�chste freie Nummer (bzw. die Anzahl der belegten Nummern). 151 152 Bei Sorten-Defknoten sind diese Variablen nicht von Bedeutung; 153 um die Nummerierung der Sorten-Variablen k�mmert sich auch der 154 Level-DefKnoten. So hat intern jede Sorte alle Variablen. 155 (Die Variablen-Definitionen stehen allerdings trotzdem im 156 Code-Speicher der Sorten, so dass die Sortenvariablen-Namespace 157 getrennt ist. 158 159 �berblick �ber die ganzen Spezial-Variablen-Nummern siehe 160 definition.h, bei class VarDefinition. */ 161 int mVarNrBei; 162 /** Nummer der n�chsten freien Bool-Variable. -1, wenn's grad 163 keine freien Bool-Variablen gibt. */ 164 int mBoolNrBei; 165 166 /** Die Default-Werte der Variablen, nochmal nach Nummer aufgelistet. 167 Wird von den Blops ben�tigt, wenn die Variablen am Anfang 168 initialisiert werden. Allerdings nur Default-Werte von echten 169 Variablen (d. h. von Variablen, die Speicher belegen.) */ 170 std::vector<int> mDefaultWerte; 171 std::vector<int> mDefaultArten; 172 173 /** Wenn dieser Knoten VarDefinitionen f�r Sortennamen verwalten soll, 174 mu� er sich merken, f�r welche Sortenliste er bei welcher Nummer 175 angefangen hat. Das ist mit den jeweiligen bloparten indiziert. */ 176 std::map<Str,int> mSortenAnfaenge; 177 178 179 180 public: 181 182 /** Erzeugt den Top-Knoten. */ 183 DefKnoten(); 184 185 /** Erzeugt einen Unter-Knoten. */ 186 DefKnoten(Str datna, int znr, DefKnoten * vater); 187 188 virtual ~DefKnoten(); 189 type()190 virtual int type() const {return type_DefKnoten;} 191 192 virtual Str toString() const; 193 194 void fuegeEin(const Str & na, const Version & version, Knoten * wert); 195 196 /** L�scht alle Kinder raus, die DefKnoten sind und nicht 197 "Title" hei�en. 198 Wird von LevelDaten::ladLevelSummary() gebraucht. */ 199 void loeschAlleLevel(); 200 enthaelt(Str na)201 bool enthaelt(Str na) {return mKinder.enthaelt(na);} 202 getKind(const Str & na,const Version & version,bool defaultVorhanden)203 Knoten * getKind(const Str & na, const Version & version, 204 bool defaultVorhanden) { 205 return mKinder.Bestapproximierende(na,version,defaultVorhanden); 206 } 207 208 209 /***** Methoden f�r den Codespeicher *****/ 210 211 212 /** Speichert alle vordefinierten Variablen in den 213 Namespace, au�er die pics-Konstanten. Wird vom Constructor 214 des WurzelKnotens aufgerufen. */ 215 void speicherGlobaleVordefinierte(); 216 217 /** Speichert die Pics-Konstanten. (picsliste sollte der pics-Knoten sein.) 218 Wird von fuegeEin(...) aufgerufen, wenn es die pics bekommt. 219 Alternativ auch bei greypic und startpic. 220 Welches davon steht in schluessel */ 221 void speicherPicsConst(const Version & version, Knoten * picsliste, 222 const char* schluessel); 223 224 /** Speichert eine Konstante mit dem Namen, der in nameKnoten steht und 225 dem angegebenen Wert. nameKnoten ist hoffentlich ein ListenKnoten 226 mit genau einem Eintrag. Wird von fuegeEin() aufgerufen, um die 227 Gras-, die Grau- und die nix-Konstante abzuspeichern, wenn es die 228 bekommt. */ 229 void speicherKnotenConst(const Version & version, Knoten * nameKnoten, 230 int wert); 231 232 233 /* Erzeugt eine neue Var-Definition und speichert sie ab. Dabei 234 bekommt sie auch gleich eine Nummer. (Aufzurufen, wenn eine 235 VarDefinition geparst wurde.) def ist der Default-Wert. */ 236 void neueVarDefinition(const Str & na, const Version& version, 237 int def, int defart); 238 239 /* Speichert eine neue Definition - Code oder Variable. Noch unsch�n: 240 Sollte von au�en nur f�r Code aufgerufen werden. Bei Variablen immer 241 neueVarDefinition verwenden! */ 242 void speicherDefinition(int ns, const Str & na, const Version & version, 243 Definition * f); 244 245 /** Liefert eine Code-Definition aus diesem Speicher oder von 246 weiter oben. Throwt bei nichtexistenz. 247 Achtung: Beh�lt den Besitz an der Defintion. */ 248 Definition * getDefinition(int ns, const Str & na, 249 const Version & version, bool defaultVorhanden); 250 251 /** Liefert ein Kind von hier oder von weiter oben. */ 252 Knoten * getVerwandten(const Str & na, const Version & version, 253 bool defaultVorhanden); 254 255 256 257 /***** Variablen-Nummern-Verwaltung *****/ 258 259 260 261 /** Erzeugt eine unbenannte Variable und liefert die Nummer zur�ck. 262 def wird als default-Wert in mDefaultWerte gespeichert. */ 263 int neueVariable(int def, int defart); 264 265 void neuerDefault(int var, int def, int defart); 266 267 /** Erzeugt eine unbenannte Bool-Variable und liefert 268 die Nummer zur�ck. */ 269 int neueBoolVariable(); 270 271 272 /** Liefert zur�ck, wie viel Speicher f�r Variablen jeder Blop 273 reservieren muss. Nur auf Level-Ebene aufrufen. */ 274 int getDatenLaenge() const; 275 276 /** Liefert den Default-Wert der Variable mit Nummer nr. Es 277 muss aber eine richtige Variable sein, die echten Blop- 278 Speicherplatz verbraucht. (Sonst soll man sich den Default- 279 Wert aus der VarDefinition holen. Das hier ist nur f�r 280 Variablen-Anfangs-Initialisierung.) */ 281 int getDefaultWert(int nr) const; 282 int getDefaultArt(int nr) const; 283 284 285 /** Liest mSortenAnfaenge aus. Throwt bei Nichtexistenz. 286 Nimmt den entsprechenden ld-Eintrag wie "pics" als Index. */ 287 int getSortenAnfang(const Str &) const; 288 289 /** Liefert zurueck, wie viele Sortennummern insgesamt schon 290 von mSortenAnfaenge belegt sind. */ 291 int getSortenAnzahl() const; 292 293 }; 294 295 296 297 /***********************************************************************/ 298 /* ListenKnoten */ 299 300 301 typedef std::vector<Knoten *> tKnotenListe; 302 303 304 /** Knoten der Form bla1, bla2, bla3. Kinder sind DatenKnoten. */ 305 class ListenKnoten: public Knoten { 306 307 tKnotenListe mKinder; 308 309 public: 310 311 ListenKnoten(Str datna, int znr); 312 ~ListenKnoten(); 313 type()314 virtual int type() const {return type_ListenKnoten;} 315 316 virtual Str toString() const; 317 fuegeEin(Knoten * wert)318 void fuegeEin(Knoten * wert) { 319 mKinder.push_back(wert); 320 } 321 322 323 int getVielfachheit(int nr) const; 324 getLaenge()325 int getLaenge() const { 326 return mKinder.size(); 327 } 328 329 /** Dies rechnet Vielfachheiten mit ein */ 330 int getImpliziteLaenge() const; 331 332 /** Dies auch, geht aber nur bis zum physischen Index nr. 333 Somit gilt: 334 335 getKernDatum(i) == getImplizitesDatum(getLaengeBis(i)) 336 */ 337 int getLaengeBis(int nr) const; 338 339 getKind(int nr)340 Knoten * getKind(int nr) { 341 return mKinder[nr]; 342 } 343 344 const DatenKnoten * getDatum(int nr, int solltyp = type_EgalDatum); 345 346 /** Dies wirft Vielfachheiten bei der Ausgabe weg */ 347 const DatenKnoten * getKernDatum(int nr, int solltyp = type_EgalDatum); 348 349 /** Dies rechnet Vielfachheiten beim Index mit ein */ 350 const DatenKnoten * getImplizitesDatum(int nr, int solltyp = type_EgalDatum); 351 352 353 /** Setzt voraus, da� es nur einen Eintrag gibt. Gibt diesen Eintrag. */ 354 const DatenKnoten * getEinzigesDatum(int solltyp = type_EgalDatum); 355 }; 356 357 358 359 360 /***********************************************************************/ 361 /* DatenKnoten */ 362 363 364 /** Enth�lt echte Daten und nicht blo� weitere Knoten */ 365 class DatenKnoten: public Knoten { 366 367 public: 368 DatenKnoten(Str datna,int znr)369 DatenKnoten(Str datna, int znr): Knoten(datna, znr) {} 370 type()371 virtual int type() const {return type_DatenKnoten;} 372 373 virtual int datatype() const = 0; 374 375 /** liefert sich selbst zur�ck, damit man keinen namespace verschwendet */ 376 const DatenKnoten * assert_datatype(int) const; 377 378 virtual int getZahl(int /* rolle */ = zahlrolle_einzige) const { 379 CASSERT(false);} 380 381 virtual Str getWort(int /* rolle */ = wortrolle_einziges) const { 382 CASSERT(false);} 383 384 }; 385 386 387 388 389 /***********************************************************************/ 390 /* WortKnoten */ 391 392 393 /** Ein Wort-Knoten. "bla" oder bla. */ 394 class WortKnoten: public DatenKnoten { 395 Str mWort; 396 397 public: 398 WortKnoten(Str datna,int znr,Str w)399 WortKnoten(Str datna, int znr, Str w): 400 DatenKnoten(datna, znr), mWort(w) {} 401 datatype()402 virtual int datatype() const {return type_WortDatum;} 403 404 virtual Str getWort(int rolle = wortrolle_einziges) const; 405 406 virtual Str toString() const; 407 408 }; 409 410 411 412 413 /***********************************************************************/ 414 /* ZahlKnoten */ 415 416 417 /** Enth�lt eine Zahl */ 418 class ZahlKnoten: public DatenKnoten { 419 int mZahl; 420 421 public: 422 ZahlKnoten(Str datna,int znr,int z)423 ZahlKnoten(Str datna, int znr, int z): 424 DatenKnoten(datna, znr), mZahl(z) {} 425 datatype()426 virtual int datatype() const {return type_ZahlDatum;} 427 428 virtual int getZahl(int rolle = zahlrolle_einzige) const; 429 430 virtual Str toString() const; 431 432 }; 433 434 435 /***********************************************************************/ 436 /* VielfachheitKnoten */ 437 438 439 /** Enth�lt ein Wort und eine Vielfachheit des Wortes. */ 440 class VielfachheitKnoten: public DatenKnoten { 441 Str mWort; 442 int mZahl; 443 WortKnoten mNurDasWort; 444 445 public: 446 VielfachheitKnoten(Str datna,int znr,Str w,int z)447 VielfachheitKnoten(Str datna, int znr, Str w, int z): 448 DatenKnoten(datna, znr), mWort(w), mZahl(z), mNurDasWort(datna,znr,w) {} 449 datatype()450 virtual int datatype() const {return type_VielfachheitDatum;} 451 452 virtual int getZahl(int rolle = zahlrolle_einzige) const; 453 454 virtual Str getWort(int rolle = wortrolle_einziges) const; 455 getNurDasWort()456 virtual const WortKnoten * getNurDasWort() const {return & mNurDasWort;} 457 458 virtual Str toString() const; 459 460 }; 461 462 463 464 465 #endif 466 467