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