tokenizer: simplify '?:' better when the condition is always true

This commit is contained in:
Daniel Marjamäki 2009-07-23 10:12:02 +02:00
parent 9b2dd8c7eb
commit 024778d6eb
2 changed files with 37 additions and 14 deletions

View File

@ -1938,13 +1938,11 @@ bool Tokenizer::simplifyQuestionMark()
!Token::Match(tok->previous(), "%num%")) !Token::Match(tok->previous(), "%num%"))
continue; continue;
if (tok->previous()->str() == "false" || // Find the ":" token..
tok->previous()->str() == "0") Token *semicolon = 0;
{ {
// Use code after semicolon, remove code before it.
const Token *end = 0;
unsigned int parlevel = 0; unsigned int parlevel = 0;
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) for (Token *tok2 = tok; tok2; tok2 = tok2->next())
{ {
if (tok2->str() == "(") if (tok2->str() == "(")
++parlevel; ++parlevel;
@ -1956,17 +1954,21 @@ bool Tokenizer::simplifyQuestionMark()
} }
else if (parlevel == 0 && tok2->str() == ":") else if (parlevel == 0 && tok2->str() == ":")
{ {
end = tok2; semicolon = tok2;
break; break;
} }
} }
}
if (!semicolon || !semicolon->next())
continue;
if (!end || !end->next()) if (tok->previous()->str() == "false" ||
continue; tok->previous()->str() == "0")
{
end = end->next(); // Use code after semicolon, remove code before it.
semicolon = semicolon->next();
tok = tok->tokAt(-2); tok = tok->tokAt(-2);
while (tok->next() != end) while (tok->next() != semicolon)
{ {
tok->deleteNext(); tok->deleteNext();
} }
@ -1974,9 +1976,18 @@ bool Tokenizer::simplifyQuestionMark()
tok = tok->next(); tok = tok->next();
ret = true; ret = true;
} }
else
// The condition is true. Delete the operator after the ":"..
else if (Token::Match(semicolon, ": %num%") || Token::Match(semicolon, ": %var% [);]"))
{ {
/** @todo simplify "(true ? x : y)" to "(x)" */ // delete the condition token and the "?"
tok = tok->tokAt(-2);
tok->deleteNext();
tok->deleteNext();
// delete the ":" token and the token after it..
semicolon->deleteThis();
semicolon->deleteThis();
} }
} }

View File

@ -1090,7 +1090,19 @@ private:
{ {
const char code[] = "(1?(false?1:2):3)"; const char code[] = "(1?(false?1:2):3)";
TODO_ASSERT_EQUALS("( 2 )", tok(code)); ASSERT_EQUALS("( 2 )", tok(code));
}
{
const char code[] = "( true ? a ( ) : b ( ) )";
ASSERT_EQUALS(code, tok(code));
TODO_ASSERT_EQUALS("( a ( ) )", tok(code));
}
{
const char code[] = "( true ? abc . a : abc . b )";
ASSERT_EQUALS(code, tok(code));
TODO_ASSERT_EQUALS("( abc . a )", tok(code));
} }
} }
}; };