Parses the {@literal <boolean-expr>} non-terminal.

<pre>
{@literal
<boolean-expr> ::= <boolean-op> <semver-expr>
| <epsilon>
}
</pre>

@param expr
the left-hand expression of the logical operators
@return the expression AST
974075
private Expression parseBooleanExpression(Expression expr) {
    if (tokens.positiveLookahead(AND)) {
      tokens.consume();
      expr = new And(expr, parseSemVerExpression());
    } else if (tokens.positiveLookahead(OR)) {
      tokens.consume();
      expr = new Or(expr, parseSemVerExpression());
    }
    return expr;
  }
103443
function parseConditionalExpression() {
        var expr, previousAllowIn, consequent, alternate, startToken;

        startToken = lookahead;

        expr = inheritCoverGrammar(parseBinaryExpression);
        if (match('?')) {
            lex();
            previousAllowIn = state.allowIn;
            state.allowIn = true;
            consequent = isolateCoverGrammar(parseAssignmentExpression);
            state.allowIn = previousAllowIn;
            expect(':');
            alternate = isolateCoverGrammar(parseAssignmentExpression);

            expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate);
            isAssignmentTarget = isBindingElement = false;
        }

        return expr;
    }
1011667
public static <T extends Enum<T>> EnumExpression<T> asEnum(Expression<T> expr) {
        Expression<T> underlyingMixin = ExpressionUtils.extract(expr);
        if (underlyingMixin instanceof PathImpl) {
            return new EnumPath<T>((PathImpl<T>) underlyingMixin);
        } else if (underlyingMixin instanceof OperationImpl) {
            return new EnumOperation<T>((OperationImpl<T>) underlyingMixin);
        } else if (underlyingMixin instanceof TemplateExpressionImpl) {
            return new EnumTemplate<T>((TemplateExpressionImpl<T>) underlyingMixin);
        } else {
            return new EnumExpression<T>(underlyingMixin) {

                private static final long serialVersionUID = 949681836002045152L;

                @Override
                public <R, C> R accept(Visitor<R, C> v, C context) {
                    return this.mixin.accept(v, context);
                }

            };
        }

    }
1244736
public static ParsedExpression parse(String expression) {
        ParsedExpression pe = (ParsedExpression)PARSED_CACHE.get(expression);

        if(pe != null)
            return pe;

        try {
            NetUIELParser learn = new NetUIELParser(new StringReader(expression));

            ParsedExpression expr = learn.parse();
            expr.seal();

            /* infrequent; this should only happen when there is a cache miss */
            synchronized(PARSED_CACHE) {
                PARSED_CACHE.put(expression, expr);
            }

            return expr;
        } catch(ParseException e) {
            String msg = "Error occurred parsing expression \"" + expression + "\".";
            LOGGER.error(msg, e);
            throw new ExpressionParseException(msg, e);
        } catch(TokenMgrError tm) {
            String msg = "Error occurred parsing expression \"" + expression + "\".";
            LOGGER.error(msg, tm);
            throw new ExpressionParseException(msg, tm);
        }
    }
549510
public static ExprInt toExprInt(Expression expr) {
	if (expr instanceof ExprInt) return (ExprInt) expr;
	if (expr instanceof Literal) {
	    Double dbl = ((Literal) expr).getDouble(null);
	    if (dbl != null) return expr.getFactory().createLitInteger((int) dbl.doubleValue(), expr.getStart(), expr.getEnd());
	}
	return new CastInt(expr);
    }
1067339
public static ExprBoolean toExprBoolean(Expression expr) {
	if (expr instanceof ExprBoolean) return (ExprBoolean) expr;
	if (expr instanceof Literal) {
	    Boolean bool = ((Literal) expr).getBoolean(null);
	    if (bool != null) return expr.getFactory().createLitBoolean(bool.booleanValue(), expr.getStart(), expr.getEnd());
	    // TODO throw new TemplateException("can't cast value to a boolean value");
	}
	return new CastBoolean(expr);
    }
