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) else if (std::strcmp(argv[i], "--debug-fp") == 0)
_settings->debugFalsePositive = true; _settings->debugFalsePositive = true;
// Experimental AST handling
else if (std::strcmp(argv[i], "--ast") == 0)
_settings->ast = true;
// Inconclusive checking (still in testing phase) // Inconclusive checking (still in testing phase)
else if (std::strcmp(argv[i], "--inconclusive") == 0) else if (std::strcmp(argv[i], "--inconclusive") == 0)
_settings->inconclusive = true; _settings->inconclusive = true;

View File

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

View File

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

View File

@ -1166,13 +1166,30 @@ void Token::astHandleParentheses()
innerTop = innerTop->_astParent; innerTop = innerTop->_astParent;
if (_astParent) { if (_astParent) {
if (_str == "(" && _astParent->_astOperand2 != NULL) if (_astParent->_astOperand2 == this)
_astParent->_astOperand2 = innerTop; _astParent->_astOperand2 = innerTop;
else else if (_astParent->_astOperand1 == this)
_astParent->_astOperand1 = innerTop; _astParent->_astOperand1 = innerTop;
innerTop->_astParent = _astParent; innerTop->_astParent = _astParent;
} else { _astParent = NULL;
_astParent = innerTop;
} }
} }
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; return ret;
} }
std::string astString() const { std::string astString(const char *sep = "") const {
std::string ret; std::string ret;
if (_astOperand1) if (_astOperand1)
ret = _astOperand1->astString(); ret = _astOperand1->astString(sep);
if (_astOperand2) if (_astOperand2)
ret += _astOperand2->astString(); ret += _astOperand2->astString(sep);
return ret+_str; return ret + sep + _str;
} }
void printAst() const;
}; };
/// @} /// @}

View File

@ -3645,6 +3645,12 @@ bool Tokenizer::simplifyTokenList()
tok->deleteNext(); 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()) if (_settings->terminated())
return false; return false;
@ -3653,6 +3659,9 @@ bool Tokenizer::simplifyTokenList()
if (_settings->_verbose) if (_settings->_verbose)
_symbolDatabase->printOut("Symbol database"); _symbolDatabase->printOut("Symbol database");
if (_settings->ast)
list.front()->printAst();
} }
if (_settings->debugwarnings) { if (_settings->debugwarnings) {

View File

@ -392,7 +392,7 @@ void TokenList::createAst() const
while (tok->next()) while (tok->next())
tok = tok->next(); tok = tok->next();
for (; tok; tok = tok->previous()) { 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) { op.find(" "+tok->str()+" ")!=std::string::npos) {
tok->astOperand1(tok->next()); tok->astOperand1(tok->next());
} }
@ -401,6 +401,13 @@ void TokenList::createAst() const
const std::string op(operators[i]); const std::string op(operators[i]);
for (Token *tok = _front; tok; tok = tok->next()) { for (Token *tok = _front; tok; tok = tok->next()) {
if (tok->astOperand1()==NULL && op.find(" "+tok->str()+" ")!=std::string::npos) { 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) { if (tok->type() != Token::eIncDecOp) {
tok->astOperand1(tok->previous()); tok->astOperand1(tok->previous());
tok->astOperand2(tok->next()); tok->astOperand2(tok->next());

View File

@ -9929,7 +9929,13 @@ private:
// Create AST.. // Create AST..
tokenList.createAst(); 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 void astexpr() const { // simple expressions with arithmetical ops