1 /**********************************************************
2  * Version $Id$
3  *********************************************************/
4 
5 //#include "..\stdafx.h"
6 #include <iostream>
7 
8 #include <vector>
9 #include <functional>
10 #include "ausdruck.h"
11 #include "funktion.h"
12 
13 
14 
15 using namespace std;
16 
17 
18 class compare_BB_Funktion : public greater<BBFunktion *>
19 {
20 public:
operator ()(const BBFunktion * & x,const BBFunktion * & y) const21     bool operator()(const BBFunktion * &x, const BBFunktion * &y) const
22 	{
23 		return x->name < y->name;
24 	};
25 };
26 
BBBaumInteger()27 BBBaumInteger::BBBaumInteger()
28 {
29 	typ = NoOp;
30 	memset(&k, 0, sizeof(BBKnoten));
31 }
32 
~BBBaumInteger()33 BBBaumInteger::~BBBaumInteger()
34 {
35 	if (typ == NoOp)
36 		return;
37 	switch(typ)
38 	{
39 	case BIOperator:
40 		if (k.BiOperator.links != NULL)
41 			delete k.BiOperator.links;
42 		if (k.BiOperator.rechts != NULL)
43 			delete k.BiOperator.rechts;
44 		break;
45 	case UniOperator:
46 		if (k.UniOperator.rechts != NULL)
47 			delete k.UniOperator.rechts;
48 		break;
49 	case MIndex:
50 		if (k.MatrixIndex.P != NULL)
51 			delete k.MatrixIndex.P;
52 		break;
53 	case Funktion:
54 		if (k.func != NULL)
55 			delete k.func;
56 		break;
57 	case IZahl:
58 	case FZahl:
59 	case IVar:
60 	case FVar:
61 		break;
62 	}
63 	memset(&k, 0, sizeof(BBKnoten));
64 }
65 
BBBaumMatrixPoint()66 BBBaumMatrixPoint::BBBaumMatrixPoint() : typ(NoOp) , isMatrix(true)
67 {
68 	memset(&k, 0, sizeof(BBKnoten));
69 }
70 
~BBBaumMatrixPoint()71 BBBaumMatrixPoint::~BBBaumMatrixPoint()
72 {
73 	if (typ == NoOp)
74 		return;
75 	switch(typ)
76 	{
77 	case BIOperator:
78 		if (k.BiOperator.links != NULL)
79 			delete k.BiOperator.links;
80 		if (k.BiOperator.rechts != NULL)
81 			delete k.BiOperator.rechts;
82 		break;
83 	case UniOperator:
84 		if (k.UniOperator.rechts != NULL)
85 			delete k.UniOperator.rechts;
86 		break;
87 	case IFAusdruck:
88 		if (k.IntFloatAusdruck.b != NULL)
89 			delete k.IntFloatAusdruck.b;
90 		break;
91 	case MVar:
92 	case PVar:
93 		break;
94 	}
95 	memset(&k, 0, sizeof(BBKnoten));
96 }
97 
getFirstCharKlammer(const string & statement,const string & cmp,char & c,int & pos)98 bool getFirstCharKlammer(const string& statement, const string& cmp, char& c, int& pos)
99 {
100 	if (statement.empty())
101 		return false;
102 
103 	int klammer_ebene = 0, klammerE_ebene = 0;
104 	for (int i=0; i<statement.size()-1; i++)
105 	{
106 		if (statement[i] == '(')
107 			klammer_ebene++;
108 		if (statement[i] == ')')
109 			klammer_ebene--;
110 		if (statement[i] == '[')
111 			klammerE_ebene++;
112 		if (statement[i] == ']')
113 			klammerE_ebene--;
114 		if (klammer_ebene == 0 && klammerE_ebene == 0 && i != statement.size() -1 && i != 0)
115 		{
116 
117 			//int p = cmp.find_first_of(statement[i]);
118 			//if (cmp.find_first_of(statement[i]) >= 0)
119 			int j;
120 			for (j=0; j<cmp.size(); j++)
121 				if (cmp[j] == statement[i])
122 					break;
123 			if (j < cmp.size())
124 			{
125 				c = statement[i];
126 				pos = i;
127 				return true;
128 			}
129 		}
130 	}
131 	return false;
132 }
133 
getLastCharKlammer(const string & statement,const string & cmp,char & c,int & pos)134 bool getLastCharKlammer(const string& statement, const string& cmp, char& c, int& pos)
135 {
136 	if (statement.empty())
137 		return false;
138 
139 	int char_found = -1;
140 	int klammer_ebene = 0, klammerE_ebene = 0;
141 	for (int i=0; i<statement.size()-1; i++)
142 	{
143 		if (statement[i] == '(')
144 			klammer_ebene++;
145 		if (statement[i] == ')')
146 			klammer_ebene--;
147 		if (statement[i] == '[')
148 			klammerE_ebene++;
149 		if (statement[i] == ']')
150 			klammerE_ebene--;
151 		if (klammer_ebene == 0 && klammerE_ebene == 0 && i != statement.size() -1 && i != 0)
152 		{
153 			int j;
154 			for (j=0; j<cmp.size(); j++)
155 				if (cmp[j] == statement[i])
156 					char_found = i;
157 		}
158 	}
159 	if (char_found > 0)
160 	{
161 		c = statement[char_found];
162 		pos = char_found;
163 		return true;
164 	}
165 	return false;
166 }
167 
isKlammer(const string & statement)168 bool isKlammer(const string& statement)
169 {
170 	// klammer-Level z�hlen
171 	if (statement.empty())
172 		return false;
173 
174 	if (statement[0] != '(' || statement[statement.size()-1] != ')')
175 		return false;
176 	int klammer_ebene = 0;
177 	for (int i=0; i<statement.size()-1; i++)
178 	{
179 		if (statement[i] == '(')
180 			klammer_ebene++;
181 		if (statement[i] == ')')
182 			klammer_ebene--;
183 		if (klammer_ebene == 0 && i != statement.size() -1)
184 			return false;
185 	}
186 	return true;
187 }
188 
189 //++++++++++++++ Integer/ Float ++++++++++++++++++++++++++
190 
isBiOperator(const string & statement,char & c,int & pos)191 bool isBiOperator(const string& statement, char& c, int& pos)
192 {
193 	// Klammern z�hlen, da nur zwischen Klammer-Level NULL
194 	// ein Operator stehen darf
195 
196 	// den Operator mit der niedrigsten Priorit�t zuerst ausf�hren, da er
197 	// in der Baum-Struktur "oben" stehen mu� !
198 	if (getFirstCharKlammer(statement, "+", c, pos))
199 		return true;
200 	if (getLastCharKlammer(statement, "-", c, pos))
201 		return true;
202 	if (getFirstCharKlammer(statement, "*", c, pos))
203 		return true;
204 	if (getLastCharKlammer(statement, "/", c, pos))
205 		return true;
206 	if (getFirstCharKlammer(statement, "^", c, pos))
207 		return true;
208 //-->
209 	if (getFirstCharKlammer(statement, "%", c, pos))
210 		return true;
211 //<--
212 	return false;
213 }
214 
isUniOperator(const string & statement,char & c)215 bool isUniOperator(const string& statement, char& c)
216 {
217 	c = statement[0];
218 	return (c == '-' || c == '+');
219 }
220 
isMatrixIndex(const string & statement,BBMatrix * & bm,BBBaumMatrixPoint * & bp,bool getMem)221 bool isMatrixIndex(const string& statement, BBMatrix *& bm, BBBaumMatrixPoint *& bp, bool getMem /* = true */)
222 {
223 	// wenn X[p] enth�lt und X = Matrix und p = Point
224 	if (statement.empty())
225 		return false;
226 	string s(statement);
227 	int pos1, pos2;
228 	pos1 = s.find('[');
229 	if (pos1 > 0)
230 	{
231 		pos2 = s.find(']');
232 		if ( pos2 > pos1 && pos2 == s.size()-1 )
233 		{
234 			// ersten Teil
235 			string m, p;
236 			m = s.substr(0, pos1);
237 			p = s.substr(pos1+1, pos2-pos1-1);
238 			BBTyp *tm;
239 			BBBaumMatrixPoint *bmp;
240 			if (isMVar(m, tm))
241 			{
242 				try
243 				{
244 					// erst Testen
245 					pars_matrix_point(p, bmp, false, false);
246 				}
247 				catch (BBFehlerException)
248 				{
249 					return false;
250 				}
251 				if (!getMem) // falls nichts allokieren -> test erfolgreich
252 					return true;
253 				try
254 				{
255 					// dann allokieren
256 					pars_matrix_point(p, bmp, false);
257 				}
258 				catch (BBFehlerException)
259 				{
260 					return false;
261 				}
262 
263 				bm = (BBMatrix *) tm;
264 				bp = bmp;
265 				return true;
266 			}
267 
268 /*			if (isMVar(m, tm) && isPVar(p, tp))
269 			{
270 				bm = (BBMatrix *) tm;
271 				bp = (BBPoint *) tp;
272 				return true;
273 			}
274 			*/
275 		}
276 	}
277 	return false;
278 }
279 
isFZahl(const string & statement)280 bool isFZahl(const string& statement)
281 {
282 	// Format: [+-]d[d][.[d[dd]][e|E +|- d[d]]]
283 	if (statement .size() > 50)
284 		return false;
285 	char buff[100];
286 	double f;
287 	int anz = sscanf(statement.data(), "%f%s", &f, buff);
288 	return  (anz == 1);
289 }
290 
isIZahl(const string & statement)291 bool isIZahl(const string& statement)
292 {
293 	if (statement.empty())
294 		return false;
295 
296 	string s(statement);
297 
298 	// eventuel voranstehenden +-
299 	if (s[0] == '+')
300 		s.erase(s.begin());
301 	else if (s[0] == '-')
302 		s.erase(s.begin());
303 
304 	if (s.empty())
305 		return false;
306 	int p =	s.find_first_not_of("1234567890");
307 	if (p >= 0)
308 		return false;
309 
310 	return true;
311 }
312 
isFVar(const string & statement,BBTyp * & b)313 bool isFVar(const string& statement, BBTyp * & b)
314 {
315 	b = isVar(statement);
316 	if (b == NULL)
317 		return false;
318 	if (b->type == BBTyp::FType)
319 		return true;
320 	return false;
321 }
322 
isIVar(const string & statement,BBTyp * & b)323 bool isIVar(const string& statement, BBTyp * & b)
324 {
325 	b = isVar(statement);
326 	if (b == NULL)
327 		return false;
328 	if (b->type == BBTyp::IType)
329 		return true;
330 	return false;
331 }
332 
isPVar(const string & statement,BBTyp * & b)333 bool isPVar(const string& statement, BBTyp * & b)
334 {
335 	b = isVar(statement);
336 	if (b == NULL)
337 		return false;
338 	if (b->type == BBTyp::PType)
339 		return true;
340 	return false;
341 }
342 
isMVar(const string & statement,BBTyp * & b)343 bool isMVar(const string& statement, BBTyp * & b)
344 {
345 	b = isVar(statement);
346 	if (b == NULL)
347 		return false;
348 	if (b->type == BBTyp::MType)
349 		return true;
350 	return false;
351 }
352 
isFktName(const string & s)353 BBFunktion *isFktName(const string& s)
354 {
355 	if (FunktionList.empty())
356 		return NULL;
357 	T_FunktionList::iterator it;
358 	for (it = FunktionList.begin(); it != FunktionList.end(); it++)
359 	{
360 		if ((*it)->name == s)
361 			return (*it);
362 	}
363 	return NULL;
364 }
365 
getNextFktToken(const string & s,int & pos,string & erg)366 bool getNextFktToken(const string& s, int& pos, string& erg)
367 {
368 	// Syntax xx[,xx[,xx...]]
369 	if (pos >= s.size())
370 		return false;
371 	string ss(s.substr(pos));
372 	int pos1 = ss.find_first_of(',');
373 	if (pos1 >= 0)
374 	{
375 		erg = ss.substr(0, pos1);
376 		pos += pos1;
377 	}
378 	else
379 	{
380 		erg = ss;
381 		pos = s.size();
382 	}
383 	if (erg.empty())
384 		return false;
385 	return true;
386 }
387 
isFunktion(const string & statement,BBFktExe * & fktexe,bool getMem,bool AlleFunktionen)388 bool isFunktion (const string& statement, BBFktExe * & fktexe, bool getMem /* = true */, bool AlleFunktionen /* = true */)
389 {
390 	// Syntax: fktname([arg1[, arg2]])
391 	string s(statement);
392 	int pos1, pos2;
393 	pos1 = s.find_first_of('(');
394 	pos2 = s.find_last_of(')');
395 	if (pos1 <= 0 || pos2 != s.size()-1)
396 		return false;
397 
398 	// Variablen-Name
399 	string sub1, sub2;
400 	sub1 = s.substr(0, pos1);
401 	trim(sub1);
402 	sub2 = s.substr(pos1+1, pos2-pos1-1);
403 	trim(sub2);
404 	if (sub1.empty())
405 		return false;
406 	BBFunktion *fkt = isFktName(sub1);
407 	if (fkt == NULL)
408 		return false;
409 
410 	if (!AlleFunktionen)
411 	{ // nur diejenigen Funktionen mit Return-Typ
412 		if (fkt->ret.typ == BBArgumente::NoOp) // kein Return-Typ
413 			return false;
414 	}
415 	if (sub2.empty()) // keine Argumente
416 	{
417 		if (!fkt->args.empty())
418 			return false;
419 		if (getMem)
420 		{
421 			fktexe = new BBFktExe;
422 			fktexe->args = fkt->args;
423 			fktexe->f = fkt;  // vorher ... = NULL;
424 		}
425 		return true;
426 	}
427 	else
428 	{
429 		// Argumente z�hlen
430 		// 1. Float/Integer lassen sich konvertieren
431 		// 2. Matrix
432 		// 3. Point
433 		if (getMem)
434 		{
435 			fktexe = new BBFktExe;
436 			fktexe->args = fkt->args; // vector kopieren
437 			fktexe->f = fkt;
438 		}
439 		int anz = fkt->args.size();
440 		int possub2 = 0;
441 		for (int i=0; i<anz; i++)
442 		{
443 			// finde Token
444 			string ss;
445 			if (!getNextFktToken(sub2, possub2, ss))
446 				return false;
447 //			BBTyp *bt = isVar(ss);
448 //			if (bt == NULL)
449 //				return false;
450 			if (fkt->args[i].typ == BBArgumente::ITyp ||
451 				fkt->args[i].typ == BBArgumente::FTyp)
452 			{
453 //				if (bt->type != BBTyp::IType ||
454 //					bt->type != BBTyp::FType)
455 //					return false;
456 				try
457 				{
458 					BBBaumInteger *b;
459 					pars_integer_float(ss, b, getMem);
460 					if (getMem)
461 						fktexe->args[i].ArgTyp.IF = b;
462 
463 				}
464 				catch (BBFehlerException)
465 				{
466 					if (getMem)
467 						delete fktexe;
468 					return false;
469 				}
470 			}
471 			else
472 			{
473 /*				if (fkt->args[i].typ == BBArgumente::MTyp &&
474 					bt->type != BBTyp::MType)
475 					return false;
476 				if (fkt->args[i].typ == BBArgumente::PTyp &&
477 					bt->type != BBTyp::PType)
478 					return false;
479 */
480 				try
481 				{
482 					BBBaumMatrixPoint *b;
483 					pars_matrix_point(ss, b, fkt->args[i].typ == BBArgumente::MTyp, getMem);
484 					if (getMem)
485 						fktexe->args[i].ArgTyp.MP = b;
486 				}
487 				catch (BBFehlerException)
488 				{
489 					if (getMem)
490 						delete fktexe;
491 					return false;
492 				}
493 			}
494 			possub2++; // Komma entfernen
495 		}
496 		if (possub2 < sub2.size()) // zuviel Parameter angegeben
497 		{
498 			if (getMem)
499 				delete fktexe;
500 			return false;
501 		}
502 	}
503 	return true;
504 }
505 
506 // ------------- Hauptroutine -------------------
507 
508 static char c;
509 static BBTyp *b;
510 static BBMatrix *bm;
511 static BBPoint *bp;
512 static BBBaumMatrixPoint *bmp;
513 static int pos;
514 static BBFktExe *bfkt;
515 
pars_integer_float(const string & statement,BBBaumInteger * & Knoten,int getMem)516 void pars_integer_float(const string& statement, BBBaumInteger * & Knoten, int getMem /* = true */)
517 {
518 	string s(statement);
519 	trim(s);
520 	if (s.empty())
521 		throw BBFehlerException();
522 	if (isKlammer(s))
523 	{
524 		s.erase(s.begin());
525 		s.erase(s.end()-1);
526 
527 		pars_integer_float(s, Knoten, getMem);
528 	}
529 	else if (isMatrixIndex(s, bm, bmp, getMem!=0))
530 	{
531 		if (getMem)
532 		{
533 			Knoten = new BBBaumInteger;
534 			Knoten->typ = BBBaumInteger::MIndex;
535 			Knoten->k.MatrixIndex.M = bm;
536 			Knoten->k.MatrixIndex.P = bmp;
537 		}
538 	}
539 	else if (isBiOperator(s, c, pos))
540 	{
541 		string links  = s.substr(0, pos);
542 		string rechts = s.substr(pos+1, s.size()-pos-1);
543 		if (links.empty() || rechts.empty())
544 			throw BBFehlerException();
545 
546 		if (getMem)
547 		{
548 			Knoten = new BBBaumInteger;
549 			Knoten->typ = BBBaumInteger::BIOperator;
550 			switch(c)
551 			{
552 			case '+':
553 				Knoten->k.BiOperator.OpTyp = BBBaumInteger::BBKnoten::BBBiOperator::Plus;
554 				break;
555 			case '-':
556 				Knoten->k.BiOperator.OpTyp = BBBaumInteger::BBKnoten::BBBiOperator::Minus;
557 				break;
558 			case '*':
559 				Knoten->k.BiOperator.OpTyp = BBBaumInteger::BBKnoten::BBBiOperator::Mal;
560 				break;
561 			case '/':
562 				Knoten->k.BiOperator.OpTyp = BBBaumInteger::BBKnoten::BBBiOperator::Geteilt;
563 				break;
564 			case '^':
565 				Knoten->k.BiOperator.OpTyp = BBBaumInteger::BBKnoten::BBBiOperator::Hoch;
566 				break;
567 //-->
568 			case '%':
569 				Knoten->k.BiOperator.OpTyp = BBBaumInteger::BBKnoten::BBBiOperator::Modulo;
570 				break;
571 //<--
572 			}
573 			pars_integer_float(links, Knoten->k.BiOperator.links);
574 			pars_integer_float(rechts, Knoten->k.BiOperator.rechts);
575 		}
576 		else
577 		{
578 			pars_integer_float(links, Knoten, getMem);
579 			pars_integer_float(rechts, Knoten, getMem);
580 		}
581 	}
582 	else if (isUniOperator(s, c))
583 	{
584 		s.erase(s.begin());
585 		if (getMem)
586 		{
587 			Knoten = new BBBaumInteger;
588 			Knoten->typ = BBBaumInteger::UniOperator;
589 			Knoten->k.UniOperator.OpTyp = (c == '+' ? BBBaumInteger::BBKnoten::BBUniOperator::Plus : BBBaumInteger::BBKnoten::BBUniOperator::Minus);
590 			pars_integer_float(s, Knoten->k.UniOperator.rechts);
591 		}
592 		else
593 			pars_integer_float(s, Knoten->k.UniOperator.rechts, getMem);
594 
595 	}
596 	else if (isFZahl(s))
597 	{
598 		if (getMem)
599 		{
600 			Knoten = new BBBaumInteger;
601 			Knoten->typ = BBBaumInteger::FZahl;
602 			Knoten->k.FZahl = atof(s.data());
603 		}
604 	}
605 	else if (isIZahl(s))
606 	{
607 		if (getMem)
608 		{
609 			Knoten = new BBBaumInteger;
610 			Knoten->typ = BBBaumInteger::IZahl;
611 			Knoten->k.IZahl = (int)atof(s.data());
612 		}
613 	}
614 
615 	else if (isFVar(s, b))
616 	{
617 		if (getMem)
618 		{
619 			Knoten = new BBBaumInteger;
620 			Knoten->typ = BBBaumInteger::FVar;
621 			Knoten->k.FVar = getVarF(b);
622 		}
623 	}
624 	else if (isIVar(s, b))
625 	{
626 		if (getMem)
627 		{
628 			Knoten = new BBBaumInteger;
629 			Knoten->typ = BBBaumInteger::IVar;
630 			Knoten->k.IVar = getVarI(b);
631 		}
632 	}
633 	else if (isFunktion (s, bfkt, getMem!=0, false)) // nur die Funktionen mit Return-Typ
634 	{
635 		if (getMem)
636 		{
637 			Knoten = new BBBaumInteger;
638 			Knoten->typ = BBBaumInteger::Funktion;
639 			Knoten->k.func = bfkt;
640 		}
641 	}
642 	else
643 		throw BBFehlerException();
644 }
645 
isIntFloatAusdruck(const string & s)646 bool isIntFloatAusdruck(const string& s)
647 {
648 	try
649 	{
650 		BBBaumInteger *knoten = NULL;
651 		pars_integer_float(s, knoten, false);
652 	}
653 	catch (BBFehlerException)
654 	{
655 		return false;
656 	}
657 	return true;
658 }
659 
660 //++++++++++++++ Point ++++++++++++++++++++++++++
661 // Operator p/p + -
662 // Operator p/i i/p p/f f/p * /
663 
664 //++++++++++++++ Matrix ++++++++++++++++++++++++++
665 // Operator M/M + -
666 // Operator M/i i/M M/f f/M * /
667 
pars_matrix_point(const string & statement,BBBaumMatrixPoint * & Knoten,bool matrix,bool getMem)668 void pars_matrix_point(const string& statement, BBBaumMatrixPoint * &Knoten, bool matrix, bool getMem /* = true */)
669 {
670 	string s(statement);
671 	trim(s);
672 	if (s.empty())
673 		throw BBFehlerException();
674 	if (isKlammer(s))
675 	{
676 		s.erase(s.begin());
677 		s.erase(s.end()-1);
678 
679 		pars_matrix_point(s, Knoten, matrix, getMem);
680 	}
681 	else if (isUniOperator(s, c))
682 	{
683 		s.erase(s.begin());
684 		if (getMem)
685 		{
686 			Knoten = new BBBaumMatrixPoint;
687 			Knoten->typ = BBBaumMatrixPoint::UniOperator;
688 			Knoten->k.UniOperator.OpTyp = (c == '+' ? BBBaumMatrixPoint::BBKnoten::BBUniOperator::Plus : BBBaumMatrixPoint::BBKnoten::BBUniOperator::Minus);
689 			Knoten->isMatrix = matrix;
690 			pars_matrix_point(s, Knoten->k.UniOperator.rechts, matrix);
691 		}
692 		else
693 			pars_matrix_point(s, Knoten, matrix, getMem);
694 	}
695 	else if (isBiOperator(s, c, pos))
696 	{
697 		string links  = s.substr(0, pos);
698 		string rechts = s.substr(pos+1, s.size()-pos-1);
699 		if (links.empty() || rechts.empty())
700 			throw BBFehlerException();
701 		if (getMem)
702 		{
703 			Knoten = new BBBaumMatrixPoint;
704 			Knoten->typ = BBBaumMatrixPoint::BIOperator;
705 			Knoten->isMatrix = matrix;
706 			switch(c)
707 			{
708 			case '+':
709 				Knoten->k.BiOperator.OpTyp = BBBaumMatrixPoint::BBKnoten::BBBiOperator::Plus;
710 				break;
711 			case '-':
712 				Knoten->k.BiOperator.OpTyp = BBBaumMatrixPoint::BBKnoten::BBBiOperator::Minus;
713 				break;
714 			case '*':
715 				Knoten->k.BiOperator.OpTyp = BBBaumMatrixPoint::BBKnoten::BBBiOperator::Mal;
716 				break;
717 			case '/':
718 				Knoten->k.BiOperator.OpTyp = BBBaumMatrixPoint::BBKnoten::BBBiOperator::Geteilt;
719 				break;
720 			case '^':
721 				throw BBFehlerException();
722 				break;
723 			case '%':
724 				throw BBFehlerException();
725 				break;
726 			}
727 			pars_matrix_point(links, Knoten->k.BiOperator.links, matrix);
728 			pars_matrix_point(rechts, Knoten->k.BiOperator.rechts, matrix);
729 			if (c == '+' || c == '-')
730 			{
731 				// Operator nur zwischen zwei Points
732 				if (matrix && (	(Knoten->k.BiOperator.rechts)->typ != BBBaumMatrixPoint::MVar ||
733 								(Knoten->k.BiOperator.links )->typ != BBBaumMatrixPoint::MVar ))
734 				{
735 						throw BBFehlerException();
736 				}
737 				if (!matrix && ((Knoten->k.BiOperator.rechts)->typ != BBBaumMatrixPoint::PVar ||
738 								(Knoten->k.BiOperator.links )->typ != BBBaumMatrixPoint::PVar ))
739 				{
740 						throw BBFehlerException();
741 				}
742 			}
743 			if (c == '*' || c == '/')
744 			{
745 				// Operator nur zwischen i/f und p, Reihenfolge egal
746 				int pvar = 0;
747 				int mvar = 0;
748 
749 				if ((Knoten->k.BiOperator.rechts)->typ == BBBaumMatrixPoint::PVar)
750 					pvar++;
751 				if ((Knoten->k.BiOperator.rechts)->typ == BBBaumMatrixPoint::MVar)
752 					mvar++;
753 				if ((Knoten->k.BiOperator.links)->typ == BBBaumMatrixPoint::PVar)
754 					pvar++;
755 				if ((Knoten->k.BiOperator.links)->typ == BBBaumMatrixPoint::MVar)
756 					mvar++;
757 
758 				if (matrix &&  (mvar != 1 || pvar != 0))
759 					throw BBFehlerException();
760 				if (!matrix && (pvar != 1 || mvar != 0))
761 					throw BBFehlerException();
762 			}
763 		}
764 		else
765 		{
766 			pars_matrix_point(links, Knoten, matrix, getMem);
767 			pars_matrix_point(rechts, Knoten, matrix, getMem);
768 		}
769 	}
770 	else if (matrix && isMVar(s, b))
771 	{
772 		if (getMem)
773 		{
774 			Knoten = new BBBaumMatrixPoint;
775 			Knoten->typ = BBBaumMatrixPoint::MVar;
776 			Knoten->k.M = getVarM(b);
777 			Knoten->isMatrix = matrix;
778 		}
779 	}
780 	else if (!matrix && isPVar(s, b))
781 	{
782 		if (getMem)
783 		{
784 			Knoten = new BBBaumMatrixPoint;
785 			Knoten->typ = BBBaumMatrixPoint::PVar;
786 			Knoten->k.P = getVarP(b);
787 			Knoten->isMatrix = matrix;
788 		}
789 	}
790 	else if (isIntFloatAusdruck(s))
791 	{
792 		if (getMem)
793 		{
794 			Knoten = new BBBaumMatrixPoint;
795 			Knoten->typ = BBBaumMatrixPoint::IFAusdruck;
796 			Knoten->isMatrix = matrix;
797 			pars_integer_float(s, Knoten->k.IntFloatAusdruck.b);
798 		}
799 		else
800 		{
801 			BBBaumInteger *k = NULL;
802 			pars_integer_float(s, k, getMem);
803 		}
804 	}
805 	else
806 		throw BBFehlerException();
807 }
808 
809