There is some language where the following are considered comments:
[str] // comment
[str] /* comment */ [str]
[str] # comment
[str] /* comment1 comment2 */ [str]
where [str]
is 0 or more occurrences of some string.
I'm reading a file line by line, and need to remove the comments from the whole file (the file is large so I cannot keep the whole content in memory).
I have written a method that receives each line, removes the comments from it, and returns the remaining string.
(Here s_bInComment
is a static variable in Parser
class with initial value of false
)
void Parser::removeComments(std::string &str)
{
// see if we're still in comment lines, i.e. not reached */
auto commentEnd = str.find("*/");
if (s_bInComment && commentEnd == std::string::npos)
{
str.clear();
return;
}
std::string result;
const auto iStrLen = str.length();
for (std::size_t idx = 0; idx < iStrLen; ++idx)
{
if (str[idx] == '/')
{
if (idx + 1 < iStrLen)
{
if (str[idx + 1] == '/')
{
// we found //
// take the part of the string before the comment, if any
str = str.substr(0, idx);
break;
}
if (str[idx + 1] == '*')
{
// see if */ is in the same line
commentEnd = str.find("*/");
if (commentEnd == std::string::npos)
{
// multiline comment
s_bInComment = true;
str = str.substr(0, idx);
}
else
{
// remove the comment
str = result + str.substr(commentEnd + 2);
// recurse on the remaining string
removeComments(str);
}
break;
}
}
}
else if (str[idx] == '*')
{
if (idx + 1 < iStrLen)
{
if (str[idx + 1] == '/')
{
// we have found */, comment ended
s_bInComment = false;
// take the part of the string after the comment, if any
str = str.substr(idx + 2);
// recurse on the remaining string
removeComments(str);
break;
}
}
}
else if (str[idx] == '#')
{
// if there's a text before #, it should be accumulated in result
str = result.size() ? result : std::string();
break;
}
else if (!s_bInComment)
result += str[idx];
}
}
I have tested my code with the following input lines:
a /* b */ c
a /* b */
a // b
a /* b c */
// a
a /* b */ c
# a
a # b
a /* a */ b /* b */ c
Please let me know if there's room for improvement in one or other part.