int CMPolynomial::get_to_stop_symbol(const wchar_t* rsymbols,wchar_t*& ps,CMString& str) { int ret = -1; int count = 1; str.resize(0); while (TRUE) { if (count==1 && wcschr(rsymbols,*ps)) count--; // if (count==1 && *ps==rsymbol) count--; else if (*ps==L'(' || *ps==L'[' || *ps==L'{') count++; else if (*ps==L')' || *ps==L']' || *ps==L'}') count--; if (!count) { ps++; break; } str.append(*ps++); } if (count) { switch (*rsymbols) { case L',': ret = XMissingComma; break; case L']': ret = XMissingRBracket; break; default: ret = XMissingRPar; break; } } return ret; }
int CMPolynomial::translate_next_token(wchar_t*& ptr, int& tok, CMString& str, int& n, CMVSmallArray<CMString>& args) { int i; int err=-1; str.resize(0); args.Reset(0); if (!skipwhite(ptr)) { tok = NoToken; return -1; } if (isnumber(*ptr)) { while (isnumber(*ptr)) str.append(*ptr++); tok = Constant; return -1; } // check to see if item is #IF if (!_wcsnicmp(ptr,L"@IF",3)) { n=1; args.AddAt(0,CMString()); tok = If; ptr += 3; skipwhite(ptr); int symb = *ptr++; if (!(symb==L'(' || symb==L'{')) return XMissingLPar; if (get_to_stop_symbol(L")}",ptr,args[0])>=0) return XIllegalCondition; skipwhite(ptr); if (!_wcsnicmp(ptr, L"@THEN", 5)) { ptr+=5; skipwhite(ptr); } symb = *ptr++; args.AddAt(1,CMString()); n=2; if (!(symb==L'(' || symb==L'{')) return XIllegalCondition; if (get_to_stop_symbol(L"})",ptr,args[1])>=0) return XIllegalCondition; skipwhite(ptr); if (!_wcsnicmp(ptr, L"@ELSE", 5)) { n=3; args.AddAt(2,CMString()); ptr+=5; skipwhite(ptr); symb = *ptr++; if (!(symb==L'(' || symb==L'{')) return XIllegalCondition; if (get_to_stop_symbol(L"})",ptr,args[2])>=0) return XIllegalCondition; } return -1; } // check to see if item is a bad operation for (i = 0; badops[i] != NULL; i++) { if (!wcsncmp(ptr, badops[i], wcslen(badops[i]))) return XUnrecognizedOperator; } // check to see if item is an operation for (i=0;ops[i]!=NULL;i++) { if (!wcsncmp(ptr, ops[i], wcslen(ops[i]))) { tok = FirstOp+i; if ((tok==LPar) || (tok==LBracket)) index++; else if ((tok==RPar) || (tok==RBracket)) index--; ptr += wcslen(ops[i]); return -1; } } // not a number or operation, so must be a special function,function or variable // first check to see if first symbol is allowed if (!(iswalpha(*ptr) || *ptr == L'_')) return XUndefinedSymbol; // check to see if this is a definition /* Definitions are now incorporated into variables const wchar_t* defname; sdebug << ptr << ENDL; for (i=0;(defname=CMDefinitions::GetDefinitionName(i))!=0;i++) { len = wcslen(defname); sdebug << L" " << defname << L" " << len << ENDL; if (_wcsnicmp(defname, ptr, len)==0) { sdebug << L"FOUND " << defname << ENDL; // if it is in the list of definitions and the next symbol is not // a letter or '_' (implying a variable name that happens to begin // with the same letters as a special symbol), then add the 'special' // token to the CMString. if (!(iswalnum(*(ptr+len))) && *(ptr+len) != L'_') { tok = Definition; n = i; ptr += len; return -1; } break; } } */ // check to see if item is a special function for (i=0;special_funcs[i]!=NULL;i++) { if (!wcsncmp(ptr, special_funcs[i], wcslen(special_funcs[i]))) { tok = FirstSpecialFunc+i; ptr += wcslen(special_funcs[i]); skipwhite(ptr); if (*ptr++ != L'(') return XMissingArgument; CMString arglist; if (get_to_stop_symbol(L")",ptr,arglist)>=0) return XBadArgumentList; arglist += L','; wchar_t* argptr = (wchar_t*)arglist.c_str(); for (n=0;*argptr && err<0;n++) { args.AddAt(n,CMString()); if (get_to_stop_symbol(L",:",argptr,args[n])>=0) err = XBadArgumentList; } return err; } } // check to see if it is a function const wchar_t* func; if ((func=CMFunction::FindFunction(ptr))!=0) { tok = Function; str = func; ptr += wcslen(func); skipwhite(ptr); if (*ptr++ != L'(') return XMissingArgument; CMString arglist; if (get_to_stop_symbol(L")",ptr,arglist)>=0) return XBadArgumentList; arglist += L','; wchar_t* argptr = (wchar_t*)arglist.c_str(); for (n=0;*argptr && err<0;n++) { args.AddAt(n,CMString()); if (get_to_stop_symbol(L",:",argptr,args[n])>=0) err = XBadArgumentList; } return err; } // Not a number, operation, or pre-defined function // so must be a variable while (iswalnum(*ptr) || (*ptr == L'_') || (*ptr == L'@') || (*ptr == L'.') ) str.append(*ptr++); CMString indexstr; n = 0; tok = Variable; while (skipwhite(ptr) && err<0) { if (*ptr == L'~') { tok = VariableOrig; ptr++; } if (*ptr == L'[') { args.AddAt(n,CMString()); if (n < 4) err = get_to_stop_symbol(L"]",++ptr,args[n++]); else err = XTooManyIndexes; } else break; } return err; }