AST: Parse ternary and assignment operators as right-to-left and on the same precedence level
This commit is contained in:
parent
70dfb55f21
commit
a3bb8bf39c
|
@ -410,8 +410,8 @@ static void compileBinOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &,
|
||||||
if (tok)
|
if (tok)
|
||||||
f(tok, op, depth);
|
f(tok, op, depth);
|
||||||
|
|
||||||
// Assignment operators are executed in right-to-left order
|
// Assignment and ternary operators are executed in right-to-left order
|
||||||
if (binop->isAssignmentOp() && tok && tok->isAssignmentOp())
|
if ((binop->isAssignmentOp() || Token::Match(binop, "[:?]")) && tok && (tok->isAssignmentOp() || Token::Match(tok, "[:?]")))
|
||||||
compileBinOp(tok, f, op, depth);
|
compileBinOp(tok, f, op, depth);
|
||||||
|
|
||||||
// TODO: Should we check if op is empty.
|
// TODO: Should we check if op is empty.
|
||||||
|
@ -702,32 +702,24 @@ static void compileLogicOr(Token *&tok, std::stack<Token*> &op, unsigned int dep
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compileTernaryOp(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileAssignTernary(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileLogicOr(tok, op, depth);
|
compileLogicOr(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (Token::Match(tok, "[?:]")) {
|
// TODO: http://en.cppreference.com/w/cpp/language/operator_precedence says:
|
||||||
|
// "The expression in the middle of the conditional operator (between ? and :) is parsed as if parenthesized: its precedence relative to ?: is ignored."
|
||||||
|
if (tok->isAssignmentOp() || Token::Match(tok, "[?:]")) {
|
||||||
compileBinOp(tok, compileLogicOr, op, depth);
|
compileBinOp(tok, compileLogicOr, op, depth);
|
||||||
} else break;
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compileAssign(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
|
||||||
{
|
|
||||||
compileTernaryOp(tok,op, depth);
|
|
||||||
while (tok) {
|
|
||||||
if (tok->isAssignmentOp()) {
|
|
||||||
compileBinOp(tok, compileTernaryOp, op, depth);
|
|
||||||
} else break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void compileComma(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
static void compileComma(Token *&tok, std::stack<Token*> &op, unsigned int depth)
|
||||||
{
|
{
|
||||||
compileAssign(tok,op, depth);
|
compileAssignTernary(tok, op, depth);
|
||||||
while (tok) {
|
while (tok) {
|
||||||
if (tok->str() == ",") {
|
if (tok->str() == ",") {
|
||||||
compileBinOp(tok, compileAssign, op, depth);
|
compileBinOp(tok, compileAssignTernary, op, depth);
|
||||||
} else break;
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10408,7 +10408,7 @@ private:
|
||||||
ASSERT_EQUALS("'X''a'>", testAst("('X' > 'a')"));
|
ASSERT_EQUALS("'X''a'>", testAst("('X' > 'a')"));
|
||||||
ASSERT_EQUALS("'X''a'>", testAst("(L'X' > L'a')"));
|
ASSERT_EQUALS("'X''a'>", testAst("(L'X' > L'a')"));
|
||||||
|
|
||||||
ASSERT_EQUALS("a0>bc/?d:", testAst("(a>0) ? (b/(c)) : d;"));
|
ASSERT_EQUALS("a0>bc/d:?", testAst("(a>0) ? (b/(c)) : d;"));
|
||||||
ASSERT_EQUALS("abc/+d+", testAst("a + (b/(c)) + d;"));
|
ASSERT_EQUALS("abc/+d+", testAst("a + (b/(c)) + d;"));
|
||||||
|
|
||||||
ASSERT_EQUALS("absizeofd(ef.+(=", testAst("a = b(sizeof(c d) + e.f)"));
|
ASSERT_EQUALS("absizeofd(ef.+(=", testAst("a = b(sizeof(c d) + e.f)"));
|
||||||
|
@ -10462,7 +10462,7 @@ private:
|
||||||
ASSERT_EQUALS("a1(2+=",testAst("a=(t*)1+2;"));
|
ASSERT_EQUALS("a1(2+=",testAst("a=(t*)1+2;"));
|
||||||
ASSERT_EQUALS("a1(2+=",testAst("a=(t&)1+2;"));
|
ASSERT_EQUALS("a1(2+=",testAst("a=(t&)1+2;"));
|
||||||
ASSERT_EQUALS("ab::r&c(=", testAst("a::b& r = (a::b&)c;")); // #5261
|
ASSERT_EQUALS("ab::r&c(=", testAst("a::b& r = (a::b&)c;")); // #5261
|
||||||
ASSERT_EQUALS("ab1?0:=", testAst("a=(b)?1:0;"));
|
ASSERT_EQUALS("ab10:?=", testAst("a=(b)?1:0;"));
|
||||||
|
|
||||||
// ({..})
|
// ({..})
|
||||||
ASSERT_EQUALS("a{+d+ bc+", testAst("a+({b+c;})+d"));
|
ASSERT_EQUALS("a{+d+ bc+", testAst("a+({b+c;})+d"));
|
||||||
|
@ -10493,11 +10493,11 @@ private:
|
||||||
ASSERT_EQUALS("c5[--*", testAst("*c[5]--;"));
|
ASSERT_EQUALS("c5[--*", testAst("*c[5]--;"));
|
||||||
|
|
||||||
// Unary :: operator
|
// Unary :: operator
|
||||||
ASSERT_EQUALS("abc?d12,(::e/:=",testAst("a = b ? c : ::d(1,2) / e;"));
|
ASSERT_EQUALS("abcd12,(::e/:?=",testAst("a = b ? c : ::d(1,2) / e;"));
|
||||||
|
|
||||||
// how is "--" handled here:
|
// how is "--" handled here:
|
||||||
ASSERT_EQUALS("ab4<<c--+?1:", testAst("a ? (b << 4) + --c : 1"));
|
ASSERT_EQUALS("ab4<<c--+1:?", testAst("a ? (b << 4) + --c : 1"));
|
||||||
ASSERT_EQUALS("ab4<<c--+?1:", testAst("a ? (b << 4) + c-- : 1"));
|
ASSERT_EQUALS("ab4<<c--+1:?", testAst("a ? (b << 4) + c-- : 1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void astfunction() const { // function calls
|
void astfunction() const { // function calls
|
||||||
|
|
Loading…
Reference in New Issue