| 
| Autor | Beitrag |  
| Christian S. 
          Beiträge: 20451
 Erhaltene Danke: 2264
 
 Win 10
 C# (VS 2019)
 
 | 
Verfasst: Do 04.12.03 20:02 
 
Hallo!
 Im folgenden  biete ich Euch einen kleinen Math-Parser an. Es war eigentlich ein Projekt nach dem Motto "Wie macht man eigentlich ...", aber das Ergebnis ist gar nicht so übel.
 Die Performance habe ich noch nicht optimiert und es ist gut möglich, dass noch nicht alle Ausdrücke korrekt verarbeitet werden. Aber das Grundkonzept sollte stimmen und besonders als Anschauungsobjekt kann man das Ganze gut verwenden.
 Zur Verwendung:
 (1) Objekt erstellen und dabei den zu parsenden String übergeben (z. B. 2*(3+5))
 (2) über value den Wert abfragen
 												| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 20:
 21:
 22:
 23:
 24:
 25:
 26:
 27:
 28:
 29:
 30:
 31:
 32:
 33:
 34:
 35:
 36:
 37:
 38:
 39:
 40:
 41:
 42:
 43:
 44:
 45:
 46:
 47:
 48:
 49:
 50:
 51:
 52:
 53:
 54:
 55:
 56:
 57:
 58:
 59:
 60:
 61:
 62:
 63:
 64:
 65:
 66:
 67:
 68:
 69:
 70:
 71:
 72:
 73:
 74:
 75:
 76:
 77:
 78:
 79:
 80:
 81:
 82:
 83:
 84:
 85:
 86:
 87:
 88:
 89:
 90:
 91:
 92:
 93:
 94:
 95:
 96:
 97:
 98:
 99:
 100:
 101:
 102:
 103:
 104:
 105:
 106:
 107:
 108:
 109:
 110:
 111:
 112:
 113:
 114:
 115:
 116:
 117:
 118:
 119:
 120:
 121:
 122:
 123:
 124:
 125:
 126:
 127:
 128:
 129:
 130:
 131:
 132:
 133:
 134:
 135:
 136:
 137:
 138:
 139:
 140:
 141:
 142:
 143:
 144:
 145:
 146:
 147:
 148:
 149:
 150:
 151:
 152:
 153:
 154:
 155:
 156:
 157:
 158:
 159:
 160:
 161:
 162:
 163:
 164:
 165:
 166:
 167:
 168:
 169:
 170:
 171:
 172:
 173:
 174:
 175:
 176:
 177:
 178:
 179:
 180:
 181:
 182:
 183:
 184:
 185:
 186:
 187:
 188:
 189:
 190:
 191:
 192:
 193:
 194:
 195:
 196:
 197:
 198:
 199:
 200:
 201:
 202:
 203:
 204:
 205:
 206:
 207:
 208:
 209:
 210:
 211:
 212:
 213:
 214:
 215:
 216:
 217:
 218:
 219:
 220:
 221:
 222:
 223:
 224:
 225:
 226:
 227:
 228:
 229:
 230:
 231:
 232:
 233:
 234:
 235:
 236:
 237:
 238:
 239:
 240:
 241:
 242:
 243:
 244:
 245:
 246:
 247:
 248:
 249:
 250:
 251:
 252:
 253:
 254:
 255:
 256:
 257:
 258:
 259:
 260:
 261:
 262:
 263:
 264:
 265:
 266:
 267:
 268:
 269:
 270:
 271:
 272:
 273:
 274:
 275:
 276:
 277:
 278:
 279:
 280:
 281:
 282:
 283:
 284:
 285:
 286:
 287:
 288:
 289:
 290:
 291:
 292:
 293:
 294:
 295:
 296:
 297:
 298:
 299:
 300:
 301:
 302:
 303:
 304:
 305:
 306:
 307:
 308:
 309:
 310:
 311:
 312:
 313:
 314:
 315:
 316:
 317:
 318:
 319:
 320:
 321:
 322:
 323:
 324:
 325:
 
 | 
 unit csParser;
 
 interface
 
 uses SysUtils, Math;
 
 type
 TParser = class(TObject)
 private
 ops : Array of String;
 ftext : String;
 subs : Array of TParser;
 fsubsCount : Integer;
 procedure getSubs;
 procedure setText(const value : String);
 function onHighestLevel(const operators : Array of String) : Boolean;
 function arrayOr(const operators : Array of String; position : Integer) : Integer;
 public
 constructor create(text : String);
 destructor free;
 function getSubText(i : Integer) : String;
 
 function value : Real;
 
 property subsCount : Integer read fsubsCount;
 property text : String read ftext write setText;
 
 end;
 
 implementation
 
 constructor TParser.create(text : String);
 begin
 SetLength(ops, 8);
 ops[0] := '+';
 ops[1] := '-';
 ops[2] := '*';
 ops[3] := '/';
 ops[4] := '^';
 ops[5] := 'sin';
 ops[6] := 'cos';
 ops[7] := 'exp';
 
 self.ftext := text;
 SetLength(subs, 0);
 fsubsCount :=0;
 getSubs;
 end;
 
 destructor TParser.free;
 VAR i : INTEGER;
 begin
 for i:=0 To fsubscount-1 DO
 subs[i].free;
 
 SetLength(subs,0);
 end;
 
 procedure TParser.setText(const value : String);
 VAR i : INTEGER;
 begin
 self.ftext := value;
 for i:=0 TO fsubscount-1 DO
 subs[i].free;
 
 SetLength(subs, 0);
 fsubsCount := 0;
 getSubs;
 end;
 
 function TParser.arrayOr(const operators : Array of String; position : Integer) : Integer;
 VAR i : INTEGER;
 isTrue : Boolean;
 begin
 isTrue := False;
 for i := Low(operators) to high(operators) do
 begin
 if Copy(ftext, position, Length(operators[i])) = operators[i] then
 begin
 isTrue := true;
 break;
 end;
 end;
 
 if isTrue then result := i else result := -1;
 end;
 
 function TParser.onHighestLevel(const operators : Array of String) : Boolean;
 VAR done : Boolean;
 opIndex,i, bracketcount, last : Integer;
 begin
 done := False;
 last := 0;
 bracketcount := 0;
 i:=1;
 while i <= Length(ftext) do
 begin
 if ftext[i] = '(' then inc(bracketcount);
 if ftext[i] = ')' then dec(bracketcount);
 
 opIndex := arrayOr(operators, i);
 
 if (opIndex >= 0) and (bracketcount = 0) then
 begin
 
 if last < i-1 then
 begin
 SetLength(subs, Length(subs)+2);
 inc(fsubsCount, 2);
 end
 else
 begin
 SetLength(subs, Length(subs)+1);
 inc(fsubsCount, 1);
 end;
 
 if last < i-1 then
 subs[High(subs)-1] := TParser.create(Copy(ftext, last+1, i-last-1));
 
 subs[High(subs)] := TParser.create(Copy(ftext,i, Length(operators[opIndex])));
 
 last := i+Length(operators[opIndex])-1;
 inc(i, Length(operators[opIndex])-1);
 
 done := true;
 end;
 
 if (i = Length(ftext)) and (fsubsCount > 0) then
 begin
 SetLength(subs, Length(subs)+1);
 inc(fsubsCount);
 
 subs[High(subs)] := TParser.create(Copy(ftext, last+1, i-last));
 
 done := true;
 end;
 
 inc(i);
 end;
 result := done;
 end;
 
 procedure TParser.getSubs;
 VAR i, last : Integer;
 bracketcount : Integer;
 done, wasZero : Boolean;
 begin
 bracketcount := 0;
 last := 0;
 done := false;
 
 for i:= 0 to high(ops) do
 if ftext = ops[i] then exit;
 
 while (ftext[1] = '(') and(ftext[Length(ftext)] = ')') do
 begin
 wasZero := False;
 
 for i:=1 TO Length(ftext)-1 DO
 begin
 if ftext[i] = '(' then inc(bracketcount);
 if ftext[i] = ')' then dec(bracketcount);
 
 if bracketcount = 0 then
 begin
 wasZero := True;
 break;
 end;
 end;
 if wasZero = false then
 ftext := Copy(ftext, 2, Length(ftext)-2);
 
 bracketcount := 0;
 end;
 
 done := onHighestLevel(['+','-']);
 if done then exit;
 
 done := onHighestLevel(['*','/']);
 if done then exit;
 
 done := onHighestLevel(['^']);
 if done then exit;
 
 done := onHighestLevel(['sin', 'cos', 'exp']);
 if done then exit;
 end;
 
 function TParser.value : Real;
 VAR i,k,m : INTEGER;
 operation : String;
 valueFirst, opFound : Boolean;
 begin
 if fsubsCount = 0 then
 begin
 result := StrToFloat(ftext);
 exit;
 end;
 
 
 valueFirst := True;
 for m:=0 TO High(ops) do
 if subs[0].ftext = ops[m] then
 begin
 valueFirst := False;
 break;
 end;
 
 if valueFirst then
 begin
 result := subs[0].value ;
 k := 1;
 end else
 begin
 result := 0;
 k := 0;
 
 end;
 
 operation := '';
 
 
 for i := k TO subsCount-1 DO
 begin
 opFound := False;
 for m:=0 to High(ops) do
 if subs[i].ftext = ops[m] then
 begin
 opFound := True;
 break;
 end;
 
 if opFound then
 begin
 operation := subs[i].ftext;
 continue;
 end;
 
 
 if operation = '+' then
 result := result + subs[i].value;
 if operation = '-' then
 result := result - subs[i].value;
 if operation = '*' then
 result := result * subs[i].value;
 if operation = '/' then
 result := result / subs[i].value;
 if operation = '^' then
 result := power(result, subs[i].value);
 if operation = 'sin' then
 result := result + sin(subs[i].value);
 if operation = 'cos' then
 result := result + cos(subs[i].value);
 if operation = 'exp' then
 result := result + exp(subs[i].value);
 
 operation := '';
 end;
 end;
 
 function TParser.getSubText(i : Integer) : String;
 begin
 result := subs[i].ftext;
 end;
 
 end.
 |  Wie gesagt, es ist bei weitem nicht Konzept und über Vorschläge oder direkt geänderte Versioen würde ich mich sehr freuen.
 MfG
 Peter
 //edit: etwas, das noch auf jeden Fall geändet werden muss: ein neuer Operator muss an drei Stellen eingetragen werden, dass ist nicht gut.
 //edit 7.12.03: Titel von "simpler Parser" in "simpler Math-Parser" geändert_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
 
 Zuletzt bearbeitet von Christian S. am Di 12.04.05 23:03, insgesamt 9-mal bearbeitet
 |  |  |  
