1 /**********************************************************
2 * Version $Id$
3 *********************************************************/
4
5 //#include <..\stdafx.h>
6
7 #include "bedingung.h"
8 #include "pars_all.h"
9
10
11 using namespace std;
12
13
BBBool()14 BBBool::BBBool()
15 {
16 type = Nothing;
17 memset(&BoolVar1, 0, sizeof(T_BoolVar));
18 memset(&BoolVar2, 0, sizeof(T_BoolVar));
19 }
20
~BBBool()21 BBBool::~BBBool()
22 {
23 if (type == Nothing)
24 return;
25 switch (type)
26 {
27 case IFVar:
28 if (BoolVar1.IF != NULL)
29 delete BoolVar1.IF;
30 if (BoolVar2.IF != NULL)
31 delete BoolVar2.IF;
32 break;
33 case PVar:
34 case MVar:
35 if (BoolVar1.MP != NULL)
36 delete BoolVar1.MP;
37 if (BoolVar2.MP != NULL)
38 delete BoolVar2.MP;
39 break;
40 }
41 memset(&BoolVar1, 0, sizeof(T_BoolVar));
42 memset(&BoolVar2, 0, sizeof(T_BoolVar));
43 }
44
BBBedingung()45 BBBedingung::BBBedingung()
46 {
47 type = Nothing;
48 memset(&BedingungVar, 0, sizeof(T_BedingungVar));
49 }
50
~BBBedingung()51 BBBedingung::~BBBedingung()
52 {
53 if (type == Nothing)
54 return;
55 switch (type)
56 {
57 case Bool:
58 if (BedingungVar.BoolVar.b != NULL)
59 delete BedingungVar.BoolVar.b;
60 break;
61 case Und:
62 case Oder:
63 case XOder:
64 if (BedingungVar.BoolBiOp.b1 != NULL)
65 delete BedingungVar.BoolBiOp.b1;
66 if (BedingungVar.BoolBiOp.b2 != NULL)
67 delete BedingungVar.BoolBiOp.b2;
68 break;
69 case Not:
70 if (BedingungVar.BoolUniOp.b != NULL)
71 delete BedingungVar.BoolUniOp.b;
72 break;
73 }
74 memset(&BedingungVar, 0, sizeof(T_BedingungVar));
75 }
76
BBIf()77 BBIf::BBIf()
78 {
79 b = 0;
80 isElse = false;
81 }
82
~BBIf()83 BBIf::~BBIf()
84 {
85 if (b != NULL)
86 delete b;
87 DeleteAnweisungList(z);
88 DeleteAnweisungList(zelse);
89 b = 0;
90 }
91
getFirstTokenKlammer(const string & statement,int & posvor,int & posnach,string & token)92 bool getFirstTokenKlammer(const string& statement, int& posvor, int& posnach, string& token)
93 {
94 if (statement.empty())
95 return false;
96
97 int klammer_ebene = 0;
98 for (int i=0; i<statement.size()-1; i++)
99 {
100 if (statement[i] == '(')
101 klammer_ebene++;
102 if (statement[i] == ')')
103 klammer_ebene--;
104 if (klammer_ebene == 0 && i != statement.size() -1 && i != 0)
105 {
106 bool gefunden = false;
107 if (statement[i] == '&' && statement[i+1] == '&')
108 {
109 token = "&&";
110 gefunden = true;
111 }
112 else if (statement[i] == '|' && statement[i+1] == '|')
113 {
114 token = "||";
115 gefunden = true;
116 }
117 else if (statement[i] == '^' && statement[i+1] == '^')
118 {
119 token = "^^";
120 gefunden = true;
121 }
122 if (gefunden)
123 {
124 posvor = i;
125 posnach = i+2;
126
127 return true;
128 }
129
130 /*
131 int p = i+1;
132 if (!getNextToken(statement, p, token))
133 return false;
134
135 posvor = i+1;
136 posnach = p;
137 return true;
138 */
139 }
140 }
141 return false;
142 }
143
deleteKlammern(string & s)144 void deleteKlammern(string& s)
145 {
146 // Klammern ( .. ) entfernen
147 if (s.size() < 2)
148 return;
149 s.erase(s.end()-1);
150 s.erase(s.begin());
151 }
152
isBoolBiOperator(const string & s,string & links,string & rechts,BBBedingung::T_BedingungType & t)153 bool isBoolBiOperator(const string& s, string& links, string& rechts, BBBedingung::T_BedingungType& t)
154 {
155 // in Klammer-Ebene 0 auf Strings suchen
156 int pos = 0, posvor, posnach;
157 string token;
158
159 if (!getFirstTokenKlammer(s, posvor, posnach, token))
160 return false;
161 if (token == "&&")
162 {
163 links = s.substr(0, posvor);
164 rechts = s.substr(posnach);
165 trim(links);
166 trim(rechts);
167 // deleteKlammern(links);
168 // deleteKlammern(rechts);
169 t = BBBedingung::Und;
170 return true;
171 }
172 else if (token == "||")
173 {
174 links = s.substr(0, posvor);
175 rechts = s.substr(posnach);
176 trim(links);
177 trim(rechts);
178 // deleteKlammern(links);
179 // deleteKlammern(rechts);
180 t = BBBedingung::Oder;
181 return true;
182
183 }
184 else if (token == "^^")
185 {
186 links = s.substr(0, posvor);
187 rechts = s.substr(posnach);
188 trim(links);
189 trim(rechts);
190 // deleteKlammern(links);
191 // deleteKlammern(rechts);
192 t = BBBedingung::XOder;
193 return true;
194 }
195 return false;
196 }
197
isBoolUniOperator(const string & s,string & rechts)198 bool isBoolUniOperator(const string& s, string& rechts)
199 {
200 string t;
201 int pos = 0;
202 if (!getNextToken(s, pos, t))
203 return false;
204 if (t != "not")
205 return false;
206 rechts = s.substr(pos);
207 return true;
208 }
209
210
isBool(const string & s,BBBool * & b)211 bool isBool(const string& s, BBBool * &b)
212 {
213
214 // ausdruck1 == != < > <= >= ausdruck2
215 //
216 string links, rechts;
217 BBBool::T_booloperator t; //{ Gleich, Ungleich, Kleiner, Groesser, KleinerG, GroesserG} BoolOp;
218
219 int pos, pos1, pos2;
220 if ((pos = s.find("==")) > 0)
221 {
222 t = BBBool::Gleich;
223 pos2 = pos+1;
224 }
225 else if ((pos = s.find("!=")) > 0)
226 {
227 t = BBBool::Ungleich;
228 pos2 = pos+1;
229 }
230 else if ((pos = s.find(">=")) > 0)
231 {
232 t = BBBool::GroesserG;
233 pos2 = pos+1;
234 }
235 else if ((pos = s.find("<=")) > 0)
236 {
237 t = BBBool::KleinerG;
238 pos2 = pos+1;
239 }
240 else if ((pos = s.find(">")) > 0)
241 {
242 t = BBBool::Groesser;
243 pos2 = pos;
244 }
245 else if ((pos = s.find("<")) > 0)
246 {
247 t = BBBool::Kleiner;
248 pos2 = pos;
249 }
250 else
251 return false;
252
253
254 pos1 = pos-1;
255 bool found = true; // bei Fehler immer return false
256 // Auf IntegerFloat pruefen
257 BBBaumInteger *k = NULL;
258 try
259 {
260 pars_integer_float(s.substr(0, pos1+1), k, false);
261 }
262 catch (BBFehlerException)
263 {
264 found = false;
265 }
266 if (found)
267 {
268 b = new BBBool;
269 b->type = BBBool::IFVar;
270 b->BoolOp = t;
271 string links, rechts;
272 links = s.substr(0, pos1+1);
273 rechts = s.substr(pos2+1);
274 try
275 {
276 // erste Variable
277 pars_integer_float(links, b->BoolVar1.IF);
278 pars_integer_float(rechts, b->BoolVar2.IF);
279 }
280 catch (BBFehlerException)
281 {
282 delete b;
283 b = 0;
284 return false;
285 }
286 return true;
287 }
288 else
289 {
290 // Matrix oder Point
291
292 found = true;
293 BBBool::T_BoolType BType;
294 // Auf Matrix pruefen
295 BBBaumMatrixPoint *k = NULL;
296 BType = BBBool::MVar;
297 try
298 {
299 pars_matrix_point(s.substr(0, pos1+1), k, true, false);
300 }
301 catch (BBFehlerException)
302 {
303 found = false;
304 }
305 if (!found)
306 {
307 found = true;
308 // Auf Point pruefen
309 BType = BBBool::PVar;
310 try
311 {
312 pars_matrix_point(s.substr(0, pos1+1), k, false, false);
313 }
314 catch (BBFehlerException)
315 {
316 found = false;
317 }
318 }
319 if (!found)
320 return false;
321
322 // Matrix oder Point gefunden
323 b = new BBBool;
324 b->type = BType;
325 b->BoolOp = t;
326 string links, rechts;
327 links = s.substr(0, pos1+1);
328 rechts = s.substr(pos2+1);
329 try
330 {
331 pars_matrix_point(links, b->BoolVar1.MP, BType == BBBool::MVar);
332 pars_matrix_point(rechts, b->BoolVar2.MP, BType == BBBool::MVar);
333 }
334 catch (BBFehlerException)
335 {
336 delete b;
337 b = 0;
338 return false;
339 }
340 return true;
341 }
342 }
343
isBedingung(const std::string & statement,BBBedingung * & bed)344 bool isBedingung(const std::string& statement, BBBedingung * &bed)
345 {
346 string s(statement);
347 string rechts;
348 string links;
349 BBBedingung::T_BedingungType t;
350 BBBool *b;
351
352 // zuerst uni-, dann bidirektionale Operatoren pr�fen
353 trim(s);
354 if (isKlammer(s))
355 {
356 string ss = s;
357 ss.erase(ss.begin());
358 ss.erase(ss.end()-1);
359 return isBedingung(ss, bed);
360 }
361 else if (isBoolUniOperator(s, rechts))
362 {
363 bed = new BBBedingung;
364 bed->type = BBBedingung::Not;
365 int ret = isBedingung(rechts, bed->BedingungVar.BoolUniOp.b);
366 if (!ret)
367 {
368 delete bed;
369 bed = 0;
370 }
371 return (ret!=0);
372 }
373 else if (isBoolBiOperator(s, links, rechts, t))
374 {
375 bed = new BBBedingung;
376 bed->type = t;
377 bool ret1 = isBedingung(links, bed->BedingungVar.BoolBiOp.b2);
378 if (ret1)
379 {
380 int ret2 = isBedingung(rechts, bed->BedingungVar.BoolBiOp.b1);
381 if (ret2)
382 return true;
383 }
384 delete bed;
385 bed = 0;
386 return false;
387 }
388 else if (isBool(s, b))
389 {
390 bed = new BBBedingung;
391 bed->type = BBBedingung::Bool;
392 bed->BedingungVar.BoolVar.b = b;
393 return true;
394 }
395 else
396 return false;
397 }
398
getNextKlammerString(const string & s,int & pos)399 bool getNextKlammerString(const string& s, int& pos)
400 // liefert den String zwischen der ersten Klammer ( und der
401 // zugehoerigen Klammer ).
402 // z.B. ((hallo(1)) d) liefert (hallo(1)) d
403
404 {
405 if (pos >= s.size())
406 return false;
407 if (s[pos] != '(')
408 return false;
409
410 int klammer_ebene = 1;
411 for (int i=pos+1; i<s.size(); i++)
412 {
413 if (s[i] == '(')
414 klammer_ebene++;
415 if (s[i] == ')')
416 klammer_ebene--;
417 if (klammer_ebene == 0)
418 {
419 pos = i;
420 return true;
421 }
422 }
423 return false;
424 }
425
isIf(const std::string & statement,int & pos,BBIf * & i,string & anweisungen,string & anweisungen_else)426 bool isIf(const std::string& statement, int& pos, BBIf *& i, string& anweisungen, string& anweisungen_else)
427 {
428 // pos wird auf { gesetzt
429 //
430 //
431 // Syntax: if (bedingung) { anweisungen }
432 // bedingung: bool / (bool && || ^^ ! bool)
433 // bool: 1.) (IF/IF P/P M/M) == != < >
434
435 string s(statement.substr(pos));
436 int pos0;
437 pos0 = s.find_first_not_of(" \t\n");
438 if (pos0 < 0)
439 return false;
440 s.erase(0, pos0);
441 if (s.size() < 2)
442 return false;
443 // if
444 if (s[0] != 'i' || s[1] != 'f')
445 return false;
446 s.erase(s.begin(), s.begin()+2);
447
448 // Bedingung herausfinden
449 // passende Klammern suchen
450 int pos1;
451 pos1 = s.find_first_not_of(" \t\n");
452 if (pos1 < 0)
453 return false;
454 int pos2 = pos1;
455 if (!getNextKlammerString(s, pos2))
456 return false;
457 string bedstring;
458 bedstring = s.substr(pos1, pos2-pos1+1);
459 BBBedingung * bed;
460 if (isBedingung(bedstring, bed))
461 {
462 i = new BBIf;
463 i->b = bed;
464 int p = pos2+1; // Klammer ) wegnehmen
465 // Klammer { finden
466 char c;
467 getNextChar(s, p, c);
468 if (c != '{')
469 {
470 delete i;
471 i = 0;
472 return false;
473 }
474 int p2 = p;
475 if (!getStringBetweenKlammer(s, p2))
476 {
477 delete i;
478 i = 0;
479 return false;
480 }
481 anweisungen = s.substr(p, p2-p);
482 pos += pos0 + p +2; // pos0 sind blanks, p ist ein hinter { und 2 kommt vom if
483 pos += anweisungen.size();
484 // hier den Else-Zweig abfragen
485 i->isElse = false;
486
487 int p3 = p2+1;
488 string selse;
489 if (!getNextToken(s, p3, selse))
490 return true;
491 if (selse != "else")
492 return true;
493
494 getNextChar(s, p3, c);
495 if (c != '{')
496 {
497 delete i;
498 i = 0;
499 return false;
500 }
501 p = p3;
502 if (!getStringBetweenKlammer(s, p))
503 {
504 delete i;
505 i = 0;
506 return false;
507 }
508 anweisungen_else = s.substr(p3, p-p3);
509 pos += p-p2;
510 i->isElse = true;
511 return true;
512 }
513 return false;
514 }
515