Refactoring: Reuse Token::expressionString() logic for finding right-most leaf in tree
This commit is contained in:
parent
16c62281d0
commit
58b21e3071
|
@ -135,16 +135,9 @@ const Token * astIsVariableComparison(const Token *tok, const std::string &comp,
|
|||
|
||||
const Token * nextAfterAstRightmostLeaf(const Token * tok)
|
||||
{
|
||||
const Token * rightmostLeaf = tok;
|
||||
if (!rightmostLeaf || !rightmostLeaf->astOperand1())
|
||||
if (!tok || !tok->astOperand1())
|
||||
return nullptr;
|
||||
do {
|
||||
if (rightmostLeaf->astOperand2())
|
||||
rightmostLeaf = rightmostLeaf->astOperand2();
|
||||
else
|
||||
rightmostLeaf = rightmostLeaf->astOperand1();
|
||||
} while (rightmostLeaf->astOperand1());
|
||||
return rightmostLeaf->next();
|
||||
return tok->findExpressionStartEndTokens().second->next();
|
||||
}
|
||||
|
||||
static const Token * getVariableInitExpression(const Variable * var)
|
||||
|
|
111
lib/token.cpp
111
lib/token.cpp
|
@ -1166,6 +1166,62 @@ void Token::astOperand2(Token *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
|
||||
{
|
||||
if (!Token::Match(this, "%cop%|++|--"))
|
||||
|
@ -1221,40 +1277,6 @@ bool Token::isUnaryPreOp() const
|
|||
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)
|
||||
{
|
||||
std::ostringstream ret;
|
||||
|
@ -1277,25 +1299,8 @@ static std::string stringFromTokenRange(const Token* start, const Token* end)
|
|||
|
||||
std::string Token::expressionString() 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 stringFromTokenRange(start, end);
|
||||
const auto tokens = findExpressionStartEndTokens();
|
||||
return stringFromTokenRange(tokens.first, tokens.second);
|
||||
}
|
||||
|
||||
static void astStringXml(const Token *tok, std::size_t indent, std::ostream &out)
|
||||
|
|
|
@ -1049,6 +1049,8 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::pair<const Token *, const Token *> findExpressionStartEndTokens() const;
|
||||
|
||||
/**
|
||||
* Is current token a calculation? Only true for operands.
|
||||
* For '*' and '&' tokens it is looked up if this is a
|
||||
|
|
Loading…
Reference in New Issue