816103
private Object eval(ExpressionContext expr) {
    Object res = expr;
    while(res instanceof ExpressionContext)
      res = ((ExpressionContext)res).accept(visitor);
    if(res instanceof LValue)
      res = ((LValue) res).get(expr);
    return res;
  }
119479
public static BooleanExpression asBoolean(Expression<Boolean> expr) {
        Expression<Boolean> underlyingMixin = ExpressionUtils.extract(expr);
        if (underlyingMixin instanceof PathImpl) {
            return new BooleanPath((PathImpl<Boolean>) underlyingMixin);
        } else if (underlyingMixin instanceof PredicateOperation) {
            return new BooleanOperation((PredicateOperation) underlyingMixin);
        } else if (underlyingMixin instanceof PredicateTemplate) {
            return new BooleanTemplate((PredicateTemplate) underlyingMixin);
        } else {
            return new BooleanExpression(underlyingMixin) {

                private static final long serialVersionUID = -8712299418891960222L;

                @Override
                public <R, C> R accept(Visitor<R, C> v, C context) {
                    return this.mixin.accept(v, context);
                }

            };
        }
    }
786698
private ExprKraken parseAndExpr()
  {
    // AndExpr oldAndExpr = _andExpr;
    AndExpr andExpr = new AndExpr();
    // _andExpr = andExpr;

    andExpr.add(parseNotExpr());

    while (true) {
      Token token = scanToken();

      switch (token) {
      case AND:
        andExpr.add(parseNotExpr());
        break;

      default:
        _token = token;

        // _andExpr = oldAndExpr;

        return andExpr.getSingleExpr();
      }
    }
  }
1002456
private ByExpressionBuilder parseBy()
  {
    ByExpressionBuilder by = new ByExpressionBuilder();

    int x = _parseIndex;

    Token token = scanToken();

    if (token == null)
      throw new IllegalStateException(L.l("expected field name at {0} in {1}",
                                          x,
                                          _method.getName()));

    do {
      switch (token) {
      case IDENTIFIER: {
        StringBuilder sb = new StringBuilder();
        sb.append(_lexeme);
        
        while (peekToken() == Token.IDENTIFIER) {
          token = scanToken();
          
          sb.append(_lexeme);
        }
        
        String term = fieldTerm(sb.toString());
        by.addField(term);

        break;
      }
      
      case AND: {
        by.addAnd();
        break;
      }
      
      case EQ:
      case NE:
      case LT:
      case LE:
      case GT:
      case GE:
        by.term(token);
        break;
        
      case GREATER: {
        if (peekToken() == Token.THAN) {
          scanToken();
          by.term(Token.GT);
        }
        else if (peekToken() == Token.EQ) {
          scanToken();
          by.term(Token.GE);
        }
        else {
          by.term(Token.GT);
        }
        break;
      }
        
      case LESS: {
        if (peekToken() == Token.THAN) {
          scanToken();
          by.term(Token.LT);
        }
        else if (peekToken() == Token.EQ) {
          scanToken();
          by.term(Token.LE);
        }
        else {
          by.term(Token.LT);
        }
        break;
      }
      
    case NOT: {
      if (peekToken() == Token.EQ) {
        scanToken();
        by.term(Token.NE);
      }
      else {
        by.term(Token.NE);
      }
      break;
    }
      
      case OR: {
        by.addOr();
        break;
      }
      default: {
        throw new IllegalStateException(_method.getName());
      }
      }
    }
    while ((token = scanToken()) != Token.EOF);

    return by;
  }
94893
public static ExprFloat toExprFloat(Expression expr) {
	if (expr instanceof ExprFloat) return (ExprFloat) expr;
	if (expr instanceof Literal) {
	    Double dbl = ((Literal) expr).getDouble(null);
	    if (dbl != null) return expr.getFactory().createLitFloat((float) dbl.doubleValue(), expr.getStart(), expr.getEnd());
	}
	return new CastFloat(expr);
    }
