Skip to content

Commit

Permalink
Parsing tools: added ParseInteger function
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Jan 22, 2024
1 parent d86fa2d commit ee93886
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 17 deletions.
66 changes: 49 additions & 17 deletions Common/interface/ParsingTools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ inline bool IsDigit(Char Symbol) noexcept

/// Skips all characters until the end of the line.

/// \param[inout] Pos - starting position.
/// \param[in] End - end of the input string.
/// \param[in] GoToNextLine - whether to go to the next line.
/// \param[in] Start - starting position.
/// \param[in] End - end of the input string.
/// \param[in] GoToNextLine - whether to go to the next line.
///
/// \return If GoToNextLine is true, the position following the
/// new line character at the end of the string.
Expand Down Expand Up @@ -124,9 +124,9 @@ DEFINE_FLAG_ENUM_OPERATORS(SKIP_COMMENT_FLAGS)

/// Skips single-line and multi-line comments starting from the given position.

/// \param[inout] Start - starting position.
/// \param[in] End - end of the input string.
/// \param[in] Flags - flags controlling what kind of comments to skip.
/// \param[in] Start - starting position.
/// \param[in] End - end of the input string.
/// \param[in] Flags - flags controlling what kind of comments to skip.
///
/// \return if the comment is found, the position immediately following
/// the end of the comment; starting position otherwise.
Expand Down Expand Up @@ -211,9 +211,9 @@ InteratorType SkipComment(const InteratorType& Start, const InteratorType& End,

/// Skips all delimiters starting from the given position.

/// \param[inout] Pos - starting position.
/// \param[in] End - end of the input string.
/// \param[in] Delimiters - optional string containing custom delimiters.
/// \param[in] Start - starting position.
/// \param[in] End - end of the input string.
/// \param[in] Delimiters - optional string containing custom delimiters.
///
/// \return position of the first non-delimiter character.
template <typename InteratorType>
Expand All @@ -236,10 +236,10 @@ InteratorType SkipDelimiters(const InteratorType& Start, const InteratorType& En

/// Skips all comments and all delimiters starting from the given position.

/// \param[inout] Pos - starting position.
/// \param[in] End - end of the input string.
/// \param[in] Delimiters - optional string containing custom delimiters.
/// \param[in] CommentFlags - optional flags controlling what kind of comments to skip.
/// \param[in] Start - starting position.
/// \param[in] End - end of the input string.
/// \param[in] Delimiters - optional string containing custom delimiters.
/// \param[in] CommentFlags - optional flags controlling what kind of comments to skip.
///
/// \return true position of the first non-comment non-delimiter character.
///
Expand Down Expand Up @@ -270,8 +270,8 @@ IteratorType SkipDelimitersAndComments(const IteratorType& Start,

/// Skips one identifier starting from the given position.

/// \param[inout] Pos - starting position.
/// \param[in] End - end of the input string.
/// \param[in] Start - starting position.
/// \param[in] End - end of the input string.
///
/// \return position immediately following the last character of identifier.
template <typename IteratorType>
Expand All @@ -295,8 +295,8 @@ IteratorType SkipIdentifier(const IteratorType& Start, const IteratorType& End)

/// Skips a floating point number starting from the given position.

/// \param[inout] Pos - starting position.
/// \param[in] End - end of the input string.
/// \param[in] Start - starting position.
/// \param[in] End - end of the input string.
///
/// \return position immediately following the last character of the number.
template <typename IteratorType>
Expand Down Expand Up @@ -385,6 +385,38 @@ IteratorType SkipFloatNumber(const IteratorType& Start, const IteratorType& End)
return Pos;
}

/// Parses an integer starting from the given position.
///
/// \param[in] Start - starting position.
/// \param[in] End - end of the input string
/// \param[out] Value - parsed integer value.
/// \return position immediately following the last character of the number.
template <typename IteratorType, typename ValueType>
IteratorType ParseInteger(const IteratorType& Start, const IteratorType& End, ValueType& Value) noexcept
{
auto Pos = Start;
if (Pos == End)
return Pos;

const bool IsNegative = *Pos == '-';
if (*Pos == '+' || *Pos == '-')
++Pos;

if (Pos == End || !IsNum(*Pos))
return Start;

Value = 0;
while (Pos != End && IsNum(*Pos))
{
Value = Value * 10 + (*Pos - '0');
++Pos;
}

if (IsNegative)
Value = -Value;

return Pos;
}

/// Splits string into chunks separated by comments and delimiters.
///
Expand Down
34 changes: 34 additions & 0 deletions Tests/DiligentCoreTest/src/Common/ParsingToolsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1369,4 +1369,38 @@ TEST(Common_ParsingTools, RefinePreprocessorDirective)
TestRefine("# \t /* Comment*/ define", "define");
}


TEST(Common_ParsingTools, ParseInteger)
{
auto Test = [](const std::string Str, size_t RefPos, int RefValue) {
int Value = INT_MAX;
auto Pos = ParseInteger(Str.begin(), Str.end(), Value);
EXPECT_EQ(Pos, Str.begin() + RefPos);
EXPECT_EQ(Value, RefValue);
};

Test("", 0, INT_MAX);
Test(" ", 0, INT_MAX);
Test("+", 0, INT_MAX);
Test("-", 0, INT_MAX);
Test("x", 0, INT_MAX);
Test("abcd", 0, INT_MAX);
Test("+x", 0, INT_MAX);
Test("-y", 0, INT_MAX);
Test("x123", 0, INT_MAX);
Test("+0", 2, 0);
Test("-0", 2, 0);
Test("234", 3, 234);
Test("+468", 4, 468);
Test("-135", 4, -135);
Test("234x567", 3, 234);
Test("+468x087", 4, 468);
Test("-135x124", 4, -135);
for (int i = -100; i <= 100; ++i)
{
std::string Str = std::to_string(i);
Test(Str, Str.length(), i);
}
};

} // namespace

0 comments on commit ee93886

Please sign in to comment.