00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define PARSER_CPP 1
00024
00025 #include <math.h>
00026 #include <string.h>
00027 #include <stdio.h>
00028 #include <ctype.h>
00029 #include <errno.h>
00030 #include "moremath.h"
00031 #include "parser.h"
00032 #include "equ.h"
00033 #include "func.h"
00034 #include "functext.h"
00035 #include "errors.h"
00036
00037
00038 Parser::Parser()
00039 {
00040 EquationTokenStart = NULL;
00041 EquationTokenEnd = NULL;
00042 EquationText = NULL;
00043 equation = NULL;
00044 }
00045
00046
00047 Parser::~Parser()
00048 {
00049 while (EquationTokenStart!=EquationTokenEnd) {
00050 EquationTokenStart=EquationTokenStart->Next;
00051 delete EquationTokenStart->Last;
00052 };
00053 if (EquationTokenStart!=NULL) delete EquationTokenStart;
00054 }
00055
00056
00057 Equation *
00058 Parser::TextToTree( char *text )
00059 {
00060 try {
00061 equation = new Equation();
00062
00063 EquationText = new char[strlen(text) + 1];
00064 strcpy(EquationText,text);
00065 if (strlen(EquationText) == 0) {
00066 throw ERR_NO_TEXT;
00067 };
00068 PassOne();
00069 ErrorCheck();
00070 PassTwo();
00071 RemoveBrackets();
00072 TidyUp();
00073 TreeToText();
00074 }
00075 catch (...) {
00076 if (equation)
00077 {
00078 delete equation;
00079 equation = NULL;
00080 }
00081 if (EquationText) {
00082 delete EquationText;
00083 EquationText = NULL;
00084 }
00085 while (EquationTokenStart!=EquationTokenEnd) {
00086 EquationTokenStart=EquationTokenStart->Next;
00087 delete EquationTokenStart->Last;
00088 };
00089 if (EquationTokenStart!=NULL) {
00090 delete EquationTokenStart;
00091 EquationTokenStart = NULL;
00092 EquationTokenEnd = NULL;
00093 }
00094 throw;
00095 }
00096
00097 if (equation->EquationText)
00098 delete [] equation->EquationText;
00099 equation->EquationText = EquationText;
00100 EquationText = NULL;
00101 while (EquationTokenStart!=EquationTokenEnd) {
00102 EquationTokenStart=EquationTokenStart->Next;
00103 delete EquationTokenStart->Last;
00104 };
00105 if (EquationTokenStart!=NULL) {
00106 delete EquationTokenStart;
00107 EquationTokenStart = NULL;
00108 EquationTokenEnd = NULL;
00109 }
00110
00111 return equation;
00112 }
00113
00114
00115 void
00116 Parser::TreeToText( Equation *eqn )
00117 {
00118 equation = eqn;
00119
00120 try {
00121 TidyUp();
00122 TreeToText();
00123 }
00124 catch (...) {
00125 if (EquationText) {
00126 delete EquationText;
00127 EquationText = NULL;
00128 }
00129 }
00130
00131 if (equation->EquationText != NULL) delete equation->EquationText;
00132 equation->EquationText = EquationText;
00133 EquationText = NULL;
00134 }
00135
00136 void
00137 Parser::TidyUpEqn(Equation *eqn)
00138 {
00139 equation = eqn;
00140
00141 TidyUp();
00142 }
00143
00144
00145 void
00146 Parser::PassOne()
00147 {
00148 char * Pointer;
00149 Pointer = EquationText;
00150 char * ThisFunc = new char[10];
00151 ThisFunc[0] = 0;
00152 double * ThisDigit = new double;
00153 *ThisDigit = 0;
00154 bool * DoDigit = new bool;
00155 *DoDigit = false;
00156 int * DecPt = new int;
00157 *DecPt = 0;
00158 equation->brackets = 0;
00159
00160 while ( *Pointer != 0 ) {
00161 if ( isdigit(*Pointer) ) {
00162 if ( strlen(ThisFunc) != 0 ) EndFunc(ThisFunc);
00163 Digit( Pointer, ThisDigit, DoDigit, DecPt );
00164 }
00165 if ( isalpha(*Pointer) ) {
00166 if ( *DoDigit == true ) {
00167 EndNum( ThisDigit, DoDigit, DecPt );
00168 }
00169 Alpha( Pointer, ThisFunc );
00170 }
00171 if ( ispunct(*Pointer) ) {
00172 if ( ( *DoDigit == true ) && ( *Pointer != '.' ) ) {
00173 EndNum( ThisDigit, DoDigit, DecPt );
00174 }
00175 if ( strlen(ThisFunc) != 0 ) EndFunc(ThisFunc);
00176 if ( *Pointer == '.' ) {
00177 *DecPt = 1;
00178 if ( *DoDigit == false ) {
00179 *DoDigit = true;
00180 *ThisDigit = 0;
00181 }
00182 }
00183 else {
00184 Symbol(Pointer);
00185 }
00186 }
00187 if (isspace(*Pointer)) {
00188 if ( *DoDigit == true ) EndNum( ThisDigit, DoDigit, DecPt );
00189 if ( ThisFunc[0] != 0 ) EndFunc( ThisFunc );
00190 }
00191 Pointer++;
00192 }
00193 if ( *DoDigit == true ) EndNum( ThisDigit, DoDigit, DecPt );
00194 if ( ThisFunc[0] != 0 ) EndFunc( ThisFunc );
00195 delete ThisDigit;
00196 delete DoDigit;
00197 delete DecPt;
00198 delete [] ThisFunc;
00199 }
00200
00201
00202 void
00203 Parser::Digit(char * Pointer, double * ThisDigit, bool * DoDigit, int * DecPt)
00204 {
00205 if ( *DecPt == 0 ) {
00206 *ThisDigit = (*ThisDigit) * 10 + (*Pointer) - 48;
00207 }
00208 else {
00209 (*ThisDigit) = (*ThisDigit) + ((*Pointer) - 48) / pow( 10.0, (double)(*DecPt) );
00210 (*DecPt)++;
00211 }
00212 if ( *DoDigit == false ) *DoDigit = true;
00213 }
00214
00215
00216 void
00217 Parser::Alpha(char * Pointer, char * ThisFunc)
00218 {
00219 if ( strlen(ThisFunc) < 10 ) {
00220 strncat( ThisFunc, Pointer, 1 );
00221 }
00222 }
00223
00224
00225 void
00226 Parser::Symbol(char * Pointer)
00227 {
00228 func_type WhichSymbol = MTK_NOFUNC;
00229 switch (*Pointer) {
00230 case '!' :
00231 WhichSymbol=MTK_FACTORIAL;
00232 break;
00233 case '(' : WhichSymbol=MTK_LBRACKET;
00234 equation->brackets++;
00235 break;
00236 case ')' : WhichSymbol=MTK_RBRACKET;
00237 equation->brackets--;
00238 break;
00239 case '*' : WhichSymbol=MTK_MULTIPLY;
00240 break;
00241 case '+' : WhichSymbol=MTK_ADD;
00242 break;
00243 case ',': WhichSymbol = MTK_COMMA;
00244 break;
00245 case '-' : WhichSymbol=MTK_SUBTRACT;
00246 break;
00247 case '/' : WhichSymbol=MTK_DIVIDE;
00248 break;
00249 case '^' : WhichSymbol=MTK_POWER;
00250 break;
00251 default :
00252
00253 throw ERR_SYMBOL;
00254 };
00255 if (WhichSymbol!=0) {
00256 AddToken(WhichSymbol);
00257 (EquationTokenEnd->Value).Number=0;
00258 };
00259 }
00260
00261
00262 void
00263 Parser::EndFunc(char * ThisFunc)
00264 {
00265 func_type WhichFunc=MTK_NOFUNC, i;
00266
00267 if (strcmp(ThisFunc,"C")==0) {
00268 WhichFunc=MTK_COMBINATION;
00269 }
00270 else {
00271 if (strcmp(ThisFunc,"P")==0) {
00272 WhichFunc=MTK_PERMUTATION;
00273 }
00274 else {
00275 if (strcmp(ThisFunc,"pi")==0) WhichFunc=MTK_PI_SYM;
00276 else {
00277 Alpha(" ",ThisFunc);
00278 i = MTK_LN;
00279 while ( WhichFunc==MTK_NOFUNC && i<=MTK_FRAC ) {
00280 if ( strcmp(ThisFunc,func_details[i].func_text)==0 ) WhichFunc = i;
00281 i++;
00282 }
00283 }
00284 }
00285 }
00286
00287 if (WhichFunc != MTK_NOFUNC) {
00288 AddToken(WhichFunc);
00289 EquationTokenEnd->Value.Number=0;
00290 }
00291 else {
00292 variable *VarPoint;
00293 VarPoint = equation->Variables.first();
00294 AddToken(MTK_VARIABLE);
00295 ThisFunc[ strlen(ThisFunc) - 1 ] = 0;
00296 while (VarPoint!=NULL) {
00297 if (strcmp(ThisFunc,VarPoint->Name)==0) {
00298 EquationTokenEnd->Value.WhichVar=equation->Variables.at() + 1;
00299 ThisFunc[0]=0;
00300 return;
00301 }
00302 VarPoint=equation->Variables.next();
00303 }
00304 VarPoint = new variable;
00305 equation->Variables.append(VarPoint);
00306 EquationTokenEnd->Value.WhichVar=equation->Variables.count();
00307 strncpy( VarPoint->Name, ThisFunc, 12 );
00308 VarPoint->Value = 0;
00309 }
00310 ThisFunc[0] = 0;
00311 }
00312
00313
00314 void
00315 Parser::EndNum(double * ThisDigit, bool * DoDigit, int * DecPt)
00316 {
00317 AddToken(MTK_NUMBER);
00318 (EquationTokenEnd->Value).Number=*ThisDigit;
00319 *ThisDigit=0;
00320 *DoDigit=false;
00321 *DecPt=0;
00322 }
00323
00324
00325 void
00326 Parser::AddToken(func_type WhichType)
00327 {
00328 if (EquationTokenEnd!=NULL)
00329 {
00330 EquationTokenEnd->Next=new Token;
00331 (EquationTokenEnd->Next)->Last=EquationTokenEnd;
00332 EquationTokenEnd=EquationTokenEnd->Next;
00333 EquationTokenEnd->Next=NULL;
00334 EquationTokenEnd->Type=WhichType;
00335 }
00336 else
00337 {
00338 EquationTokenStart=new Token;
00339 EquationTokenEnd=EquationTokenStart;
00340 EquationTokenStart->Last=NULL;
00341 EquationTokenStart->Next=NULL;
00342 EquationTokenStart->Type=WhichType;
00343 };
00344 }
00345
00346
00347
00348
00349 void
00350 Parser::ErrorCheck()
00351 {
00352 Token *Pointer,*Temp;
00353
00354 if (equation->brackets != 0) {
00355 throw ERR_BRACKET;
00356 }
00357
00358 Pointer=EquationTokenStart;
00359 if (EquationTokenStart==EquationTokenEnd) {
00360 if ( EquationTokenStart==NULL ) {
00361 throw ERR_NO_TEXT;
00362 };
00363 if (((Pointer->Type)<MTK_NUMBER)||((Pointer->Type)>MTK_PI_SYM)) {
00364 throw ERR_FUNCTION;
00365 };
00366 return;
00367 };
00368 switch (Pointer->Type) {
00369 case MTK_ADD :
00370 if (((((Pointer->Next)->Type)>=MTK_MULTIPLY)&&(((Pointer->Next)->Type)<=MTK_POWER)) || (Pointer->Next->Type == MTK_BESSJ)) {
00371 throw ERR_OPERATOR;
00372 };
00373 (Pointer->Next)->Last=NULL;
00374 Temp=Pointer;
00375 Pointer=Pointer->Next;
00376 delete Temp;
00377 EquationTokenStart=Pointer;
00378 break;
00379 case MTK_SUBTRACT :
00380 if (((((Pointer->Next)->Type)>=MTK_MULTIPLY)&&(((Pointer->Next)->Type)<=MTK_POWER)) || (Pointer->Next->Type == MTK_BESSJ)) {
00381 throw ERR_OPERATOR;
00382 };
00383 if ((Pointer->Next)->Type==MTK_NUMBER) {
00384 (((Pointer->Next)->Value).Number)=-(((Pointer->Next)->Value).Number);
00385 (Pointer->Next)->Last=NULL;
00386 Temp=Pointer;
00387 Pointer=Pointer->Next;
00388 delete Temp;
00389 EquationTokenStart=Pointer;
00390 }
00391 else {
00392 Pointer->Type=MTK_NUMBER;
00393 (Pointer->Value).Number=-1;
00394 Temp=Pointer->Next;
00395 Pointer->Next = new Token;
00396 Pointer->Next->Last = Pointer;
00397 Pointer->Next->Next = Temp;
00398 Pointer->Next->Type = MTK_MULTIPLY;
00399 Temp->Last = Pointer->Next;
00400 };
00401 break;
00402 case MTK_MULTIPLY : case MTK_DIVIDE : case MTK_POWER :
00403 throw ERR_OPERATOR;
00404 case MTK_COMBINATION : case MTK_PERMUTATION : case MTK_FACTORIAL : case MTK_COMMA :
00405 throw ERR_FUNCTION;
00406 case MTK_RBRACKET :
00407 throw ERR_BRACKET;
00408 };
00409 while ((Pointer->Next!=EquationTokenEnd)&&(Pointer->Next!=NULL)) {
00410 Pointer=Pointer->Next;
00411 switch (Pointer->Type) {
00412 case MTK_MULTIPLY : case MTK_DIVIDE : case MTK_POWER :
00413 if ( (Pointer->Last->Type != MTK_LBRACKET) && ((Pointer->Last->Type < MTK_FACTORIAL) || (Pointer->Last->Type > MTK_RBRACKET)) ) {
00414 throw ERR_OPERATOR;
00415 };
00416 break;
00417 case MTK_FACTORIAL : case MTK_COMBINATION : case MTK_PERMUTATION : case MTK_COMMA :
00418 if ( (Pointer->Last->Type < MTK_NUMBER) || (Pointer->Last->Type > MTK_RBRACKET) ) {
00419 if (Pointer->Last->Type != MTK_INT) {
00420 throw ERR_FUNCTION;
00421 }
00422 }
00423 break;
00424 case MTK_ADD : case MTK_SUBTRACT :
00425 if (((Pointer->Next->Type >= MTK_MULTIPLY) && (Pointer->Next->Type <= MTK_POWER)) || (Pointer->Next->Type == MTK_COMMA)) {
00426 throw ERR_OPERATOR;
00427 };
00428 if ( ( (Pointer->Last->Type < MTK_NUMBER) || (Pointer->Last->Type > MTK_RBRACKET) ) && (Pointer->Last->Type != MTK_FACTORIAL) ){
00429 if ( (Pointer->Next->Type == MTK_NUMBER) && (Pointer->Type == MTK_SUBTRACT) )
00430 Pointer->Next->Value.Number = - Pointer->Next->Value.Number;
00431 if ( (Pointer->Next->Type == MTK_NUMBER) || (Pointer->Type == MTK_ADD) ) {
00432 Pointer->Next->Last = Pointer->Last;
00433 Temp = Pointer;
00434 Pointer = Pointer->Next;
00435 delete Temp;
00436 Pointer->Last->Next = Pointer;
00437 }
00438 else {
00439 Pointer->Type=MTK_NUMBER;
00440 (Pointer->Value).Number=-1;
00441 Temp=Pointer->Next;
00442 Pointer->Next = new Token;
00443 Pointer->Next->Last = Pointer;
00444 Pointer->Next->Next = Temp;
00445 Pointer->Next->Type = MTK_MULTIPLY;
00446 Temp->Last = Pointer->Next;
00447 };
00448 };
00449 break;
00450 case MTK_RBRACKET :
00451 if ((((Pointer->Last)->Type)<MTK_LBRACKET)
00452 || (((Pointer->Last)->Type)>MTK_RBRACKET)) {
00453 throw ERR_BRACKET;
00454 };
00455 break;
00456 default :
00457 if ((Pointer->Last->Type > MTK_LBRACKET) && (Pointer->Last->Type < MTK_COMMA)) {
00458 Temp = Pointer->Last;
00459 Pointer->Last=new Token;
00460 Pointer->Last->Next=Pointer;
00461 Pointer=Pointer->Last;
00462 Pointer->Last=Temp;
00463 Temp->Next=Pointer;
00464 Pointer->Type=MTK_MULTIPLY;
00465 Pointer->Value.Number=0;
00466 Pointer=Pointer->Next;
00467 };
00468 };
00469 };
00470 Pointer=Pointer->Next;
00471 if (Pointer) {
00472 if ((((Pointer->Type)>=MTK_COMBINATION)&&((Pointer->Type)<=MTK_FRAC))
00473 || (Pointer->Type == MTK_COMMA) ) {
00474 throw ERR_FUNCTION;
00475 };
00476 if ((Pointer->Type)==MTK_LBRACKET) {
00477 throw ERR_BRACKET;
00478 };
00479 if (((Pointer->Type)<=MTK_POWER) && ((Pointer->Type)>=MTK_ADD)) {
00480 throw ERR_OPERATOR;
00481 };
00482 if (((Pointer->Type)>=MTK_NUMBER)&&((Pointer->Type)<=MTK_PI_SYM)) {
00483 if ((Pointer->Last->Type >= MTK_NUMBER) && (Pointer->Last->Type < MTK_COMMA)) {
00484 Temp=Pointer->Last;
00485 Pointer->Last=new Token;
00486 Pointer->Last->Next=Pointer;
00487 Pointer=Pointer->Last;
00488 Pointer->Last=Temp;
00489 Temp->Next=Pointer;
00490 Pointer->Type=MTK_MULTIPLY;
00491 Pointer->Value.Number=0;
00492 Pointer=Pointer->Next;
00493 }
00494 }
00495 }
00496 }
00497
00498
00499
00500 void
00501 Parser::PassTwo()
00502 {
00503 Node *TreePos;
00504 Token *Pointer;
00505
00506 Pointer = EquationTokenStart;
00507 TreePos = equation->Root;
00508 TreePos->Type=Pointer->Type;
00509 TreePos->evalfn = func_details[TreePos->Type].func_ptr;
00510 TreePos->Value = Pointer->Value;
00511
00512 while (Pointer->Next!=NULL) {
00513 Pointer=Pointer->Next;
00514
00515 if (Priority(TreePos->Type,Pointer->Type)==true) {
00516 if ((TreePos->Parent!=NULL)&&(Pointer->Type!=MTK_FACTORIAL)) {
00517 while (Priority((TreePos->Parent)->Type,Pointer->Type)==true) {
00518 TreePos=TreePos->Parent;
00519 if (TreePos->Parent==NULL) break;
00520 }
00521 }
00522 if (Pointer->Type==MTK_RBRACKET) {
00523 if (TreePos->Parent==NULL) {
00524 throw ERR_BRACKET;
00525 }
00526 TreePos=TreePos->Parent;
00527 }
00528 TreePos=equation->AddParent(TreePos);
00529 }
00530 else {
00531 if ((((TreePos->Type>=MTK_ADD)&&(TreePos->Type)<=MTK_POWER))||(Pointer->Type==MTK_LBRACKET) || (TreePos->Type == MTK_COMMA)) {
00532 if (Pointer->Type==MTK_LBRACKET) {
00533 if (TreePos->Child_One==NULL) {
00534 TreePos=equation->AddChildOne(TreePos);
00535 }
00536 else {
00537 TreePos=equation->AddChildTwo(TreePos);
00538 }
00539 }
00540 else {
00541 TreePos=equation->AddChildTwo(TreePos);
00542 }
00543 }
00544 else {
00545 while ((Priority(TreePos->Type,Pointer->Type)!=true)
00546 ||(TreePos->Child_One!=NULL)) {
00547 if (TreePos->Child_One==NULL) break;
00548 if (TreePos->Child_Two==NULL) {
00549 TreePos=TreePos->Child_One;
00550 }
00551 else {
00552 TreePos=TreePos->Child_Two;
00553 }
00554 }
00555 if (Priority(TreePos->Type,Pointer->Type)==true) {
00556 TreePos=equation->AddParent(TreePos);
00557 }
00558 else {
00559 TreePos=equation->AddChildOne(TreePos);
00560 }
00561 }
00562 }
00563 equation->InitNode(TreePos,Pointer->Type,Pointer->Value);
00564 TreePos->Child_Two=NULL;
00565 }
00566 }
00567
00568
00569 bool
00570 Parser::Priority(func_type First, func_type Second)
00571 {
00572 if (Second==MTK_LBRACKET) return false;
00573 if (First==MTK_LBRACKET) return false;
00574 if (First==MTK_RBRACKET) return true;
00575 if (Second==MTK_RBRACKET) return true;
00576 if (Second == MTK_COMMA) return true;
00577 if (First == MTK_COMMA) return false;
00578 if ((First==MTK_ADD)||(First==MTK_SUBTRACT))
00579 {
00580 if ((Second==MTK_ADD)||(Second==MTK_SUBTRACT)) return true;
00581 return false;
00582 };
00583 if ((First==MTK_MULTIPLY)||(First==MTK_DIVIDE))
00584 {
00585 if ((Second>=MTK_ADD)&&(Second<=MTK_DIVIDE)) return true;
00586 return false;
00587 };
00588 if (Second==MTK_FACTORIAL) return true;
00589 if ((Second>=MTK_ADD)&&(Second<=MTK_DIVIDE)) return true;
00590 if (Second == MTK_BESSJ) return true;
00591 if ((First>=MTK_NUMBER)&&(First<=MTK_RBRACKET)) return true;
00592 return false;
00593 }
00594
00595
00596 void
00597 Parser::RemoveBrackets()
00598 {
00599 Node *TreePos, *temp;
00600
00601 TreePos = equation->Root;
00602 while (equation->Root->Brackets==0) {
00603 while (TreePos->Child_One!=NULL) {
00604 if ((TreePos->Child_One)->Brackets==1) break;
00605 TreePos=TreePos->Child_One;
00606 };
00607 if ((TreePos->Type==MTK_LBRACKET)||(TreePos->Type==MTK_RBRACKET)) {
00608 TreePos=equation->DeleteNode(TreePos);
00609 if (TreePos==NULL) break;
00610 }
00611 else {
00612 if (TreePos->Child_Two==NULL) {
00613 TreePos->Brackets=1;
00614 TreePos=TreePos->Parent;
00615 }
00616 else {
00617 if ((TreePos->Child_Two)->Brackets==1) {
00618 TreePos->Brackets=1;
00619 TreePos=TreePos->Parent;
00620 }
00621 else {
00622 TreePos=TreePos->Child_Two;
00623 }
00624 }
00625 }
00626 }
00627 if ((equation->Root->Type==MTK_LBRACKET)||(equation->Root->Type==MTK_RBRACKET)) {
00628 equation->Delete(equation->Root);
00629 }
00630
00631 equation->Reset(0);
00632 TreePos = equation->Root;
00633 while (equation->Root->Brackets==0) {
00634 while (TreePos->Child_One!=NULL) {
00635 if ((TreePos->Child_One)->Brackets==1) break;
00636 TreePos=TreePos->Child_One;
00637 };
00638 if (TreePos->Type == MTK_COMMA) {
00639 if ( !TreePos->Parent || !TreePos->Child_One || !TreePos->Child_Two || (TreePos->Parent->Type != MTK_BESSJ))
00640 throw ERR_FUNCTION;
00641 temp = TreePos;
00642 TreePos = TreePos->Parent;
00643 TreePos->Child_One = temp->Child_One;
00644 TreePos->Child_Two = temp->Child_Two;
00645 temp->Child_One->Parent = TreePos;
00646 temp->Child_Two->Parent = TreePos;
00647 delete temp;
00648 }
00649 else {
00650 if (TreePos->Child_Two==NULL) {
00651 TreePos->Brackets=1;
00652 TreePos=TreePos->Parent;
00653 }
00654 else {
00655 if (TreePos->Child_Two->Brackets == 1) {
00656 TreePos->Brackets=1;
00657 TreePos=TreePos->Parent;
00658 }
00659 else {
00660 TreePos=TreePos->Child_Two;
00661 }
00662 }
00663 }
00664 }
00665 }
00666
00667
00668
00669 void
00670 Parser::TidyUp()
00671 {
00672 Node *TreePos;
00673 TreePos = equation->Root;
00674
00675 equation->Reset(0);
00676 while ( equation->Root->Brackets == 0 ) {
00677 while ( TreePos->Child_One != NULL ) {
00678 if ( TreePos->Child_One->Brackets == 1 ) break;
00679 TreePos=TreePos->Child_One;
00680 };
00681 TreePos->Brackets = 1;
00682 TreePos = TreePos->Parent;
00683 if ( TreePos == NULL ) break;
00684 if ( TreePos->Child_Two == NULL ) {
00685 TidyNode(TreePos);
00686 }
00687 else {
00688 if ( (TreePos->Child_Two)->Brackets==0 ) {
00689 TreePos=TreePos->Child_Two;
00690 }
00691 else {
00692 TidyNode( TreePos );
00693 }
00694 }
00695 }
00696 }
00697
00698
00699
00700 void
00701 Parser::TidyNode(Node *&TreePos)
00702 {
00703 Node *Temp;
00704 double value;
00705
00706 switch (TreePos->Type) {
00707 case MTK_ADD: case MTK_SUBTRACT:
00708 if ((TreePos->Child_One->Type == MTK_NUMBER)&&(TreePos->Child_Two->Type == MTK_NUMBER)) {
00709 if (TreePos->Type == MTK_ADD) {
00710 TreePos->Value.Number = TreePos->Child_One->Value.Number + TreePos->Child_Two->Value.Number;
00711 }
00712 else {
00713 TreePos->Value.Number = TreePos->Child_One->Value.Number - TreePos->Child_Two->Value.Number;
00714 }
00715 TreePos->Type = MTK_NUMBER;
00716 TreePos->evalfn=func_details[MTK_NUMBER].func_ptr;
00717 equation->Delete(TreePos->Child_One);
00718 equation->Delete(TreePos->Child_Two);
00719 TreePos->Child_One = NULL;
00720 TreePos->Child_Two = NULL;
00721 break;
00722 }
00723 if ((TreePos->Child_One->Type == MTK_NUMBER) && ((TreePos->Child_One->Value).Number == 0)) {
00724 TreePos = equation->DeleteNode(TreePos,TreePos->Child_One,TreePos->Child_Two);
00725 break;
00726 }
00727 if ((TreePos->Child_Two->Type == MTK_NUMBER) && ((TreePos->Child_Two->Value).Number == 0)) {
00728 TreePos = equation->DeleteNode(TreePos,TreePos->Child_Two,TreePos->Child_One);
00729 break;
00730 };
00731 if ((TreePos->Child_Two->Type == MTK_NUMBER) && ((TreePos->Child_Two->Value).Number < 0)) {
00732 TreePos->Child_Two->Value.Number = -(TreePos->Child_Two->Value.Number);
00733 if (TreePos->Type == MTK_ADD) TreePos->Type = MTK_SUBTRACT;
00734 else TreePos->Type = MTK_ADD;
00735 TreePos->evalfn=func_details[TreePos->Type].func_ptr;
00736 break;
00737 };
00738 break;
00739 case MTK_MULTIPLY:
00740 if ((TreePos->Child_One->Type == MTK_NUMBER) && (TreePos->Child_Two->Type == MTK_NUMBER)) {
00741 TreePos->Value.Number = TreePos->Child_One->Value.Number * TreePos->Child_Two->Value.Number;
00742 TreePos->Type = MTK_NUMBER;
00743 TreePos->evalfn = func_details[MTK_NUMBER].func_ptr;
00744 equation->Delete(TreePos->Child_One);
00745 equation->Delete(TreePos->Child_Two);
00746 TreePos->Child_One = NULL;
00747 TreePos->Child_Two = NULL;
00748 break;
00749 }
00750 if (((TreePos->Child_One->Type == MTK_NUMBER) && ((TreePos->Child_One->Value).Number == 0))
00751 || ((TreePos->Child_Two->Type == MTK_NUMBER) && ((TreePos->Child_Two->Value).Number == 0))) {
00752 equation->Delete(TreePos->Child_One);
00753 equation->Delete(TreePos->Child_Two);
00754 TreePos->Type=MTK_NUMBER;
00755 TreePos->evalfn = func_details[MTK_NUMBER].func_ptr;
00756 (TreePos->Value).Number=0;
00757 TreePos->Child_One=NULL;
00758 TreePos->Child_Two=NULL;
00759 break;
00760 };
00761 if ((TreePos->Child_One->Type == MTK_NUMBER) && ((TreePos->Child_One->Value).Number == 1)) {
00762 TreePos = equation->DeleteNode(TreePos,TreePos->Child_One,TreePos->Child_Two);
00763 break;
00764 };
00765 if ((TreePos->Child_Two->Type == MTK_NUMBER) && ((TreePos->Child_Two->Value).Number == 1)) {
00766 TreePos = equation->DeleteNode(TreePos,TreePos->Child_Two,TreePos->Child_One);
00767 break;
00768 };
00769 if ((TreePos->Child_One->Type >= MTK_LN) && (TreePos->Child_One->Type <= MTK_FRAC)) {
00770 if ((TreePos->Child_Two->Type < MTK_LN) || (TreePos->Child_Two->Type > MTK_FRAC)) {
00771 Temp=TreePos->Child_One;
00772 TreePos->Child_One=TreePos->Child_Two;
00773 TreePos->Child_Two=Temp;
00774 };
00775 };
00776 break;
00777 case MTK_DIVIDE:
00778 if ((TreePos->Child_Two->Type == MTK_NUMBER) && ((TreePos->Child_Two->Value).Number == 0)) {
00779 throw ERR_DIV_ZERO;
00780 };
00781 if ((TreePos->Child_One->Type == MTK_NUMBER) && (TreePos->Child_Two->Type == MTK_NUMBER)) {
00782 TreePos->Value.Number = TreePos->Child_One->Value.Number / TreePos->Child_Two->Value.Number;
00783 TreePos->Type = MTK_NUMBER;
00784 TreePos->evalfn = func_details[MTK_NUMBER].func_ptr;
00785 equation->Delete(TreePos->Child_One);
00786 equation->Delete(TreePos->Child_Two);
00787 TreePos->Child_One = NULL;
00788 TreePos->Child_Two = NULL;
00789 break;
00790 }
00791 if ((TreePos->Child_One->Type == MTK_NUMBER) && ((TreePos->Child_One->Value).Number == 0)) {
00792 equation->Delete(TreePos->Child_One);
00793 equation->Delete(TreePos->Child_Two);
00794 TreePos->Type=MTK_NUMBER;
00795 TreePos->evalfn = func_details[MTK_NUMBER].func_ptr;
00796 (TreePos->Value).Number=0;
00797 TreePos->Child_One=NULL;
00798 TreePos->Child_Two=NULL;
00799 break;
00800 }
00801 if ((TreePos->Child_Two->Type == MTK_NUMBER) && ((TreePos->Child_Two->Value).Number == 1)) {
00802 TreePos = equation->DeleteNode(TreePos,TreePos->Child_Two,TreePos->Child_One);
00803 break;
00804 }
00805 break;
00806 case MTK_POWER :
00807 if (((TreePos->Child_One)->Type==MTK_NUMBER)&&(((TreePos->Child_One)->Value).Number==0)
00808 &&((TreePos->Child_Two)->Type==MTK_NUMBER)&&(((TreePos->Child_Two)->Value).Number==0)) {
00809 throw ERR_DIV_ZERO;
00810 };
00811 if (((TreePos->Child_One)->Type==MTK_NUMBER)&&(((TreePos->Child_One)->Value).Number==0)) {
00812 equation->Delete(TreePos->Child_One);
00813 equation->Delete(TreePos->Child_Two);
00814 TreePos->Child_One=NULL;
00815 TreePos->Child_Two=NULL;
00816 TreePos->Type=MTK_NUMBER;
00817 TreePos->evalfn = func_details[MTK_NUMBER].func_ptr;
00818 (TreePos->Value).Number=0;
00819 break;
00820 }
00821 if (((TreePos->Child_Two)->Type==MTK_NUMBER)&&(((TreePos->Child_Two)->Value).Number==0)) {
00822 equation->Delete(TreePos->Child_One);
00823 equation->Delete(TreePos->Child_Two);
00824 TreePos->Child_One=NULL;
00825 TreePos->Child_Two=NULL;
00826 TreePos->Type=MTK_NUMBER;
00827 TreePos->evalfn = func_details[MTK_NUMBER].func_ptr;
00828 (TreePos->Value).Number=1;
00829 break;
00830 }
00831 if (((TreePos->Child_Two)->Type==MTK_NUMBER)&&(((TreePos->Child_Two)->Value).Number==1)) {
00832 TreePos = equation->DeleteNode(TreePos, TreePos->Child_Two, TreePos->Child_One);
00833 break;
00834 }
00835 if (((TreePos->Child_One)->Type==MTK_NUMBER)&&((TreePos->Child_Two)->Type==MTK_NUMBER)) {
00836 TreePos->Value.Number = pow(TreePos->Child_One->Value.Number,TreePos->Child_Two->Value.Number);
00837 TreePos->Type = MTK_NUMBER;
00838 TreePos->evalfn = func_details[MTK_NUMBER].func_ptr;
00839 equation->Delete(TreePos->Child_One);
00840 equation->Delete(TreePos->Child_Two);
00841 TreePos->Child_One = NULL;
00842 TreePos->Child_Two = NULL;
00843 break;
00844 }
00845 break;
00846 case MTK_BESSJ:
00847 case MTK_COMBINATION:
00848 case MTK_PERMUTATION:
00849 if ((TreePos->Child_One->Type == MTK_NUMBER) && (TreePos->Child_Two->Type == MTK_NUMBER)) {
00850 switch (TreePos->Type) {
00851 case MTK_BESSJ:
00852 value = ansi_jn((int)TreePos->Child_One->Value.Number,TreePos->Child_Two->Value.Number);
00853 break;
00854 case MTK_COMBINATION:
00855 value = combination(TreePos->Child_One->Value.Number, TreePos->Child_Two->Value.Number);
00856 break;
00857 case MTK_PERMUTATION:
00858 value = permutation(TreePos->Child_One->Value.Number, TreePos->Child_Two->Value.Number);
00859 break;
00860 }
00861 TreePos->Type = MTK_NUMBER;
00862 TreePos->evalfn = func_details[MTK_NUMBER].func_ptr;
00863 TreePos->Value.Number = value;
00864 equation->Delete(TreePos->Child_One);
00865 TreePos->Child_One = NULL;
00866 equation->Delete(TreePos->Child_Two);
00867 TreePos->Child_Two = NULL;
00868 }
00869 break;
00870 default :
00871 if ( ( (TreePos->Type) >= MTK_LN ) && ( (TreePos->Type) <= MTK_FACTORIAL) ) {
00872 if (TreePos->Child_One->Type == MTK_NUMBER) {
00873 if ( equation->Radians || (TreePos->Type < MTK_SIN) || ( TreePos->Type > MTK_ARCTAN) ) {
00874 value = (*(TreePos->evalfn))(TreePos->Child_One->Value.Number);
00875 }
00876 else {
00877 if ( TreePos->Type <= MTK_COT )
00878 value = (*(TreePos->evalfn))(TreePos->Child_One->Value.Number*DEGTORAD);
00879 else
00880 value = (*(TreePos->evalfn))(TreePos->Child_One->Value.Number)/DEGTORAD;
00881 }
00882 TreePos->Type = MTK_NUMBER;
00883 TreePos->evalfn = func_details[MTK_NUMBER].func_ptr;
00884 TreePos->Value.Number = value;
00885 equation->Delete(TreePos->Child_One);
00886 TreePos->Child_One = NULL;
00887 }
00888 }
00889 };
00890
00891 TreePos->Brackets=1;
00892 }
00893
00894
00895 void
00896 Parser::TreeToText()
00897 {
00898 int Length;
00899 char *Buffer;
00900
00901 equation->Reset(0);
00902 Buffer = TreeToText(equation->Root);
00903
00904 Length=strlen(Buffer);
00905 if (EquationText)
00906 delete [] EquationText;
00907 EquationText=new char[Length+1];
00908 strcpy(EquationText,Buffer);
00909 delete [] Buffer;
00910 }
00911
00912
00913 char *
00914 Parser::TreeToText(Node *TreeRoot)
00915 {
00916 bool Flag=true;
00917 int length, extra;
00918 Node *TreePos;
00919 char *Buffer, *ch1, *ch2, *tempbuffer;
00920 Buffer = new char[1024];
00921 int BufferSize = 1023;
00922 TreePos = TreeRoot;
00923 Buffer[0] = 0;
00924
00925 while (Flag) {
00926 while (TreePos->Child_One != NULL){
00927 if (TreePos->Child_One->Brackets == 1) break;
00928 if ((TreePos->Type >= MTK_LN) && (TreePos->Type <= MTK_FRAC)) {
00929 NodeText(TreePos->Type,TreePos,Buffer, BufferSize);
00930 }
00931 if (TreePos->Type == MTK_BESSJ) {
00932 if (!TreePos->Child_One || !TreePos->Child_Two) {
00933 throw ERR_FUNCTION;
00934 }
00935 ch1 = TreeToText(TreePos->Child_One);
00936 ch2 = TreeToText(TreePos->Child_Two);
00937 length = strlen(ch1) + strlen(ch2) + 9;
00938 extra = BufferSize - strlen(Buffer);
00939 if (extra < length) {
00940 tempbuffer = Buffer;
00941 Buffer = new char[BufferSize + extra + 100];
00942 strcpy(Buffer, tempbuffer);
00943 delete tempbuffer;
00944 }
00945 strcat(Buffer,"( ");
00946 strcat(Buffer,ch1);
00947 strcat(Buffer," , ");
00948 strcat(Buffer,ch2);
00949 strcat(Buffer," ) ");
00950 delete ch1;
00951 delete ch2;
00952 TreePos->Brackets = 1;
00953 break;
00954 }
00955 else
00956 if ( Priority(TreePos->Child_One->Type, TreePos->Type) == false ) {
00957 NodeText(MTK_LBRACKET, NULL, Buffer, BufferSize);
00958 };
00959 TreePos=TreePos->Child_One;
00960 };
00961 if ((TreePos->Type<MTK_LN)||(TreePos->Type>MTK_FRAC)) {
00962 NodeText(TreePos->Type,TreePos,Buffer, BufferSize);
00963 }
00964 if ((TreePos->Child_Two == NULL) || (TreePos->Type == MTK_BESSJ)) {
00965 do {
00966 if (TreePos != TreeRoot) {
00967 if ((Priority(TreePos->Type, TreePos->Parent->Type) == false)
00968 && (TreePos->Child_One != NULL)){
00969 NodeText(MTK_RBRACKET, NULL, Buffer, BufferSize);
00970 }
00971 if (TreePos->Parent->Child_Two == TreePos) {
00972 if (((TreePos->Parent->Type == MTK_SUBTRACT)
00973 && ((TreePos->Type == MTK_ADD) || (TreePos->Type == MTK_SUBTRACT)))
00974 || ((TreePos->Parent->Type == MTK_DIVIDE)
00975 && ((TreePos->Type == MTK_MULTIPLY) || (TreePos->Type == MTK_DIVIDE)))) {
00976 NodeText(MTK_RBRACKET, NULL, Buffer, BufferSize);
00977 }
00978 }
00979 }
00980 if (TreePos == TreeRoot) {
00981 Flag = false;
00982 break;
00983 };
00984 TreePos=TreePos->Parent;
00985 }
00986 while (TreePos->Brackets==1);
00987 }
00988 else {
00989 if ((Priority(TreePos->Child_Two->Type,TreePos->Type)==false) ||
00990 ((TreePos->Type == MTK_SUBTRACT) && ((TreePos->Child_Two->Type == MTK_ADD) || (TreePos->Child_Two->Type == MTK_SUBTRACT))) ||
00991 ((TreePos->Type == MTK_DIVIDE) && ((TreePos->Child_Two->Type == MTK_MULTIPLY) || (TreePos->Child_Two->Type == MTK_DIVIDE))))
00992 NodeText(MTK_LBRACKET, NULL, Buffer, BufferSize);
00993 TreePos = TreePos->Child_Two;
00994 }
00995 }
00996 return Buffer;
00997 }
00998
00999
01000 void
01001 Parser::NodeText(int type, Node *TreePos,char *Buffer,int &BufferSize)
01002 {
01003 char Temp[30];
01004 char *tempbuffer;
01005 int extra;
01006 if ((type <1) || (type>MTK_NUMBER_OF_FUNCS)) {
01007 if (TreePos) TreePos->Brackets=1;
01008 throw ERR_FUNCTION;
01009 }
01010 if ( (type != MTK_NUMBER) && (type != MTK_VARIABLE) ) {
01011 if ( (type != MTK_MULTIPLY) ){
01012 extra = strlen(Buffer) + strlen(func_details[type].func_text) - BufferSize;
01013 if ( extra >= -1 ) {
01014 extra +=100;
01015 tempbuffer = Buffer;
01016 Buffer = new char[BufferSize + extra];
01017 strcpy(Buffer,tempbuffer);
01018 delete tempbuffer;
01019 }
01020 strcat(Buffer,func_details[type].func_text);
01021 }
01022 if (TreePos->Child_One)
01023 {
01024 if ( (TreePos->Child_One)->Type!=MTK_NUMBER ) {
01025 extra = strlen(Buffer) + strlen(func_details[type].func_text) - BufferSize;
01026 if ( extra >= -1 ) {
01027 extra +=100;
01028 tempbuffer = Buffer;
01029 Buffer = new char[BufferSize + extra];
01030 strcpy(Buffer,tempbuffer);
01031 delete tempbuffer;
01032 }
01033 strcat(Buffer,func_details[type].func_text);
01034 }
01035 }
01036 if (TreePos->Child_One)
01037 {
01038 if ((TreePos->Child_Two)->Type==MTK_NUMBER) {
01039 extra = strlen(Buffer) + strlen(func_details[type].func_text) - BufferSize;
01040 if ( extra >= -1 ) {
01041 extra +=100;
01042 tempbuffer = Buffer;
01043 Buffer = new char[BufferSize + extra];
01044 strcpy(Buffer,tempbuffer);
01045 delete tempbuffer;
01046 }
01047 strcat(Buffer,func_details[type].func_text);
01048 }
01049 }
01050 }
01051 else {
01052 if (type == MTK_NUMBER){
01053 sprintf(Temp,"%.15G",(TreePos->Value).Number);
01054 }
01055 else {
01056 sprintf(Temp,"%s",equation->Variables.at(TreePos->Value.WhichVar - 1)->Name);
01057 }
01058 extra = strlen(Buffer) + strlen(Temp) - BufferSize;
01059 if ( extra >= -1 ) {
01060 extra +=50;
01061 tempbuffer = Buffer;
01062 Buffer = new char[BufferSize + extra];
01063 strcpy(Buffer,tempbuffer);
01064 delete tempbuffer;
01065 }
01066 strcat(Buffer,Temp);
01067 }
01068
01069 if (TreePos) TreePos->Brackets=1;
01070 }
01071
01072
01073
01074
01075
01076
01077
01078
01079