AST: Improved handling of unary operators
This commit is contained in:
parent
6732f05b95
commit
1ad9c933ec
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue