changed: the way of parsing operators in the mathematical parser
(the parser is not too much greedy now) git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@38 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
@@ -549,7 +549,7 @@ public:
|
||||
exp_offset.Sub( ss2.exponent );
|
||||
exp_offset.Abs();
|
||||
|
||||
// abs(this) will be >= abs(ss2)
|
||||
// (1) abs(this) will be >= abs(ss2)
|
||||
if( SmallerWithoutSignThan(ss2) )
|
||||
{
|
||||
Big<exp, man> temp(ss2);
|
||||
@@ -567,11 +567,12 @@ public:
|
||||
else
|
||||
if( exp_offset < mantissa_size_in_bits )
|
||||
{
|
||||
// moving 'exp_offset' times
|
||||
// (2) moving 'exp_offset' times
|
||||
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// (3)
|
||||
// exp_offset == mantissa_size_in_bits
|
||||
// we're rounding 'this' about one (up or down depending on a ss2 sign)
|
||||
ss2.mantissa.SetOne();
|
||||
@@ -590,11 +591,12 @@ public:
|
||||
else
|
||||
{
|
||||
// values have different signs
|
||||
if( mantissa.Sub(ss2.mantissa) )
|
||||
{
|
||||
mantissa.Rcl(1,1); // maybe without this rcl and subone()? !!!!
|
||||
c = exponent.SubOne();
|
||||
}
|
||||
// there shouldn't be a carry here because
|
||||
// (1) (2) and (3) guarantee that the mantissa of this
|
||||
// is greater than the mantissa of the ss2
|
||||
uint c_temp = mantissa.Sub(ss2.mantissa);
|
||||
|
||||
TTMATH_ASSERT( c_temp == 0 )
|
||||
}
|
||||
|
||||
c += Standardizing();
|
||||
|
@@ -1619,13 +1619,22 @@ void CreateMathematicalOperatorsTable()
|
||||
}
|
||||
|
||||
|
||||
bool CanBeMathematicalOperator(unsigned char c)
|
||||
{
|
||||
if( c=='|' || c=='&' || c=='!' || c=='=' || c=='<' || c=='>' ||
|
||||
c=='*' || c=='/' || c=='+' || c=='-' || c=='^' )
|
||||
return true;
|
||||
/*!
|
||||
returns true if 'str2' is the substring of str1
|
||||
|
||||
return false;
|
||||
e.g.
|
||||
true when str1="test" and str2="te"
|
||||
*/
|
||||
bool IsSubstring(const std::string & str1, const std::string & str2)
|
||||
{
|
||||
if( str2.length() > str1.length() )
|
||||
return false;
|
||||
|
||||
for(std::string::size_type i=0 ; i<str2.length() ; ++i)
|
||||
if( str1[i] != str2[i] )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1635,17 +1644,31 @@ return false;
|
||||
void ReadMathematicalOperator(Item & result)
|
||||
{
|
||||
std::string oper;
|
||||
typename OperatorsTable::iterator iter_old, iter_new;
|
||||
|
||||
for( ; CanBeMathematicalOperator(*pstring) ; ++pstring )
|
||||
iter_old = operators_table.end();
|
||||
|
||||
for( ; true ; ++pstring )
|
||||
{
|
||||
oper += *pstring;
|
||||
iter_new = operators_table.lower_bound(oper);
|
||||
|
||||
if( iter_new == operators_table.end() || !IsSubstring(iter_new->first, oper) )
|
||||
{
|
||||
oper.erase( --oper.end() ); // we've got mininum one element
|
||||
|
||||
typename OperatorsTable::iterator iter = operators_table.find(oper);
|
||||
|
||||
if( iter == operators_table.end() )
|
||||
Error( err_unknown_operator );
|
||||
|
||||
result.type = Item::mat_operator;
|
||||
result.moperator.SetType( iter->second );
|
||||
if( iter_old != operators_table.end() && iter_old->first == oper )
|
||||
{
|
||||
result.type = Item::mat_operator;
|
||||
result.moperator.SetType( iter_old->second );
|
||||
break;
|
||||
}
|
||||
|
||||
Error( err_unknown_operator );
|
||||
}
|
||||
|
||||
iter_old = iter_new;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1676,10 +1699,7 @@ int ReadOperator(Item & result)
|
||||
++pstring;
|
||||
}
|
||||
else
|
||||
if( CanBeMathematicalOperator(*pstring) )
|
||||
ReadMathematicalOperator(result);
|
||||
else
|
||||
Error( err_unknown_character );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -65,7 +65,7 @@
|
||||
#define TTMATH_MAJOR_VER 0
|
||||
#define TTMATH_MINOR_VER 8
|
||||
#define TTMATH_REVISION_VER 1
|
||||
#define TTMATH_PRERELEASE_VER 1
|
||||
#define TTMATH_PRERELEASE_VER 0
|
||||
|
||||
|
||||
/*!
|
||||
|
Reference in New Issue
Block a user