813508
public static SoyExpression isNonNull(final Expression expr) {
    if (BytecodeUtils.isPrimitive(expr.resultType())) {
      return SoyExpression.TRUE;
    }
    return SoyExpression.forBool(
        new Expression(Type.BOOLEAN_TYPE, expr.features()) {
          @Override
          protected void doGen(CodeBuilder adapter) {
            expr.gen(adapter);
            Label isNull = new Label();
            adapter.ifNull(isNull);
            // non-null
            adapter.pushBoolean(true);
            Label end = new Label();
            adapter.goTo(end);
            adapter.mark(isNull);
            adapter.pushBoolean(false);
            adapter.mark(end);
          }
        });
  }
561733
protected AstNode expr(boolean required) throws ScanException, ParseException {
		AstNode v = or(required);
		if (v == null) {
			return null;
		}
		if (token.getSymbol() == QUESTION) {
			consumeToken();
			AstNode a = expr(true);
			consumeToken(COLON);
			AstNode b = expr(true);
			v = createAstChoice(v, a, b);
		}
		return v;
	}
629147
final public void LiteralExpression() throws ParseException {
                                               /*@bgen(jjtree) LiteralExpression */
                                                AstLiteralExpression jjtn000 = new AstLiteralExpression(JJTLITERALEXPRESSION);
                                                boolean jjtc000 = true;
                                                jjtree.openNodeScope(jjtn000);Token t = null;
    try {
      t = jj_consume_token(LITERAL_EXPRESSION);
                             jjtree.closeNodeScope(jjtn000, true);
                             jjtc000 = false;
                             jjtn000.setImage(t.image);
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
  }
218127
private Expression extractSideEffects(Expression expr) {
    if (expr.getConstantValue() instanceof Boolean) {
      return null;
    }
    switch (expr.getKind()) {
      case INFIX_EXPRESSION:
        {
          List<Expression> operands = ((InfixExpression) expr).getOperands();
          Expression lastOperand = operands.remove(operands.size() - 1);
          lastOperand = extractSideEffects(lastOperand);
          if (lastOperand != null) {
            operands.add(lastOperand);
          }
          if (operands.size() == 1) {
            return operands.remove(0);
          }
          return TreeUtil.remove(expr);
        }
      case PARENTHESIZED_EXPRESSION:
        {
          Expression sideEffects = extractSideEffects(
              ((ParenthesizedExpression) expr).getExpression());
          if (sideEffects != null) {
            return ParenthesizedExpression.parenthesize(sideEffects);
          }
          return null;
        }
      default:
        return null;
    }
  }
144611
public static ExprBoolean toExprBoolean(Expression expr, Position start, Position end) {
	if (expr instanceof Literal) {
	    Boolean b = ((Literal) expr).getBoolean(null);
	    if (b != null) {
		return expr.getFactory().createLitBoolean(!b.booleanValue(), start, end);
	    }
	}
	return new OpNegate(expr, start, end);
    }
48155
public static <T extends Number & Comparable<?>> NumberExpression<T> asNumber(Expression<T> expr) {
        Expression<T> underlyingMixin = ExpressionUtils.extract(expr);
        if (underlyingMixin instanceof PathImpl) {
            return new NumberPath<T>((PathImpl<T>) underlyingMixin);
        } else if (underlyingMixin instanceof OperationImpl) {
            return new NumberOperation<T>((OperationImpl<T>) underlyingMixin);
        } else if (underlyingMixin instanceof TemplateExpressionImpl) {
            return new NumberTemplate<T>((TemplateExpressionImpl<T>) underlyingMixin);
        } else {
            return new NumberExpression<T>(underlyingMixin) {

                private static final long serialVersionUID = -8712299418891960222L;

                @Override
                public <R, C> R accept(Visitor<R, C> v, C context) {
                    return this.mixin.accept(v, context);
                }

            };
        }
    }