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)
|
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) {
|
if (tok->_astParent) {
|
||||||
tok->_astParent->_astOperand2 = this;
|
tok->_astParent->_astOperand2 = this;
|
||||||
_astParent = tok->_astParent;
|
_astParent = tok->_astParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
tok->_astParent = this;
|
tok->_astParent = this;
|
||||||
_astOperand1 = tok;
|
_astOperand1 = tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Token::astOperand2(Token *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) {
|
if (tok->_astParent) {
|
||||||
tok->_astParent->_astOperand1 = this;
|
tok->_astParent->_astOperand1 = this;
|
||||||
_astParent = tok->_astParent;
|
_astParent = tok->_astParent;
|
||||||
|
@ -1076,7 +1087,7 @@ void Token::astHandleParenthesis()
|
||||||
innerTop = innerTop->_astParent;
|
innerTop = innerTop->_astParent;
|
||||||
|
|
||||||
if (_astParent) {
|
if (_astParent) {
|
||||||
if (_str == "(")
|
if (_str == "(" && _astParent->_astOperand2 != NULL)
|
||||||
_astParent->_astOperand2 = innerTop;
|
_astParent->_astOperand2 = innerTop;
|
||||||
else
|
else
|
||||||
_astParent->_astOperand1 = innerTop;
|
_astParent->_astOperand1 = innerTop;
|
||||||
|
|
|
@ -360,7 +360,7 @@ void TokenList::createAst()
|
||||||
|
|
||||||
for (unsigned int i = 0; i < sizeof(operators) / sizeof(*operators); ++i) {
|
for (unsigned int i = 0; i < sizeof(operators) / sizeof(*operators); ++i) {
|
||||||
// TODO: extract operators to std::set - that should be faster
|
// 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]);
|
const std::string op(1+operators[i]);
|
||||||
Token *tok = _front;
|
Token *tok = _front;
|
||||||
while (tok->next())
|
while (tok->next())
|
||||||
|
@ -371,12 +371,16 @@ void TokenList::createAst()
|
||||||
tok->astOperand1(tok->next());
|
tok->astOperand1(tok->next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else { // parse from left to right
|
||||||
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) {
|
||||||
tok->astOperand1(tok->previous());
|
if (tok->str() != "++" && tok->str() != "--") {
|
||||||
tok->astOperand2(tok->next());
|
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(astpar);
|
||||||
TEST_CASE(astbrackets);
|
TEST_CASE(astbrackets);
|
||||||
TEST_CASE(astunaryop);
|
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) {
|
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();
|
return tokenList.front()->astTop()->astString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void astexpr() {
|
void astexpr() { // simple expressions with arithmetical ops
|
||||||
ASSERT_EQUALS("123++", testAst("1+2+3"));
|
ASSERT_EQUALS("123++", testAst("1+2+3"));
|
||||||
ASSERT_EQUALS("12*3+", testAst("1*2+3"));
|
ASSERT_EQUALS("12*3+", testAst("1*2+3"));
|
||||||
ASSERT_EQUALS("123*+", testAst("1+2*3"));
|
ASSERT_EQUALS("123*+", testAst("1+2*3"));
|
||||||
ASSERT_EQUALS("12*34*+", testAst("1*2+3*4"));
|
ASSERT_EQUALS("12*34*+", testAst("1*2+3*4"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void astpar() {
|
void astpar() { // parentheses
|
||||||
ASSERT_EQUALS("12+3*", testAst("(1+2)*3"));
|
ASSERT_EQUALS("12+3*", testAst("(1+2)*3"));
|
||||||
ASSERT_EQUALS("123+*", testAst("1*(2+3)"));
|
ASSERT_EQUALS("123+*", testAst("1*(2+3)"));
|
||||||
ASSERT_EQUALS("123+*4*", testAst("1*(2+3)*4"));
|
ASSERT_EQUALS("123+*4*", testAst("1*(2+3)*4"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void astbrackets() {
|
void astbrackets() { // []
|
||||||
ASSERT_EQUALS("123+[4+", testAst("1[2+3]+4"));
|
ASSERT_EQUALS("123+[4+", testAst("1[2+3]+4"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void astunaryop() {
|
void astunaryop() { // unary operators
|
||||||
ASSERT_EQUALS("12-+", testAst("1+-2"));
|
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