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);
}
Пример #2
0
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 }
Пример #3
0
//-----------------------------------------------------------------------------
// 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;
}
Пример #4
0
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));
};
Пример #5
0
bool			IsParameterOfVerb (const string& LexFunct) 
{
	  return	    IsOper(LexFunct) 
				|| IsFunc(LexFunct);
};