Make it possible to create AST, by using the --ast flag

This commit is contained in:
Daniel Marjamäki 2013-11-02 18:37:35 +01:00
parent 46b4a19bd3
commit bbdfd8b5c7
8 changed files with 59 additions and 11 deletions

View File

@ -125,6 +125,10 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
else if (std::strcmp(argv[i], "--debug-fp") == 0)
_settings->debugFalsePositive = true;
// Experimental AST handling
else if (std::strcmp(argv[i], "--ast") == 0)
_settings->ast = true;
// Inconclusive checking (still in testing phase)
else if (std::strcmp(argv[i], "--inconclusive") == 0)
_settings->inconclusive = true;

View File

@ -26,7 +26,7 @@
Settings::Settings()
: _terminate(false),
debug(false), debugwarnings(false), debugFalsePositive(false),
inconclusive(false), experimental(false),
ast(false), inconclusive(false), experimental(false),
_errorsOnly(false),
_inlineSuppressions(false),
_verbose(false),

View File

@ -62,6 +62,9 @@ public:
/** @brief Is --debug-fp given? */
bool debugFalsePositive;
/** @brief Experimental AST handling */
bool ast;
/** @brief Inconclusive checks */
bool inconclusive;

View File

@ -1166,13 +1166,30 @@ void Token::astHandleParentheses()
innerTop = innerTop->_astParent;
if (_astParent) {
if (_str == "(" && _astParent->_astOperand2 != NULL)
if (_astParent->_astOperand2 == this)
_astParent->_astOperand2 = innerTop;
else
else if (_astParent->_astOperand1 == this)
_astParent->_astOperand1 = innerTop;
innerTop->_astParent = _astParent;
} else {
_astParent = innerTop;
_astParent = NULL;
}
}
void Token::printAst() const
{
bool title = false;
bool print = true;
for (const Token *tok = this; tok; tok = tok->next()) {
if (print && tok->_astOperand1) {
if (!title)
std::cout << "\n\n##AST" << std::endl;
title = true;
std::cout << tok->astTop()->astString(" ") << std::endl;
print = false;
}
if (Token::Match(tok, "[;{}]"))
print = true;
}
}

View File

@ -671,14 +671,16 @@ public:
return ret;
}
std::string astString() const {
std::string astString(const char *sep = "") const {
std::string ret;
if (_astOperand1)
ret = _astOperand1->astString();
ret = _astOperand1->astString(sep);
if (_astOperand2)
ret += _astOperand2->astString();
return ret+_str;
ret += _astOperand2->astString(sep);
return ret + sep + _str;
}
void printAst() const;
};
/// @}

View File

@ -3645,6 +3645,12 @@ bool Tokenizer::simplifyTokenList()
tok->deleteNext();
}
// Experimental AST handling. Only for C code now since
// uninstantiated C++ templates are not handled well. Fix
// TestTokenize::asttemplate
if (_settings->ast && isC())
list.createAst();
if (_settings->terminated())
return false;
@ -3653,6 +3659,9 @@ bool Tokenizer::simplifyTokenList()
if (_settings->_verbose)
_symbolDatabase->printOut("Symbol database");
if (_settings->ast)
list.front()->printAst();
}
if (_settings->debugwarnings) {

View File

@ -392,7 +392,7 @@ void TokenList::createAst() const
while (tok->next())
tok = tok->next();
for (; tok; tok = tok->previous()) {
if ((!tok->previous() || tok->previous()->isOp()) &&
if (tok->isOp() && (!tok->previous() || tok->previous()->isOp() || tok->previous()->type() == Token::eOther) &&
op.find(" "+tok->str()+" ")!=std::string::npos) {
tok->astOperand1(tok->next());
}
@ -401,6 +401,13 @@ void TokenList::createAst() const
const std::string op(operators[i]);
for (Token *tok = _front; tok; tok = tok->next()) {
if (tok->astOperand1()==NULL && op.find(" "+tok->str()+" ")!=std::string::npos) {
// Don't create AST for "..."
if (tok->str() == "." && (tok->previous()->str() == "." || tok->next()->str() == "."))
continue;
if (Token::Match(tok, "* [)]]"))
continue;
if (tok->type() != Token::eIncDecOp) {
tok->astOperand1(tok->previous());
tok->astOperand2(tok->next());

View File

@ -9929,7 +9929,13 @@ private:
// Create AST..
tokenList.createAst();
return tokenList.front()->astTop()->astString();
for (const Token *tok = tokenList.front(); tok; tok = tok->next()) {
if (tok->astOperand1())
return tok->astTop()->astString();
}
// No AST found
return "";
}
void astexpr() const { // simple expressions with arithmetical ops