Refactor methods for identification of numeric literals. (#1514)

This commit is contained in:
amai2012 2018-12-10 12:10:26 +01:00 committed by GitHub
parent 2abb3aa263
commit 6924522475
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 78 deletions

View File

@ -644,35 +644,24 @@ bool MathLib::isDecimalFloat(const std::string &str)
if (str.empty()) if (str.empty())
return false; return false;
enum State { enum State {
START, BASE_PLUSMINUS, BASE_DIGITS1, LEADING_DECIMAL, TRAILING_DECIMAL, BASE_DIGITS2, E, MANTISSA_PLUSMINUS, MANTISSA_DIGITS, SUFFIX_F, SUFFIX_L START, BASE_DIGITS1, LEADING_DECIMAL, TRAILING_DECIMAL, BASE_DIGITS2, E, MANTISSA_PLUSMINUS, MANTISSA_DIGITS, SUFFIX_F, SUFFIX_L
} state = START; } state = START;
for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) { std::string::const_iterator it = str.begin();
if ('+' == *it || '-' == *it)
++it;
for (; it != str.end(); ++it) {
switch (state) { switch (state) {
case START: case START:
if (*it=='+' || *it=='-')
state=BASE_PLUSMINUS;
else if (*it=='.')
state=LEADING_DECIMAL;
else if (std::isdigit(static_cast<unsigned char>(*it)))
state=BASE_DIGITS1;
else
return false;
break;
case BASE_PLUSMINUS:
if (*it=='.') if (*it=='.')
state=LEADING_DECIMAL; state=LEADING_DECIMAL;
else if (std::isdigit(static_cast<unsigned char>(*it))) else if (std::isdigit(static_cast<unsigned char>(*it)))
state=BASE_DIGITS1; state=BASE_DIGITS1;
else if (*it=='e' || *it=='E')
state=E;
else else
return false; return false;
break; break;
case LEADING_DECIMAL: case LEADING_DECIMAL:
if (std::isdigit(static_cast<unsigned char>(*it))) if (std::isdigit(static_cast<unsigned char>(*it)))
state=BASE_DIGITS2; state=BASE_DIGITS2;
else if (*it=='e' || *it=='E')
state=E;
else else
return false; return false;
break; break;
@ -763,19 +752,16 @@ bool MathLib::isPositive(const std::string &str)
bool MathLib::isOct(const std::string& str) bool MathLib::isOct(const std::string& str)
{ {
enum Status { enum Status {
START, PLUSMINUS, OCTAL_PREFIX, DIGITS START, OCTAL_PREFIX, DIGITS
} state = START; } state = START;
for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) { if (str.empty())
return false;
std::string::const_iterator it = str.begin();
if ('+' == *it || '-' == *it)
++it;
for (; it != str.end(); ++it) {
switch (state) { switch (state) {
case START: case START:
if (*it == '+' || *it == '-')
state = PLUSMINUS;
else if (*it == '0')
state = OCTAL_PREFIX;
else
return false;
break;
case PLUSMINUS:
if (*it == '0') if (*it == '0')
state = OCTAL_PREFIX; state = OCTAL_PREFIX;
else else
@ -801,45 +787,41 @@ bool MathLib::isOct(const std::string& str)
bool MathLib::isIntHex(const std::string& str) bool MathLib::isIntHex(const std::string& str)
{ {
enum Status { enum Status {
START, PLUSMINUS, HEX_PREFIX, DIGIT, DIGITS START, HEX_0, HEX_X, DIGIT
} state = START; } state = START;
for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) { if (str.empty())
return false;
std::string::const_iterator it = str.begin();
if ('+' == *it || '-' == *it)
++it;
for (; it != str.end(); ++it) {
switch (state) { switch (state) {
case START: case START:
if (*it == '+' || *it == '-')
state = PLUSMINUS;
else if (*it == '0')
state = HEX_PREFIX;
else
return false;
break;
case PLUSMINUS:
if (*it == '0') if (*it == '0')
state = HEX_PREFIX; state = HEX_0;
else else
return false; return false;
break; break;
case HEX_PREFIX: case HEX_0:
if (*it == 'x' || *it == 'X') if (*it == 'x' || *it == 'X')
state = HEX_X;
else
return false;
break;
case HEX_X:
if (isxdigit(static_cast<unsigned char>(*it)))
state = DIGIT; state = DIGIT;
else else
return false; return false;
break;
case DIGIT: case DIGIT:
if (isxdigit(static_cast<unsigned char>(*it))) if (isxdigit(static_cast<unsigned char>(*it)))
state = DIGITS; ; // state = DIGITS;
else
return false;
break;
case DIGITS:
if (isxdigit(static_cast<unsigned char>(*it)))
state = DIGITS;
else else
return isValidIntegerSuffix(it,str.end()); return isValidIntegerSuffix(it,str.end());
break; break;
} }
} }
return state == DIGITS; return DIGIT==state;
} }
bool MathLib::isFloatHex(const std::string& str) bool MathLib::isFloatHex(const std::string& str)
@ -847,7 +829,12 @@ bool MathLib::isFloatHex(const std::string& str)
enum Status { enum Status {
START, HEX_0, HEX_X, WHOLE_NUMBER_DIGIT, POINT, FRACTION, EXPONENT_P, EXPONENT_SIGN, EXPONENT_DIGITS, EXPONENT_SUFFIX START, HEX_0, HEX_X, WHOLE_NUMBER_DIGIT, POINT, FRACTION, EXPONENT_P, EXPONENT_SIGN, EXPONENT_DIGITS, EXPONENT_SUFFIX
} state = START; } state = START;
for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) { if (str.empty())
return false;
std::string::const_iterator it = str.begin();
if ('+' == *it || '-' == *it)
++it;
for (; it != str.end(); ++it) {
switch (state) { switch (state) {
case START: case START:
if (*it == '0') if (*it == '0')
@ -1018,63 +1005,57 @@ bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string::
bool MathLib::isBin(const std::string& str) bool MathLib::isBin(const std::string& str)
{ {
enum Status { enum Status {
START, PLUSMINUS, GNU_BIN_PREFIX, DIGIT, DIGITS START, GNU_BIN_PREFIX_0, GNU_BIN_PREFIX_B, DIGIT
} state = START; } state = START;
for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) { if (str.empty())
return false;
std::string::const_iterator it = str.begin();
if ('+' == *it || '-' == *it)
++it;
for (; it != str.end(); ++it) {
switch (state) { switch (state) {
case START: case START:
if (*it == '+' || *it == '-')
state = PLUSMINUS;
else if (*it == '0')
state = GNU_BIN_PREFIX;
else
return false;
break;
case PLUSMINUS:
if (*it == '0') if (*it == '0')
state = GNU_BIN_PREFIX; state = GNU_BIN_PREFIX_0;
else else
return false; return false;
break; break;
case GNU_BIN_PREFIX: case GNU_BIN_PREFIX_0:
if (*it == 'b' || *it == 'B') if (*it == 'b' || *it == 'B')
state = GNU_BIN_PREFIX_B;
else
return false;
break;
case GNU_BIN_PREFIX_B:
if (*it == '0' || *it == '1')
state = DIGIT; state = DIGIT;
else else
return false; return false;
break; break;
case DIGIT: case DIGIT:
if (*it == '0' || *it == '1') if (*it == '0' || *it == '1')
state = DIGITS; ; // state = DIGIT;
else
return false;
break;
case DIGITS:
if (*it == '0' || *it == '1')
state = DIGITS;
else else
return isValidIntegerSuffix(it,str.end()); return isValidIntegerSuffix(it,str.end());
break; break;
} }
} }
return state == DIGITS; return state == DIGIT;
} }
bool MathLib::isDec(const std::string & str) bool MathLib::isDec(const std::string & str)
{ {
enum Status { enum Status {
START, PLUSMINUS, DIGIT START, DIGIT
} state = START; } state = START;
for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) { if (str.empty())
return false;
std::string::const_iterator it = str.begin();
if ('+' == *it || '-' == *it)
++it;
for (; it != str.end(); ++it) {
switch (state) { switch (state) {
case START: case START:
if (*it == '+' || *it == '-')
state = PLUSMINUS;
else if (isdigit(static_cast<unsigned char>(*it)))
state = DIGIT;
else
return false;
break;
case PLUSMINUS:
if (isdigit(static_cast<unsigned char>(*it))) if (isdigit(static_cast<unsigned char>(*it)))
state = DIGIT; state = DIGIT;
else else

View File

@ -800,6 +800,7 @@ private:
ASSERT_EQUALS(false, MathLib::isDecimalFloat(".")); ASSERT_EQUALS(false, MathLib::isDecimalFloat("."));
ASSERT_EQUALS(false, MathLib::isDecimalFloat("...")); ASSERT_EQUALS(false, MathLib::isDecimalFloat("..."));
ASSERT_EQUALS(false, MathLib::isDecimalFloat(".e")); ASSERT_EQUALS(false, MathLib::isDecimalFloat(".e"));
ASSERT_EQUALS(false, MathLib::isDecimalFloat(".e2"));
ASSERT_EQUALS(false, MathLib::isDecimalFloat(".E")); ASSERT_EQUALS(false, MathLib::isDecimalFloat(".E"));
ASSERT_EQUALS(false, MathLib::isDecimalFloat("+E.")); ASSERT_EQUALS(false, MathLib::isDecimalFloat("+E."));
ASSERT_EQUALS(false, MathLib::isDecimalFloat("+e.")); ASSERT_EQUALS(false, MathLib::isDecimalFloat("+e."));
@ -932,6 +933,7 @@ private:
ASSERT_EQUALS(false, MathLib::isDec("-x")); ASSERT_EQUALS(false, MathLib::isDec("-x"));
ASSERT_EQUALS(false, MathLib::isDec("+x")); ASSERT_EQUALS(false, MathLib::isDec("+x"));
ASSERT_EQUALS(false, MathLib::isDec("x")); ASSERT_EQUALS(false, MathLib::isDec("x"));
ASSERT_EQUALS(false, MathLib::isDec(""));
} }
void isNullValue() const { void isNullValue() const {