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)
|
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;
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
10
lib/token.h
10
lib/token.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue