AST: Improved handling of unary operators

This commit is contained in:
Daniel Marjamäki 2012-12-16 08:41:04 +01:00
parent 6732f05b95
commit 1ad9c933ec
3 changed files with 37 additions and 10 deletions

View File

@ -1051,16 +1051,27 @@ std::string Token::stringifyList(bool varid) const
void Token::astOperand1(Token *tok)
{
// unary operand -> goto parent operator
while (tok->_astParent && !tok->_astParent->_astOperand2)
tok = tok->_astParent;
// there is a parent.. relink
if (tok->_astParent) {
tok->_astParent->_astOperand2 = this;
_astParent = tok->_astParent;
}
tok->_astParent = this;
_astOperand1 = tok;
}
void Token::astOperand2(Token *tok)
{
// unary operand -> goto parent operator
while (tok->_astParent && !tok->_astParent->_astOperand2)
tok = tok->_astParent;
// there is a parent.. relink
if (tok->_astParent) {
tok->_astParent->_astOperand1 = this;
_astParent = tok->_astParent;
@ -1076,7 +1087,7 @@ void Token::astHandleParenthesis()
innerTop = innerTop->_astParent;
if (_astParent) {
if (_str == "(")
if (_str == "(" && _astParent->_astOperand2 != NULL)
_astParent->_astOperand2 = innerTop;
else
_astParent->_astOperand1 = innerTop;

View File

@ -360,7 +360,7 @@ void TokenList::createAst()
for (unsigned int i = 0; i < sizeof(operators) / sizeof(*operators); ++i) {
// TODO: extract operators to std::set - that should be faster
if (*operators[i] == '>') {
if (*operators[i] == '>') { // Unary operators, parse from right to left
const std::string op(1+operators[i]);
Token *tok = _front;
while (tok->next())
@ -371,12 +371,16 @@ void TokenList::createAst()
tok->astOperand1(tok->next());
}
}
} else {
} else { // parse from left to right
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) {
tok->astOperand1(tok->previous());
tok->astOperand2(tok->next());
if (tok->str() != "++" && tok->str() != "--") {
tok->astOperand1(tok->previous());
tok->astOperand2(tok->next());
} else if (tok->previous() && !tok->previous()->isOp()) {
tok->astOperand1(tok->previous());
}
}
}
}

View File

@ -465,6 +465,8 @@ private:
TEST_CASE(astpar);
TEST_CASE(astbrackets);
TEST_CASE(astunaryop);
TEST_CASE(astfunction);
TEST_CASE(asttemplate);
}
std::string tokenizeAndStringify(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Unspecified, const char* filename = "test.cpp", bool cpp11 = true) {
@ -7642,25 +7644,35 @@ private:
return tokenList.front()->astTop()->astString();
}
void astexpr() {
void astexpr() { // simple expressions with arithmetical ops
ASSERT_EQUALS("123++", testAst("1+2+3"));
ASSERT_EQUALS("12*3+", testAst("1*2+3"));
ASSERT_EQUALS("123*+", testAst("1+2*3"));
ASSERT_EQUALS("12*34*+", testAst("1*2+3*4"));
}
void astpar() {
void astpar() { // parentheses
ASSERT_EQUALS("12+3*", testAst("(1+2)*3"));
ASSERT_EQUALS("123+*", testAst("1*(2+3)"));
ASSERT_EQUALS("123+*4*", testAst("1*(2+3)*4"));
}
void astbrackets() {
void astbrackets() { // []
ASSERT_EQUALS("123+[4+", testAst("1[2+3]+4"));
}
void astunaryop() {
ASSERT_EQUALS("12-+", testAst("1+-2"));
void astunaryop() { // unary operators
ASSERT_EQUALS("1a--+", testAst("1 + --a"));
ASSERT_EQUALS("1a--+", testAst("1 + a--"));
ASSERT_EQUALS("ab+!", testAst("!(a+b)"));
}
void astfunction() { // function calls
TODO_ASSERT_EQUALS("1f+2+", "1f+", testAst("1+f()+2"));
}
void asttemplate() { // uninstantiated templates will have <,>,etc.. how do we handle them?
//ASSERT_EQUALS("", testAst("a<int>()==3"));
}
};