| Christian S.  
          Beiträge: 20451
 Erhaltene Danke: 2264
 
 Win 10
 C# (VS 2019)
 
 | 
Verfasst: Do 04.12.03 22:57 
 
//EDIT: Ich möchte hier darauf hinweisen, dass der alte Quelltext nicht fehlerhaft war, sodass dieser nötig geworden wäre. Dieser Quellext ist eine Erweiterung des Ersten. Da es im Open Source - Bereich üblich ist, auch alte Versionen zu Verfügung zu stellen, gab es ein neues Posting von mir.
 So, neue Operatoren können jetzt sehr bequem über Priorität, Symbol und Wirkungsfunktion definiert werden.
 												| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 19:
 20:
 21:
 22:
 23:
 24:
 25:
 26:
 27:
 28:
 29:
 30:
 31:
 32:
 33:
 34:
 35:
 36:
 37:
 38:
 39:
 40:
 41:
 42:
 43:
 44:
 45:
 46:
 47:
 48:
 49:
 50:
 51:
 52:
 53:
 54:
 55:
 56:
 57:
 58:
 59:
 60:
 61:
 62:
 63:
 64:
 65:
 66:
 67:
 68:
 69:
 70:
 71:
 72:
 73:
 74:
 75:
 76:
 77:
 78:
 79:
 80:
 81:
 82:
 83:
 84:
 85:
 86:
 87:
 88:
 89:
 90:
 91:
 92:
 93:
 94:
 95:
 96:
 97:
 98:
 99:
 100:
 101:
 102:
 103:
 104:
 105:
 106:
 107:
 108:
 109:
 110:
 111:
 112:
 113:
 114:
 115:
 116:
 117:
 118:
 119:
 120:
 121:
 122:
 123:
 124:
 125:
 126:
 127:
 128:
 129:
 130:
 131:
 132:
 133:
 134:
 135:
 136:
 137:
 138:
 139:
 140:
 141:
 142:
 143:
 144:
 145:
 146:
 147:
 148:
 149:
 150:
 151:
 152:
 153:
 154:
 155:
 156:
 157:
 158:
 159:
 160:
 161:
 162:
 163:
 164:
 165:
 166:
 167:
 168:
 169:
 170:
 171:
 172:
 173:
 174:
 175:
 176:
 177:
 178:
 179:
 180:
 181:
 182:
 183:
 184:
 185:
 186:
 187:
 188:
 189:
 190:
 191:
 192:
 193:
 194:
 195:
 196:
 197:
 198:
 199:
 200:
 201:
 202:
 203:
 204:
 205:
 206:
 207:
 208:
 209:
 210:
 211:
 212:
 213:
 214:
 215:
 216:
 217:
 218:
 219:
 220:
 221:
 222:
 223:
 224:
 225:
 226:
 227:
 228:
 229:
 230:
 231:
 232:
 233:
 234:
 235:
 236:
 237:
 238:
 239:
 240:
 241:
 242:
 243:
 244:
 245:
 246:
 247:
 248:
 249:
 250:
 251:
 252:
 253:
 254:
 255:
 256:
 257:
 258:
 259:
 260:
 261:
 262:
 263:
 264:
 265:
 266:
 267:
 268:
 269:
 270:
 271:
 272:
 273:
 274:
 275:
 276:
 277:
 278:
 279:
 280:
 281:
 282:
 283:
 284:
 285:
 286:
 287:
 288:
 289:
 290:
 291:
 292:
 293:
 294:
 295:
 296:
 297:
 298:
 299:
 300:
 301:
 302:
 303:
 304:
 305:
 306:
 307:
 308:
 309:
 310:
 311:
 312:
 313:
 314:
 315:
 316:
 317:
 318:
 319:
 320:
 321:
 322:
 323:
 324:
 325:
 326:
 327:
 328:
 329:
 330:
 331:
 332:
 333:
 334:
 335:
 336:
 337:
 338:
 339:
 340:
 341:
 342:
 343:
 344:
 345:
 346:
 347:
 348:
 349:
 350:
 351:
 352:
 353:
 354:
 355:
 356:
 357:
 358:
 359:
 360:
 361:
 362:
 363:
 364:
 365:
 366:
 367:
 368:
 369:
 370:
 371:
 372:
 373:
 374:
 375:
 376:
 377:
 378:
 379:
 380:
 381:
 382:
 383:
 384:
 385:
 386:
 387:
 388:
 389:
 390:
 391:
 392:
 393:
 394:
 395:
 396:
 397:
 398:
 399:
 400:
 401:
 402:
 403:
 404:
 405:
 406:
 407:
 408:
 409:
 410:
 411:
 412:
 413:
 414:
 415:
 416:
 
 | 
 unit csParser;
 
 interface
 
 uses SysUtils, Math;
 
 type
 tOpFunc = Function(prevValue, nextValue : Real) : Real;
 
 type
 tOp = class(TObject)
 private
 symbol : String;
 priority : Integer;
 opFunc : tOpFunc;
 public
 constructor create(symbol : String; priority : Integer; opFunc : tOpFunc);
 function value(prevValue, nextValue : Real) : Real;
 function getPriority : Integer;
 function getSymbol : String;
 end;
 
 
 type
 TParser = class(TObject)
 private
 ops : Array of tOp;
 ftext : String;
 subs : Array of TParser;
 fsubsCount : Integer;
 procedure getSubs;
 procedure setText(const value : String);
 function onHighestLevel(const operators : Array of String) : Boolean;
 function arrayOr(const operators : Array of String; position : Integer) : Integer;
 public
 constructor create(text : String);
 destructor free;
 function getSubText(i : Integer) : String;
 
 function value : Real;
 
 property subsCount : Integer read fsubsCount;
 property text : String read ftext write setText;
 
 end;
 
 implementation
 
 
 constructor tOp.create(symbol : String; priority : Integer; opFunc : tOpFunc);
 begin
 self.symbol := symbol;
 self.priority := priority;
 self.opFunc := opFunc;
 end;
 
 function tOp.value(prevValue, nextValue : Real) : Real;
 begin
 result := opFunc(prevValue, nextValue);
 end;
 
 function tOp.getPriority : Integer;
 begin
 result := priority;
 end;
 
 function tOp.getSymbol : String;
 begin
 result := symbol;
 end;
 
 
 function addition(prevValue, nextValue : Real) : Real;
 begin
 result := prevValue + nextValue;
 end;
 
 function subtraktion(prevValue, nextValue : Real) : Real;
 begin
 result := prevValue - nextValue;
 end;
 
 function multiplikation(prevValue, nextValue : Real) : Real;
 begin
 result := prevValue * nextValue;
 end;
 
 function division(prevValue, nextValue : Real) : Real;
 begin
 result := prevValue / nextValue;
 end;
 
 function potenz(prevValue, nextValue : Real) : Real;
 begin
 result := power(prevValue,nextValue);
 end;
 
 function sinus(prevValue, nextValue : Real) : Real;
 begin
 result := prevValue + sin(nextValue);
 end;
 
 function cosinus(prevValue, nextValue : Real) : Real;
 begin
 result := prevValue + cos(nextValue);
 end;
 
 function exponential(prevValue, nextValue : Real) : Real;
 begin
 result := prevValue + exp(nextValue);
 end;
 
 constructor TParser.create(text : String);
 begin
 SetLength(ops, 8);
 ops[0] := tOp.create('+',0,addition);
 ops[1] := tOp.create('-',0,subtraktion);
 ops[2] := tOp.create('*',1,multiplikation);
 ops[3] := tOp.create('/',1,division);
 ops[4] := tOp.create('^',2,potenz);
 ops[5] := tOp.create('sin',3,sinus);
 ops[6] := tOp.create('cos',3,cosinus);
 ops[7] := tOp.create('exp',3,exponential);
 
 self.ftext := text;
 SetLength(subs, 0);
 fsubsCount :=0;
 getSubs;
 end;
 
 destructor TParser.free;
 VAR i : INTEGER;
 begin
 for i:=0 To fsubscount-1 DO
 subs[i].free;
 
 SetLength(subs,0);
 
 for i:=0 TO High(ops) do
 ops[i].Free;
 end;
 
 procedure TParser.setText(const value : String);
 VAR i : INTEGER;
 begin
 self.ftext := value;
 for i:=0 TO fsubscount-1 DO
 subs[i].free;
 
 SetLength(subs, 0);
 fsubsCount := 0;
 getSubs;
 end;
 
 function TParser.arrayOr(const operators : Array of String; position : Integer) : Integer;
 VAR i : INTEGER;
 isTrue : Boolean;
 begin
 isTrue := False;
 for i := Low(operators) to high(operators) do
 begin
 if Copy(ftext, position, Length(operators[i])) = operators[i] then
 begin
 isTrue := true;
 break;
 end;
 end;
 
 if isTrue then result := i else result := -1;
 end;
 
 function TParser.onHighestLevel(const operators : Array of String) : Boolean;
 VAR done : Boolean;
 opIndex,i, bracketcount, last : Integer;
 begin
 done := False;
 last := 0;
 bracketcount := 0;
 i:=1;
 while i <= Length(ftext) do
 begin
 if ftext[i] = '(' then inc(bracketcount);
 if ftext[i] = ')' then dec(bracketcount);
 
 opIndex := arrayOr(operators, i);
 
 if (opIndex >= 0) and (bracketcount = 0) then
 begin
 
 if last < i-1 then
 begin
 SetLength(subs, Length(subs)+2);
 inc(fsubsCount, 2);
 end
 else
 begin
 SetLength(subs, Length(subs)+1);
 inc(fsubsCount, 1);
 end;
 
 if last < i-1 then
 subs[High(subs)-1] := TParser.create(Copy(ftext, last+1, i-last-1));
 
 subs[High(subs)] := TParser.create(Copy(ftext,i, Length(operators[opIndex])));
 
 last := i+Length(operators[opIndex])-1;
 inc(i, Length(operators[opIndex])-1);
 
 done := true;
 end;
 
 if (i = Length(ftext)) and (fsubsCount > 0) then
 begin
 SetLength(subs, Length(subs)+1);
 inc(fsubsCount);
 
 subs[High(subs)] := TParser.create(Copy(ftext, last+1, i-last));
 
 done := true;
 end;
 
 inc(i);
 end;
 result := done;
 end;
 
 procedure TParser.getSubs;
 VAR i,k,m, last : Integer;
 bracketcount : Integer;
 done, wasZero : Boolean;
 samePrior : Array of String;
 maxPrior : Integer;
 begin
 bracketcount := 0;
 last := 0;
 done := false;
 
 for i:= 0 to high(ops) do
 if ftext = ops[i].getSymbol then exit;
 
 while (ftext[1] = '(') and(ftext[Length(ftext)] = ')') do
 begin
 wasZero := False;
 
 for i:=1 TO Length(ftext)-1 DO
 begin
 if ftext[i] = '(' then inc(bracketcount);
 if ftext[i] = ')' then dec(bracketcount);
 
 if bracketcount = 0 then
 begin
 wasZero := True;
 break;
 end;
 end;
 if wasZero = false then
 ftext := Copy(ftext, 2, Length(ftext)-2);
 
 bracketcount := 0;
 end;
 
 maxPrior := 0;
 for m:=0 TO High(ops) DO
 if ops[m].getPriority > maxPrior then maxPrior := ops[m].getPriority;
 
 
 for m:=0 TO maxPrior DO
 begin
 SetLength(samePrior, 0);
 
 for k:=0 TO high(ops) DO
 if ops[k].getPriority = m then
 begin
 SetLength(samePrior, Length(samePrior)+1);          samePrior[High(samePrior)] := ops[k].getSymbol;
 end;
 
 done := onHighestLevel(samePrior);
 
 if done then exit;
 end;
 end;
 
 function TParser.value : Real;
 VAR i,k,m : INTEGER;
 operation : String;
 valueFirst, opFound : Boolean;
 begin
 if fsubsCount = 0 then
 begin
 result := StrToFloat(ftext);
 exit;
 end;
 
 
 valueFirst := True;
 for m:=0 TO High(ops) do
 if subs[0].ftext = ops[m].getSymbol then
 begin
 valueFirst := False;
 break;
 end;
 
 if valueFirst then
 begin
 result := subs[0].value ;
 k := 1;
 end else
 begin
 result := 0;
 k := 0;
 end;
 
 operation := '';
 
 
 for i := k TO subsCount-1 DO
 begin
 opFound := False;
 for m:=0 to High(ops) do
 if subs[i].ftext = ops[m].getSymbol then
 begin
 opFound := True;
 break;
 end;
 
 if opFound then
 begin
 operation := subs[i].ftext;
 continue;
 end;
 
 
 if operation <> '' then
 for m:=0 TO High(ops) do
 if operation = ops[m].getSymbol then result := ops[m].value(result, subs[i].value);
 
 operation := '';
 end;
 end;
 
 function TParser.getSubText(i : Integer) : String;
 begin
 result := subs[i].ftext;
 end;
 
 end.
 | _________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
 |  |  |  
| Popov 
          Beiträge: 1655
 Erhaltene Danke: 13
 
 WinXP Prof.
 Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
 
 | 
Verfasst: Mo 08.12.03 11:52 
 
Ist ja toll, wenn es im Open Source - Bereich üblich ist den alten Code zu belassen, aber man müllt sich erstens alles zu, zweitens blickt da keiner mehr durch wenn jeder bei jeder kleiner Änderung die alte Unit belässt und dann nach zehn kleinen Änderungen zehn Units da stehen und dritens wer hat nach zwei Stunden gemerkt, daß es je die erste Unit gegeben hat. Da sind nur zwei Stunden Unterschied zwischen den beiden Postings. Wen interresiert nach zwei Stunden wie die erste Version je ausgesehen hat.
 Das ganze sollte eine Sparte werden wo Leute ernsthafte Units reinstellen sollen. Nichts zu gucken und lernen, sondern um sich die Arbeit zu erleichern. Aber das wird wieder das gleiche wie dei Freware Sparte wo jeder seine Tagesergüsse veröffentlicht und die Sparte dann nichts wert ist.
 _________________ Popov
 |  |  |  
| Raphael O. 
          Beiträge: 1596
 
 
 VS 2013
 
 | 
Verfasst: Mo 08.12.03 15:33 
 
wie oft willst du noch darauf hinweisen? |  |  |  |