inline Node2D* Eval2D(std::string & s){ std::string T; if(isdigit(s[0])){ T=GetNumber(s); if(s.size()>0){ if(IsOp(s[0])){ char Op=s[0]; s.erase(s.begin()); return new OperatorNode2D(T,s,Op); } } else return new Leaf2D(T); } else if(s[0]=='x'||s[0]=='y'){ if(s.size()==1) return new Leaf2D(s); else{ T+=s[0]; s.erase(s.begin()); char Op=s[0]; s.erase(s.begin()); return new OperatorNode2D(T,s,Op); } } else if(IsFunc(s[0])){ T=GetFunc(s); if(OnlyFunc(T+s)){return new FunctionNode2D(T);} else{ char op=s[0]; s.erase(s.begin()); return new OperatorNode2D(T,s,op); } } if(OnlyParenth(s)){ s.erase(s.begin()); s.pop_back(); return Eval2D(s); } T=GetParenth(s); char op=s[0]; s.erase(s.begin()); return new OperatorNode2D(T,s,op); }
TokenTypes CMathParser::NextToken()//{ Gets the next Token from the Input stream } { CSPString NumString;// : String[80]; WORD TLen, NumLen; //, FormLen, Place; // int Check ;//: Integer; char Ch;//, FirstChar; BOOL Decimal ; TokenTypes ResultNextToken; while ((Position < FInput.GetLength()) && (FInput.GetAt(Position) == ' ')) Position++; TokenLen = Position; if (Position >= FInput.GetLength()) { ResultNextToken = EOL; TokenLen = 0; return ResultNextToken; } FInput.MakeUpper(); Ch = FInput.GetAt(Position); if (Ch== '!') { ResultNextToken = ERR; TokenLen = 0; return ResultNextToken ; } if((Ch >= '0' && Ch <= '9') || Ch == '.')// if Ch in ['0'..'9', '.'] then { NumString = ""; TLen = Position; Decimal = FALSE; while ((TLen < FInput.GetLength()) && ((FInput.GetAt(TLen) >= '0' && FInput.GetAt(TLen) <= '9' ) || ((FInput.GetAt(TLen) == '.') && (!Decimal)))) { NumString = NumString + FInput.GetAt(TLen); if (Ch == '.')// then Decimal = TRUE; TLen++;//Inc(TLen); } if ((TLen == 2) && (Ch == '.'))// then { ResultNextToken = BAD; TokenLen = 0; return ResultNextToken ; } if ((TLen < FInput.GetLength()) && ((FInput.GetAt(TLen)) == 'E'))// then { NumString = NumString + 'E'; TLen++; if( FInput.GetAt(TLen) == '+' || FInput.GetAt(TLen) == '-')// in ['+', '-'] then { NumString.SetAt(TLen, FInput.GetAt(TLen));//= NumString + FInput[TLen]; TLen++; } NumLen = 1; while ((TLen < FInput.GetLength()) && (FInput.GetAt(TLen) >= '0' && FInput.GetAt(TLen) <= '9') && (NumLen <= MP_MaxExpLen)) { NumString = NumString + FInput.GetAt(TLen); NumLen++;//Inc(NumLen); TLen++;//Inc(TLen); } } if (NumString[0] == '.')// then NumString = '0' + NumString; CurrToken.Value = atof(NumString); //Val(NumString, CurrToken.Value, Check); /*//if (Check != 0 ) {// begin ErrorCode = MP_ErrMath; ErrorCode = ErrInvalidNum; Position += Pred(Check); //Inc(Position, Pred(Check)); }// end { if } else*/ {// begin ResultNextToken = NUM; Position += NumString.GetLength(); //Inc(Position, System.Length(NumString)); TokenLen = Position - TokenLen; }// end; { else } return ResultNextToken; }//end { if } else if ((Ch>='a' && Ch <= 'z') || (Ch>='A' && Ch <= 'Z'))//in Letters then {// begin if (IsFunc("ABS") || IsFunc("ATAN") || IsFunc("COS") || IsFunc("EXP") || IsFunc("LN") || IsFunc("ROUND") || IsFunc("SIN") || IsFunc("SQRT") || IsFunc("SQR") || IsFunc("TRUNC")|| IsFunc("NOT")||// then//EXPAND IsFunc("BOOL")|| IsFunc("SGN") ) { ResultNextToken = FUNC; TokenLen = Position - TokenLen; return ResultNextToken ; } if (IsFunc("MOD")) { ResultNextToken = MODU; TokenLen = Position - TokenLen; return ResultNextToken ; } if (IsVar(CurrToken.Value)) { ResultNextToken = NUM; TokenLen = Position - TokenLen; return ResultNextToken; } else { ResultNextToken = BAD; TokenLen = 0; return ResultNextToken ; } } else {// begin switch(Ch) { case '+' : ResultNextToken = PLUS; break; case '-' : ResultNextToken = MINUS; break; case '*' : ResultNextToken = TIMES; break; case '/' : ResultNextToken = DIVIDE; break; case '^' : ResultNextToken = EXPO; break; case '(' : ResultNextToken = OPAREN; break; case ')' : ResultNextToken = CPAREN; break; default: ResultNextToken = BAD; TokenLen = 0; return ResultNextToken ; }//end; { case } Position++; TokenLen = Position - TokenLen; return ResultNextToken ; }//end; { else if } }//end; { NextToken }
//----------------------------------------------------------------------------- // return values: 0 - OK, 1 - wrong arguments, 2 - wrong command, 3 - string too long, 4 -- unclosed string int mglParser::Parse(mglGraph *gr, std::wstring str, long pos) { if(Stop || gr->NeedStop()) return 0; curGr = gr->Self(); std::wstring arg[1024]; str=mgl_trim_ws(str); long n,k=0,m=0,mm=0,res; // try parse ':' -- several commands in line for(n=0;n<long(str.length());n++) { if(str[n]=='\'' && (n==0 || str[n-1]!='\\')) k++; if(k%2) continue; if(str[n]=='(') m++; if(str[n]==')') m--; if(str[n]=='{') mm++; if(str[n]=='}') mm--; if(str[n]=='#') break; if((str[n]==':' || str[n]=='\n') && k%2==0 && m==0 && mm==0) { res=Parse(gr,str.substr(0,n),pos); if(!res) res=Parse(gr,str.substr(n+1),pos); return res; } } if(k%2 || m || mm) return 4; // strings is not closed // define parameters or start cycle res = ParseDef(str); if(res) return res-1; // parse arguments (parameters $1, ..., $9) PutArg(str,false); str=mgl_trim_ws(str); std::wstring opt; for(k=0;k<1024;k++) // parse string to substrings (by spaces) { n = mglFindArg(str); if(n<1) // this is option { if(str[-n]==';') opt = str.substr(-n+1); if(n<0) str = str.substr(0,-n); break; } arg[k] = str.substr(0,n); str = mgl_trim_ws(str.substr(n+1)); } // try to find last argument if(str[0]!=0 && str[0]!='#' && str[0]!=';') { arg[k] = str; k++; } if(k<1) n =0; else { // fill arguments by its values mglArg *a = new mglArg[k]; FillArg(gr, k, arg, a); // execute first special (program-flow-control) commands if(!skip() && !arg[0].compare(L"stop")) { Stop = true; delete []a; return 0; } if(!arg[0].compare(L"func")) { Stop = true; delete []a; return 0; } n = FlowExec(gr, arg[0].c_str(),k-1,a); if(n) { delete []a; return n-1; } if(skip()) { delete []a; return 0; } if(!arg[0].compare(L"load")) { int n = a[0].type==1?0:1; a[0].s.assign(a[0].w.begin(),a[0].w.end()); if(!n) mgl_parser_load(this,a[0].s.c_str()); delete []a; return n; } if(!arg[0].compare(L"define")) { if(k==3) { DeleteVar(arg[1].c_str()); // force to delete variable with the same name mglNum *v=AddNum(arg[1].c_str()); if(arg[2][0]=='!') // complex number is added { HADT dd = mglFormulaCalcC(arg[2].substr(1),this, DataList); v->d=NAN; v->c = dd->a[0]; delete dd; } else { HMDT dd = mglFormulaCalc(arg[2],this, DataList); v->c = v->d = dd->a[0]; delete dd; } } delete []a; return k==3?0:1; } if(!arg[0].compare(L"rkstep")) { int res=1; if(k>2 && a[0].type==1 && a[1].type==1) { std::wstring a1 = arg[1], a2=arg[2]; res = 0; if(a1[0]=='\'') a1 = a1.substr(1,a1.length()-2); if(a2[0]=='\'') a2 = a2.substr(1,a2.length()-2); mgl_rk_step_w(this, a1.c_str(), a2.c_str(), (k>=3 && a[2].type==2)?a[2].v:1); } delete []a; return res; } if(!arg[0].compare(L"call")) { n = 1; if(a[0].type==1) { int na=0; a[0].s.assign(a[0].w.begin(),a[0].w.end()); n=-IsFunc(a[0].w.c_str(),&na); if(n && k!=na+2) { char buf[64]; snprintf(buf,64,"Bad arguments for %ls: %ld instead of %d\n", a[0].w.c_str(),k-2,na); buf[63]=0; gr->SetWarn(-1,buf); n = 1; } else if(n) { mglFnStack fn; fn.pos = pos; for(int i=0;i<10;i++) { fn.par[i] = par[i]; par[i]=L""; } for(int i=1;i<k-1;i++) AddParam(i,arg[i+1].c_str()); fn_stack.push_back(fn); n--; } else if(AllowFileIO) // disable external scripts if AllowFileIO=false { FILE *fp = fopen(a[0].s.c_str(),"rt"); if(fp) { register int i; mglParser *prs = new mglParser(AllowSetSize); prs->DataList.swap(DataList); prs->NumList.swap(NumList); prs->Cmd=Cmd; for(i=10;i<30;i++) prs->AddParam(i,par[i].c_str()); prs->Execute(gr,fp); for(i=10;i<30;i++) AddParam(i,prs->par[i].c_str()); DataList.swap(prs->DataList); NumList.swap(prs->NumList); prs->Cmd=0; delete prs; fclose(fp); } else n=1; } } delete []a; return n; } if(!arg[0].compare(L"for")) { n = 1; char ch = arg[1][0]; int r = ch-'0'; if(ch>='a' && ch<='z') r = 10+ch-'a'; // int r = int(a[0].v); if(arg[1][1]==0 && (r>=0 && r<40)) { if(a[1].type==0) { n=0; fval[r] = *(a[1].d); fval[r].nx *= fval[r].ny*fval[r].nz; } else if(a[1].type==2 && a[2].type==2 && a[2].v>a[1].v) { mreal step = a[3].type==2?a[3].v:1; mm = int(step>0 ? (a[2].v-a[1].v)/step : 0); if(mm>0) { n=0; fval[r].Create(mm+1); for(int ii=0;ii<mm+1;ii++) fval[r].a[ii] = a[1].v + step*ii; } } if(n==0) { for(int i=39;i>0;i--) { for_stack[i]=for_stack[i-1]; if_for[i]=if_for[i-1]; } for_stack[0] = r+1; fval[r].nz = pos; if_for[0]=if_pos; wchar_t buf[32]; mglprintf(buf,32,L"%g",fval[r].a[0]); AddParam(r, buf); fval[r].ny = 1; } } delete []a; return n; } // alocate new arrays and execute the command itself n = PreExec(gr, k, arg, a); if(n>0) n--; else if(!arg[0].compare(L"setsize") && !AllowSetSize) n = 2; else n = Exec(gr, arg[0].c_str(),k-1,a, arg[1].c_str(), opt.c_str()); delete []a; } // delete temporary data arrays for(size_t i=0;i<DataList.size();i++) if(DataList[i] && DataList[i]->temp) { mglDataA *u=DataList[i]; DataList[i]=0; delete u; } return n; }
void CRusSemStructure::BuildVerbLexFunctParameterForTheNodes (long SitNodeNo, long ParamNodeNo) { const CRusSemNode& SitNode = m_Nodes[SitNodeNo]; const CRusSemNode& ParamNode = m_Nodes[ParamNodeNo]; vector<CLexicalFunctionField>::const_iterator It = find(SitNode.m_LexFunctFields.begin(), SitNode.m_LexFunctFields.end(), ParamNode.m_Words[ParamNode.m_MainWordNo].m_Lemma); if (It == SitNode.m_LexFunctFields.end()) { // поищем среди эквивалентов const CRusSemWord& W = ParamNode.m_Words[ParamNode.m_MainWordNo]; for (long j=0; j < W.m_WordEquals.size(); j++) { It = find(SitNode.m_LexFunctFields.begin(), SitNode.m_LexFunctFields.end(), W.m_WordEquals[j]); if (It != SitNode.m_LexFunctFields.end()) break; } }; /* параметр может быть словосочетанием Например: IncepOper1 (ответственность) = взять_на_себя */ if (It == SitNode.m_LexFunctFields.end()) if (ParamNode.GetType() == CollocRoss) { // берем TITLЕ string UnitStr = GetRoss(CollocRoss)->GetEntryStr(ParamNode.GetInterp()->m_UnitNo); EngRusMakeUpper(UnitStr); It = find(SitNode.m_LexFunctFields.begin(), SitNode.m_LexFunctFields.end(), UnitStr); }; /* строим LF SO.Oper типа "постановка вопроса" */ bool bS0 = false; if (It == SitNode.m_LexFunctFields.end()) { // поищем среди V0 for (long j=0; j < ParamNode.m_VerbsOfS0.size(); j++) { It = find(SitNode.m_LexFunctFields.begin(), SitNode.m_LexFunctFields.end(), ParamNode.m_VerbsOfS0[j]); if (It != SitNode.m_LexFunctFields.end()) { bS0 = true; break; } } }; if (It == SitNode.m_LexFunctFields.end()) return; if ( !IsParameterOfVerb(It->m_LexFunct) && (It->m_LexFunct != "S0.Oper1") ) return; // если не совпало по номеру значения if (It->m_MeanNum != -1) if (ParamNode.GetInterp() != 0) if ( GetRoss(ParamNode.GetInterp()->m_DictType)->GetUnitMeanNum(ParamNode.GetInterp()->m_UnitNo) != It->m_MeanNum) return; /* Для Func надо проверить, что слово-ситуация имеет номинатив */ if (!bS0) if (IsFunc(It->m_LexFunct)) if ( !SitNode.HasOneGrammem (rNominativ) ) return; /* для Оперов загружаем вторую валентность, и проверям, что слово-ситуация подпадает под этот шаблон. Проверку не нужно делать, если мы имеем дело с S0.Oper Проверку не нужно делать, если мы строим межклаузную LF например: "реформы, проведенные в прошлом году" */ if (!bS0) if (ParamNode.m_ClauseNo == SitNode.m_ClauseNo) if (IsOper(It->m_LexFunct)) { long j=0; for (;j < ParamNode.m_NotProhibitedValSets.size(); j++) { CSemPattern P; if (ParamNode.m_NotProhibitedValSets[j].size() < 2) continue; GetActantPattern (ParamNodeNo, ParamNode.m_NotProhibitedValSets[j][1], P); string SyntacticRelation; CSynRealization SyntacticRealization; if (IsPattern (P, SitNodeNo, SyntacticRelation, SyntacticRealization) ) break; }; if (j == ParamNode.m_NotProhibitedValSets.size()) { if ( (It->m_Prep.m_UnitNo == ErrUnitNo) || !SitNode.HasThePrep(It->m_Prep.m_UnitNo) ) return; }; }; //ведем стрелку от слова ситуации в присвязочный глагол string LexFunctName = It->m_LexFunct; if (bS0) LexFunctName = "S0."+LexFunctName; m_LexFuncts.push_back (CLexFunctRel(SitNodeNo, ParamNodeNo, LexFunctName)); };
bool IsParameterOfVerb (const string& LexFunct) { return IsOper(LexFunct) || IsFunc(LexFunct); };