Esempio n. 1
0
        template <typename _IteratorT> static rule_base::pointer_type parse(_IteratorT& begin, _IteratorT& end){
          if (begin >= end) return rule_base::pointer_type(nullptr);
          _IteratorT oCurr = begin;

          parse_helper< _WhitespaceT, void, true, void>::parse(oCurr, end);

          rule_base::pointer_type oRet(nullptr);
          for (size_t i = 0; (i < (_len-1)) && (oCurr < end); ++i, ++oCurr){
            if (_str[i] != *oCurr){
              return rule_base::pointer_type(nullptr);
            }
          }

          /*
          Problem: The string comparison algorithms compare character by character and skip any leading or trailing whitespace between terminals.
            Rules 'ABC' + 'XYZ' maybe defined expecting the two terminals be separated by whitespace but this algorithm could parse the string 'ABCXYZ' as two separate terminals.
            There's a number of traditional approaches to solving this such as tokenizing before parsing or creating parse tables.
            A proper handling would compound the complexity of this library beyond it's intended scope, there are plenty of complex parsers around.
            Currently, the last character parsed is checked against the next character in the stream to see if they're of the same 'class' and fail if so.
            This isn't ideal because it maybe perfectly valid in some grammars to expect 'ABCXYZ' to appear in the input stream yet successfully parse into independent terminals.
            This library assumes contiguous alpha-numeric terminals constitute a single terminal so the input stream of 'ABCXYZ' will fail to parse without grammar definition trickery
          */
          if (oCurr < end && isalnum(*oCurr) && isalnum(_str[_len - 2])){
            return rule_base::pointer_type(nullptr);
          }
          parse_helper< _WhitespaceT, void, true, void>::parse(oCurr, end);

          begin = oCurr;
          return rule_base::pointer_type(new _DeclT);
        }
Esempio n. 2
0
tVecLong fromI32( void const *& pPtr, int aStride )
{
	hacdUINT32 const *pVal = reinterpret_cast< hacdUINT32 const * >( pPtr );
	tVecLong oRet( pVal[0], pVal[1], pVal[2] );
	pVal += aStride / 4;
	pPtr = pVal;
	return oRet;
}
Esempio n. 3
0
// C(t) = P0*(1-t)^3 + P1*3*t(1-t)^2 + 3*P2*t^2*(1-t) + P3*t^3
CCurve::TVec CCurveBezier3::Proc( float fP ) const
{
	const float fOneMinusT = 1.0f - fP;
	const float fOMTh2 = fOneMinusT * fOneMinusT;
	const float fPh2 = fP * fP;
	TVec oRet( m_aoVertex[0].m_oPos * fOMTh2 * fOneMinusT );
	oRet += m_aoVertex[1].m_oPos * ( 3.0f * fP * fOMTh2 );
	oRet += m_aoVertex[2].m_oPos * ( 3.0f * fPh2 * fOneMinusT );
	oRet += m_aoVertex[3].m_oPos * ( fPh2 * fP );
	return oRet;
}
Esempio n. 4
0
// dC(t)/dt = T(t) =
// -3*P0*(1 - t)^2 +
// P1*(3*(1 - t)^2 - 6*(1 - t)*t) +
// P2*(6*(1 - t)*t - 3*t^2) +
// 3*P3*t^2
CCurve::TVec CCurveBezier3::ProcTangent( float fP ) const
{
	const float fOneMinusT = 1.0f - fP;
	const float fOMTh2 = fOneMinusT * fOneMinusT;
	const float fPh2 = fP * fP;
	const float fTmp = 6.0f * fOneMinusT * fP;
	TVec oRet( m_aoVertex[0].m_oPos * -3.0f * fOMTh2 );
	oRet += m_aoVertex[1].m_oPos * ( 3.0f * fOMTh2 - fTmp );
	oRet += m_aoVertex[2].m_oPos * ( fTmp - 3.0f * fPh2 );
	oRet += m_aoVertex[3].m_oPos * ( 3.0f * fPh2 );
	return oRet;
}
Esempio n. 5
0
 static rule_base::pointer_type parse(_IteratorT& begin, _IteratorT& end) {
   if (begin >= end) return rule_base::pointer_type(nullptr);
   _IteratorT oCurr = begin;
   parse_helper<_WhitespaceT, void, true, void>::parse(oCurr, end);
   for (char c = _First; c <= _Last; ++c) {
     if (c == *oCurr) {
       rule_base::pointer_type oRet(new characters<_First, _Last>(*oCurr));
       ++oCurr;
       begin = oCurr;
       return oRet;
     }
   }
   return rule_base::pointer_type(nullptr);
 }
Esempio n. 6
0
        static rule_base::pointer_type parse(_IteratorT& begin, _IteratorT& end){
          if (begin >= end) return rule_base::pointer_type(nullptr);
          _IteratorT oCurr = begin;

          parse_helper< _WhitespaceT, void, true, void>::parse(oCurr, end);

          rule_base::pointer_type oRet(nullptr);
          for (size_t i = 0; (i < _len-1) && (oCurr < end); ++i, ++oCurr){
            if (tolower(_str[i]) != tolower(*oCurr)){
              return rule_base::pointer_type(nullptr);
            }
          }
          ///ensure there's an identifiable separation between terminals. this should be done differently
          if (oCurr < end && isalnum(*oCurr) && isalnum(_str[_len - 2])){
            return rule_base::pointer_type(nullptr);
          }

          parse_helper< _WhitespaceT, void, true, void>::parse(oCurr, end);

          begin = oCurr;
          return rule_base::pointer_type(new _DeclT);
        }