F -> v | "(" O ")" | "!" O | "-" O | "NOT" C | "EXISTS" v | "IS" O | "AND (" O ")" | "OR (" O ")"
(depth int)
| 493 | |
| 494 | // F -> v | "(" O ")" | "!" O | "-" O | "NOT" C | "EXISTS" v | "IS" O | "AND (" O ")" | "OR (" O ")" |
| 495 | func (t *tree) F(depth int) Node { |
| 496 | debugf(depth, "F: %v", t.Cur()) |
| 497 | |
| 498 | // Urnary operations |
| 499 | switch cur := t.Cur(); cur.T { |
| 500 | case lex.TokenNegate, lex.TokenMinus: |
| 501 | |
| 502 | t.Next() // consume NOT, !, Minus |
| 503 | |
| 504 | debugf(depth, "start:%v cur: %v peek:%v", cur, t.Cur(), t.Peek()) |
| 505 | var arg Node |
| 506 | |
| 507 | switch t.Peek().T { |
| 508 | case lex.TokenIN, lex.TokenLike, lex.TokenContains, lex.TokenBetween, |
| 509 | lex.TokenIntersects: |
| 510 | // TODO: this is a bug. An old version of generator was saving these |
| 511 | // NOT news INTERSECTS ("a") which is invalid it should be |
| 512 | // news NOT INTERSECTS ("a") OR NOT (news INTERSECTS ("a")) |
| 513 | // |
| 514 | // NOT <expr> LIKE <expr> |
| 515 | // NOT <expr> INTERSECTS <expr> |
| 516 | // NOT <expr> BETWEEN <expr> AND <expr> |
| 517 | // NOT <expr> CONTAINS <expr> |
| 518 | // NOT <expr> IN <expr> |
| 519 | // |
| 520 | // NOT identity > 7 |
| 521 | |
| 522 | arg = t.C(depth + 1) |
| 523 | default: |
| 524 | |
| 525 | switch t.Cur().T { |
| 526 | case lex.TokenUdfExpr: |
| 527 | arg = t.v(depth + 1) |
| 528 | default: |
| 529 | arg = t.C(depth + 1) |
| 530 | } |
| 531 | } |
| 532 | n := NewUnary(cur, arg) |
| 533 | debugf(depth, "f urnary: %s arg: %#v", n, arg) |
| 534 | return n |
| 535 | case lex.TokenExists: |
| 536 | // Urnary operations: require right side value node |
| 537 | t.Next() // Consume "EXISTS" |
| 538 | debugf(depth, "F PRE EXISTS:%v cur:%v", cur, t.Cur()) |
| 539 | n := NewUnary(cur, t.v(depth+1)) |
| 540 | debugf(depth, "F POST EXISTS: %s cur:%v", n, t.Cur()) |
| 541 | return n |
| 542 | case lex.TokenIs: |
| 543 | nxt := t.Next() |
| 544 | if nxt.T == lex.TokenNegate { |
| 545 | return NewUnary(cur, t.F(depth+1)) |
| 546 | } |
| 547 | return NewUnary(cur, t.F(depth+1)) |
| 548 | case lex.TokenLogicAnd, lex.TokenLogicOr: |
| 549 | debugf(depth, "found boolean and/or (O)? %v", cur) |
| 550 | t.Next() // consume AND/OR |
| 551 | t.discardNewLinesAndComments() |
| 552 | switch t.Cur().T { |
no test coverage detected