Refactoring: Reuse Token::expressionString() logic for finding right-most leaf in tree

This commit is contained in:
Daniel Marjamäki 2018-10-18 12:09:55 +02:00
parent 16c62281d0
commit 58b21e3071
3 changed files with 62 additions and 62 deletions

View File

@ -135,16 +135,9 @@ const Token * astIsVariableComparison(const Token *tok, const std::string &comp,
const Token * nextAfterAstRightmostLeaf(const Token * tok) const Token * nextAfterAstRightmostLeaf(const Token * tok)
{ {
const Token * rightmostLeaf = tok; if (!tok || !tok->astOperand1())
if (!rightmostLeaf || !rightmostLeaf->astOperand1())
return nullptr; return nullptr;
do { return tok->findExpressionStartEndTokens().second->next();
if (rightmostLeaf->astOperand2())
rightmostLeaf = rightmostLeaf->astOperand2();
else
rightmostLeaf = rightmostLeaf->astOperand1();
} while (rightmostLeaf->astOperand1());
return rightmostLeaf->next();
} }
static const Token * getVariableInitExpression(const Variable * var) static const Token * getVariableInitExpression(const Variable * var)

View File

@ -1166,6 +1166,62 @@ void Token::astOperand2(Token *tok)
mAstOperand2 = tok; mAstOperand2 = tok;
} }
static const Token* goToLeftParenthesis(const Token* start, const Token* end)
{
// move start to lpar in such expression: '(*it).x'
int par = 0;
for (const Token *tok = start; tok && tok != end; tok = tok->next()) {
if (tok->str() == "(")
++par;
else if (tok->str() == ")") {
if (par == 0)
start = tok->link();
else
--par;
}
}
return start;
}
static const Token* goToRightParenthesis(const Token* start, const Token* end)
{
// move end to rpar in such expression: '2>(x+1)'
int par = 0;
for (const Token *tok = end; tok && tok != start; tok = tok->previous()) {
if (tok->str() == ")")
++par;
else if (tok->str() == "(") {
if (par == 0)
end = tok->link();
else
--par;
}
}
return end;
}
std::pair<const Token *, const Token *> Token::findExpressionStartEndTokens() const
{
const Token * const top = this;
const Token *start = top;
while (start->astOperand1() &&
(start->astOperand2() || !start->isUnaryPreOp() || Token::simpleMatch(start, "( )") || start->str() == "{"))
start = start->astOperand1();
const Token *end = top;
while (end->astOperand1() && (end->astOperand2() || end->isUnaryPreOp())) {
if (Token::Match(end,"(|[") &&
!(Token::Match(end, "( %type%") && !end->astOperand2())) {
end = end->link();
break;
}
end = end->astOperand2() ? end->astOperand2() : end->astOperand1();
}
start = goToLeftParenthesis(start, end);
end = goToRightParenthesis(start, end);
return std::pair<const Token *, const Token *>(start,end);
}
bool Token::isCalculation() const bool Token::isCalculation() const
{ {
if (!Token::Match(this, "%cop%|++|--")) if (!Token::Match(this, "%cop%|++|--"))
@ -1221,40 +1277,6 @@ bool Token::isUnaryPreOp() const
return false; // <- guess return false; // <- guess
} }
static const Token* goToLeftParenthesis(const Token* start, const Token* end)
{
// move start to lpar in such expression: '(*it).x'
int par = 0;
for (const Token *tok = start; tok && tok != end; tok = tok->next()) {
if (tok->str() == "(")
++par;
else if (tok->str() == ")") {
if (par == 0)
start = tok->link();
else
--par;
}
}
return start;
}
static const Token* goToRightParenthesis(const Token* start, const Token* end)
{
// move end to rpar in such expression: '2>(x+1)'
int par = 0;
for (const Token *tok = end; tok && tok != start; tok = tok->previous()) {
if (tok->str() == ")")
++par;
else if (tok->str() == "(") {
if (par == 0)
end = tok->link();
else
--par;
}
}
return end;
}
static std::string stringFromTokenRange(const Token* start, const Token* end) static std::string stringFromTokenRange(const Token* start, const Token* end)
{ {
std::ostringstream ret; std::ostringstream ret;
@ -1277,25 +1299,8 @@ static std::string stringFromTokenRange(const Token* start, const Token* end)
std::string Token::expressionString() const std::string Token::expressionString() const
{ {
const Token * const top = this; const auto tokens = findExpressionStartEndTokens();
const Token *start = top; return stringFromTokenRange(tokens.first, tokens.second);
while (start->astOperand1() &&
(start->astOperand2() || !start->isUnaryPreOp() || Token::simpleMatch(start, "( )") || start->str() == "{"))
start = start->astOperand1();
const Token *end = top;
while (end->astOperand1() && (end->astOperand2() || end->isUnaryPreOp())) {
if (Token::Match(end,"(|[") &&
!(Token::Match(end, "( %type%") && !end->astOperand2())) {
end = end->link();
break;
}
end = end->astOperand2() ? end->astOperand2() : end->astOperand1();
}
start = goToLeftParenthesis(start, end);
end = goToRightParenthesis(start, end);
return stringFromTokenRange(start, end);
} }
static void astStringXml(const Token *tok, std::size_t indent, std::ostream &out) static void astStringXml(const Token *tok, std::size_t indent, std::ostream &out)

View File

@ -1049,6 +1049,8 @@ public:
return ret; return ret;
} }
std::pair<const Token *, const Token *> findExpressionStartEndTokens() const;
/** /**
* Is current token a calculation? Only true for operands. * Is current token a calculation? Only true for operands.
* For '*' and '&' tokens it is looked up if this is a * For '*' and '&' tokens it is looked up if this is a