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