Make it possible to create AST, by using the --ast flag
This commit is contained in:
parent
46b4a19bd3
commit
bbdfd8b5c7
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -62,6 +62,9 @@ public:
|
|||
/** @brief Is --debug-fp given? */
|
||||
bool debugFalsePositive;
|
||||
|
||||
/** @brief Experimental AST handling */
|
||||
bool ast;
|
||||
|
||||
/** @brief Inconclusive checks */
|
||||
bool inconclusive;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
10
lib/token.h
10
lib/token.h
|
@ -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;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue