protected static Expression parseFlatNoparen(
      Module module, SourceReader sReader, TokenReader reader, boolean noDecl) {

    int mark = reader.mark();

    Literal literal = LiteralParser.parse(module, sReader, reader);
    if (literal != null) return literal;

    FunctionCall funcCall = FunctionCallParser.parse(module, sReader, reader);
    if (funcCall != null) return funcCall;

    if (!noDecl) {
      Declaration declaration = DeclarationParser.parse(module, sReader, reader);
      if (declaration != null) return declaration;
    }

    Access access = AccessParser.parse(module, sReader, reader);
    if (access != null) return access;

    Match match = MatchParser.parse(module, sReader, reader);
    if (match != null) return match;

    reader.reset(mark);
    return null;
  }
  @NotNull
  private static PsiBuilder.Marker parseNew(
      final PsiBuilder builder, final PsiBuilder.Marker start) {
    final PsiBuilder.Marker newExpr = (start != null ? start.precede() : builder.mark());
    builder.advanceLexer();

    final boolean parseDiamonds = areDiamondsSupported(builder);
    ReferenceParser.parseReferenceParameterList(builder, false, parseDiamonds);

    final PsiBuilder.Marker refOrType;
    final boolean parseAnnotations =
        areTypeAnnotationsSupported(builder) && builder.getTokenType() == JavaTokenType.AT;

    final IElementType tokenType = builder.getTokenType();
    if (tokenType == JavaTokenType.IDENTIFIER || parseAnnotations) {
      refOrType =
          ReferenceParser.parseJavaCodeReference(
              builder, true, true, parseAnnotations, true, parseDiamonds);
      if (refOrType == null) {
        error(builder, JavaErrorMessages.message("expected.identifier"));
        newExpr.done(JavaElementType.NEW_EXPRESSION);
        return newExpr;
      }
    } else if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType)) {
      refOrType = null;
      builder.advanceLexer();
    } else {
      error(builder, JavaErrorMessages.message("expected.identifier"));
      newExpr.done(JavaElementType.NEW_EXPRESSION);
      return newExpr;
    }

    if (refOrType != null && builder.getTokenType() == JavaTokenType.LPARENTH) {
      parseArgumentList(builder);
      if (builder.getTokenType() == JavaTokenType.LBRACE) {
        final PsiBuilder.Marker classElement = refOrType.precede();
        DeclarationParser.parseClassBodyWithBraces(builder, false, false);
        classElement.done(JavaElementType.ANONYMOUS_CLASS);
      }
    } else {
      if (builder.getTokenType() != JavaTokenType.LBRACKET) {
        error(
            builder,
            refOrType == null
                ? JavaErrorMessages.message("expected.lbracket")
                : JavaErrorMessages.message("expected.lparen.or.lbracket"));
        newExpr.done(JavaElementType.NEW_EXPRESSION);
        return newExpr;
      }

      int bracketCount = 0;
      int dimCount = 0;
      while (true) {
        if (builder.getTokenType() != JavaTokenType.LBRACKET) break;
        builder.advanceLexer();

        if (bracketCount == dimCount) {
          final PsiBuilder.Marker dimExpr = parse(builder);
          if (dimExpr != null) {
            dimCount++;
          }
        }
        bracketCount++;

        if (!JavaParserUtil.expectOrError(
            builder, JavaTokenType.RBRACKET, JavaErrorMessages.message("expected.rbracket"))) {
          newExpr.done(JavaElementType.NEW_EXPRESSION);
          return newExpr;
        }
      }

      if (dimCount == 0) {
        if (builder.getTokenType() == JavaTokenType.LBRACE) {
          parseArrayInitializer(builder);
        } else {
          error(builder, JavaErrorMessages.message("expected.array.initializer"));
        }
      }
    }

    newExpr.done(JavaElementType.NEW_EXPRESSION);
    return newExpr;
  }
  @Nullable
  private static PsiBuilder.Marker parsePrimaryExpressionStart(final PsiBuilder builder) {
    IElementType tokenType = builder.getTokenType();

    if (LITERALS.contains(tokenType)) {
      final PsiBuilder.Marker literal = builder.mark();
      builder.advanceLexer();
      literal.done(JavaElementType.LITERAL_EXPRESSION);
      return literal;
    }
    if (tokenType == JavaTokenType.LPARENTH) {
      final PsiBuilder.Marker parenth = builder.mark();
      builder.advanceLexer();

      final PsiBuilder.Marker inner = parse(builder);
      if (inner == null) {
        error(builder, JavaErrorMessages.message("expected.expression"));
      }

      if (!expect(builder, JavaTokenType.RPARENTH)) {
        if (inner != null) {
          error(builder, JavaErrorMessages.message("expected.rparen"));
        }
      }

      parenth.done(JavaElementType.PARENTH_EXPRESSION);
      return parenth;
    }
    if (tokenType == JavaTokenType.LBRACE) {
      return parseArrayInitializer(builder);
    }

    PsiBuilder.Marker annotation = null;
    final PsiBuilder.Marker beforeAnnotation = builder.mark();
    if (tokenType == JavaTokenType.AT) {
      annotation = DeclarationParser.parseAnnotations(builder);
      tokenType = builder.getTokenType();
    }

    if (tokenType == JavaTokenType.IDENTIFIER) {
      final PsiBuilder.Marker refExpr;
      if (annotation != null) {
        final PsiBuilder.Marker refParam = annotation.precede();
        refParam.doneBefore(JavaElementType.REFERENCE_PARAMETER_LIST, annotation);
        refExpr = refParam.precede();
      } else {
        refExpr = builder.mark();
        builder.mark().done(JavaElementType.REFERENCE_PARAMETER_LIST);
      }

      builder.advanceLexer();
      refExpr.done(JavaElementType.REFERENCE_EXPRESSION);
      beforeAnnotation.drop();
      return refExpr;
    }

    if (annotation != null) {
      beforeAnnotation.rollbackTo();
      tokenType = builder.getTokenType();
    } else {
      beforeAnnotation.drop();
    }

    PsiBuilder.Marker expr = null;
    if (tokenType == JavaTokenType.LT) {
      expr = builder.mark();

      if (!ReferenceParser.parseReferenceParameterList(builder, false, false)) {
        expr.rollbackTo();
        return null;
      }

      tokenType = builder.getTokenType();
      if (!CONSTRUCTOR_CALL.contains(tokenType)) {
        expr.rollbackTo();
        return null;
      }
    }

    if (CONSTRUCTOR_CALL.contains(tokenType)) {
      if (expr == null) {
        expr = builder.mark();
        builder.mark().done(JavaElementType.REFERENCE_PARAMETER_LIST);
      }
      builder.advanceLexer();
      expr.done(
          builder.getTokenType() == JavaTokenType.LPARENTH
              ? JavaElementType.REFERENCE_EXPRESSION
              : tokenType == JavaTokenType.THIS_KEYWORD
                  ? JavaElementType.THIS_EXPRESSION
                  : JavaElementType.SUPER_EXPRESSION);
      return expr;
    }
    if (tokenType == JavaTokenType.NEW_KEYWORD) {
      return parseNew(builder, null);
    }
    if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType)) {
      return parseClassObjectAccess(builder);
    }

    return null;
  }